Пересечение текста линией в CSS — Блог о самом интересном.

От создателя: в начале этого года я натолкнулась на это демо от Флорина Попка, в нем линия проходит или поверх, или сзади букв заголовка. Я поразмыслила, что это крутая мысль, но в реализации было несколько мелочей, которые я могла бы упростить и сделать лучше сразу.

Во-1-х, в уникальной демо-версии текст заголовка дублируется, чего же, как я знала, можно было просто избежать. Также длина полосы, проходящей через текст, является волшебным числом, что не является весьма гибким подходом. И, в конце концов, можем ли мы избавиться от JavaScript?

Итак, давайте поглядим, что у меня в конечном итоге вышло.

HTML структура

Флорин помещает текст в элемент заголовка, а потом дублирует этот заголовок, используя Splitting.js, чтоб поменять текстовое содержимое дублированного заголовка спанами, любой из которых содержит одну буковку начального текста.

Решение создать это с дублированием текста, используя библиотеку, чтоб поделить текст на знаки, а потом поместить любой из их в span, схожее на ненадобное, мы делаем все это при помощи препроцессора HTML.

JavaScript — let text = ‘We Love to Play’;

— let arr = text.split(»);

h1(role=’image’ aria-label=text) — arr.forEach(letter => { span.letter #{letter}

— });

1234567 — let text = ‘We Love to Play’;- let arr = text.split(»); h1(role=’image’ aria-label=text)  — arr.forEach(letter => {    span.letter #{letter}  — });

Так как разделение текста на несколько частей не подступает для программ чтения с экрана, мы задали для всего role со значением image и указали aria-label. Это генерирует последующий HTML:

W e L o v e t o P l a y

Минималистичное управление состоянием (React)

1234567891011121314151617

  W  e     L  o  v  e     t  o     P  l  a  y

Главные стили

Мы помещаем заголовок в центр его родителя (body в данном случае), используя grid-макет:

CSS body { display: grid; place-content: center;

}

1234 body {  display: grid;  place-content: center;}

Заголовок не растягивается на всю ширину родителя, но заместо этого помещается в середине. Мы также можем добавить некие штришки, к примеру, прекрасные font либо background для контейнера. Дальше мы создаем линию с полностью позиционированным псевдо-элементом ::after, его толщина (height) $h:

CSS $h: .125em;

$r: .5*$h;

h1 {
position: relative;

&::after { position: absolute; top: calc(50% — #{$r}); right: 0; height: $h; border-radius: 0 $r $r 0; background: crimson; }

}

1234567891011121314 $h: .125em;$r: .5*$h; h1 {  position: relative;    &::after {    position: absolute;    top: calc(50% — #{$r}); right: 0;    height: $h;    border-radius: 0 $r $r 0;    background: crimson;  }}

Приведенный выше код задает позиционировании и толщину псевдо-элемента, но что насчет его ширины? Как вынудить его растягиваться от левого края области просмотра до правого края текста заголовка?

Длина полосы

Итак, так как у нас есть grid макет, в котором заголовок выровнен по центру по горизонтали, это значит, что вертикальная средняя линия, делящая окно просмотра в центре, совпадает со средней линией для заголовка, разделяя их на две равные по ширине половины:

Как следует, расстояние меж левым краем области просмотра и правым краем заголовка составляет половину ширины области просмотра (50vw) плюс половина ширины заголовка, что быть может выражено как процентное значение при вычислении ширины псевдо-элементов.

Таковым образом, width для нашего псевдо-элемента ::after будет:

CSS width: calc(50vw + 50%);

1 width: calc(50vw + 50%);

Как создать, чтоб линия располагалась перед и сзади букв?

Пока что мы получили просто красноватую линию, пересекающую текст:

TikTok облегчит создание и проведение кампаний внутри видеосервиса

Мы желаем, чтоб некие буковкы показывались поверх полосы. Чтоб получить этот эффект, мы случайным образом задаем им (либо не задаем) класс .over. Это значит, что необходимо мало поменять код Pug:

JavaScript — let text = ‘We Love to Play’;

— let arr = text.split(»);

h1(role=’image’ aria-label=text) — arr.forEach(letter => { span.letter(class=Math.random() > .5 ? ‘over’ : null) #{letter}

— });

1234567 — let text = ‘We Love to Play’;- let arr = text.split(»); h1(role=’image’ aria-label=text)  — arr.forEach(letter => {    span.letter(class=Math.random() > .5 ? ‘over’ : null) #{letter}  — });

Потом мы сопоставляем буковкы с классом .over и задаем им положительный z-index.

CSS .over { position: relative; z-index: 1;

}

1234 .over {  position: relative;  z-index: 1;}

Моя начальная мысль заключалась в использовании translatez(1px) заместо z-index: 1, но позже мне показалось, что внедрение z-index имеет наилучшую поддержку браузеров и просит меньше усилий.

Линия проходит поверх одних букв, но под иными:

Анимация

Сейчас, когда мы совладали со сложной частью, мы также можем добавить анимацию. Сначала малиновая линия сдвигается на лево (в отрицательном направлении оси x, потому символ будет минус) на 100% ширины, а потом ворачивается в обычное положение.

CSS @keyframes slide { 0% { transform: translate(-100%); } }

1 @keyframes slide { 0% { transform: translate(-100%); } }

Я предпочла, чтоб до этого чем запускается анимация полосы, прошло мало времени. Это означало добавление 1s задержки, что, в свою очередь, значит добавление главного слова backwards для animation-fill-mode, чтоб линия до начала анимации находилась в позиции 0%:

CSS animation: slide 2s ease-out 1s backwards;

1 animation: slide 2s ease-out 1s backwards;

Мало 3D

Это отдало мне еще одну идею, заключающуюся в том, чтоб линия пронизывала буковкы, заходила в начале поверх буковкы, а потом уходила под нее (либо напротив). Это просит настоящего 3D и нескольких маленьких опций.

Во-1-х, мы устанавливаем для transform-style заголовока значение preserve-3d, потому что желаем, чтоб все его потомки (и псевдо-элементы) были частью 1-го и такого же 3D-контекста, что дозволит их располагать и пересекать так, как они размещены в 3D.

Google раскрыл еще одно название алгоритма BERT

Потом нам необходимо повернуть каждую буковку вокруг собственной оси y, при этом направление вращения зависит от наличия случаем назначенного класса (имя которого мы меняем на .rev от «reverse», потому что «over» не совершенно соответствует тому, что мы тут делаем).

Но, до этого чем мы создадим это, мы должны держать в голове, что элементы span в данный момент все еще являются встроенными, и указание transform для встроенного элемента не дает полностью никакого эффекта.

Чтоб обойти эту делему, мы задали для заголовка display: flex. Но это делает новейшую делему – ширина частей span, содержащих лишь пробел (» «), сбрасывается на ноль.

Обычное решение данной нам трудности — установить white-space: pre для наших спанов с классом .letter. Как мы это создадим, мы сможем повернуть спаны на угол $a… в одном либо другом направлении!

CSS $a: 2deg;

.letter { white-space: pre; transform: rotatey($a);

}

.rev { transform: rotatey(-$a); }

12345678 $a: 2deg; .letter {  white-space: pre;  transform: rotatey($a);} .rev { transform: rotatey(-$a); }

Так как вращение вокруг оси Y сжимает буковкы по горизонтали, мы можем масштабировать их вдоль оси X при помощи коэффициента ($f), оборотного косинусу $a.

CSS $a: 2deg;

$f: 1/cos($a)

.letter { white-space: pre; transform: rotatey($a) scalex($f)

}

.rev { transform: rotatey(-$a) scalex($f) }

123456789 $a: 2deg;$f: 1/cos($a) .letter {  white-space: pre;  transform: rotatey($a) scalex($f)} .rev { transform: rotatey(-$a) scalex($f) }

Вот и все! Сейчас у нас есть 3D-результат, к которому мы стремились! Но направьте внимание, что применяемый тут шрифт был избран так, чтоб итог смотрелся отлично, и иной шрифт может не подступать так же отлично.

Создатель: Ana Tudor

Редакция: Команда webformyself.

Источник

Вам также может понравиться