Развлечения с line-height!
Перевод статьи Fun with line-height! с сайта css-tricks.com, c разрешения автора — Криса Койера.
Свойство line-height в CSS управляет расстоянием между строками текста. Его часто устанавливают в безразмерное значение (напр. line
-
height
: 1.4;
), чтобы оно было пропорционально размеру шрифта. Это свойство крайне необходимо для управления типоргафикой. Если расстояние между строк слишком маленькое, то строки неуклюже придавлены друг к другу; а если слишком большое, то строки выглядят неуклюже растопыренными. Оба случая тормозят чтение текста. Но, вероятно, вы уже сами это знаете.
В этой статье мы сосредоточимся на некоторых хитростях. Если вы знаете (или можете выяснить) точное значение line
-
height
, то у вас есть возможность делать интересные вещи.
Оформление каждой строки текста своим цветом
К сожалению, не существует ::nth-line(). Мы даже не можем надёжно полагаться на <
span
>
-ы, т.к. есть куча всевозможных вещей, из-за которых текст может переноситься на новую строку в разных местах.
Есть способ, хотя и нестандартный, использовать фон элемента в качестве фона для текста.
.text { -webkit-background-clip: text; -webkit-text-fill-color: transparent; }
Есть ещё один трюк, когда можно использовать linear
-
gradient
()
с резкими переходами между цветами. Допустим нам известно, что line-height равен 22px, тогда мы мы можем сделать градиент, у которого цвета меняются точно с таким шагом.
.text { background-image: linear-gradient( to bottom, #9588DD, #9588DD 22px, #DD88C8 22px, #DD88C8 44px, #D3DD88 44px, #D3DD88 66px, #88B0DD 66px, #88B0DD); }
А теперь объединим оба трюка:
В браузере, который не поддерживает обрезку фона по тексту (напр. Firefox), вы получите сплошные полоски цвета под текстом. Возможно, это круто и вам понравится. Возможно, вы бы скорее предпочли оставить сплошной цвет текста. В этом случае можно использовать @
supports
и применять его везде, где он поддерживается.
Кроме того, поскольку вы используете значение line-height неоднократно, то было бы здорово создать для него переменную. Здесь я буду использовать SCSS, но было бы вроде как поизящнее когда-нибудь делать это при помощи настоящих CSS-переменных, так что вы могли бы изменять значение переменной даже после отображения и наблюдать как всё это продолжает работать.
$lh: 1.4em; body { font-size: 1em; line-height: $lh; } @supports (-webkit-background-clip: text) { p { -webkit-background-clip: text; -webkit-text-fill-color: transparent; background-image: linear-gradient( to bottom, #9588DD, #9588DD $lh, #DD88C8 $lh, #DD88C8 $lh*2, #D3DD88 $lh*2, #D3DD88 $lh*3, #88B0DD $lh*3, #88B0DD); } }
Использовать этот трюк для вверхней части элемента проще простого. Вот пример, в котором первые несколько строк выделены для выразительности.
.text { -webkit-background-clip: text; -webkit-text-fill-color: transparent; background-image: linear-gradient( to bottom, rgba(white, 0.8), rgba(white, 0.8) $lh, rgba(white, 0.6) $lh, rgba(white, 0.6) $lh*2, rgba(white, 0.4) $lh*2, rgba(white, 0.4) $lh*3, rgba(white, 0.2) $lh*3, rgba(white, 0.2)); }
Но это становится труднее, если вы пытаетесь обратиться к последним нескольким строкам из произвольного количества текста. В этом случае, нам необходимо, чтобы верхняя цветная полоса шла от верха до низа текста за вычетом нескольких строк. К счастью можно сделать это при помощи calc
()
! (В комментариях к оригиналу статьи Лиа Веру предложила более простое решение: просто изменить направление градиента на "to top" — прим. перев.)
.text { -webkit-background-clip: text; -webkit-text-fill-color: transparent; background-image: linear-gradient( to bottom, rgba(white, 0.8), rgba(white, 0.8) calc(100% - 66px), rgba(white, 0.6) calc(100% - 66px), rgba(white, 0.6) calc(100% - 44px), rgba(white, 0.4) calc(100% - 44px), rgba(white, 0.4) calc(100% - 22px), rgba(white, 0.2) calc(100% - 22px), rgba(white, 0.2)); background-position: bottom center; }
Есть также и другие способы сделать это, например, наложение поверх текста псевдоэлемента с градиентом (с указанием pointer
-
events
: none
;,
так чтобы он не мешал вам)
Линии между строками текста
С помощью приема, похожего на прием с резким переходом между цветами, использованный выше, можно создать линию градиента в 1px, которая повторяется с шагом, в точности равным известному line
-
height
. Самый простой способ сделать это – использовать repeating
-
linear
-
gradient
()
, а также убедиться, что все другие параметры не создают помех (например, отступы, которые также основаны на line-height).
.parent { padding: $lh*2; background: #082838; background-image: repeating-linear-gradient( to bottom, rgba(white, 0) 0, rgba(white, 0) $lh/1em*16px-1, rgba(white, 0.1) $lh/1em*16px-1, rgba(white, 0.1) $lh/1em*16px ); }
Чтобы получить строку в 1px, необходимо знать значение line
-
height
, а затем вычесть один. Цель состоит в том, что градиент повторяется с шагом, точно равным известному line-height, так что последним пикселем в этом отрезке может быть линия. Поскольку мы оставили font-size для body равным 1em, он у нас будет 16px. И поскольку line
-
height
задан в em-ах, мы можем разделить на 1em, избавившись от единицы измерения, а затем помножить результат на 16px и вычесть один где нужно.
Размещение изображений на каждой строке
Ещё одна вещь, которую можно сделать, зная точный line
-
height
, это заставить background
-
size
ему соответствовать, по крайней мере по вертикальной оси. Тогда можно заставить его повторяться по вертикали, и фоновое изображение будет размещаться построчно.
.text background-image: url(image.svg); background-size: $lh $lh; background-repeat: repeat-y; padding-left: $lh*2; }
Демо
P.S. Это тоже может быть интересно:
Читал через телефон (хром). Финальное демо жесть кривое =)
А можно скриншот жесть кривизны? Может, вместе придумаем, как пофиксить)
http://i.gyazo.com/9e12ed3f8ca431aa7b2c86ce0b09d292.png
http://i.gyazo.com/3f2df11f872f89834e3f6f84218d0dec.png
http://i.gyazo.com/e7a64a6f6447c40df45e3f0e59c1636f.png
http://i.gyazo.com/faa47a4677bf3000e9f3889c41551ac6.png
Как-то так.
Действительно занятно, судя по всему, шрифт и градиенты по-разному отмасштабировались. Похоже, это лечится заданием -webkit-text-size-adjust: none.
Приношу извинения за спам-фильтр — он здесь немножко параноик и настораживается, видя много ссылок в комментах)
Да, так — отлично, спасибо)
Запостил ссылки на скриншоты. То ли удалились сами, то ли их выпилили.
Ан нет, извиняюсь. Ваш комментарий ожидает проверки.
"Так что же это за позорные фичи?
-webkit-background-clip: text;
-webkit-text-fill-color " Отзовите статьи, лекции, примеры и т.п., пропагандирующие эти фичи без каких-либо предупреждений !!! "
Котят не жалко?
Жалко… Предупреждение, что способ нестандартный, в статье есть (прямо перед примером кода). Понятно, что оно мало кого остановит…
Но, к сожалению, близкое к монопольному положение Вебкита/Блинка продолжает делать свое черное дело, и за два года после той статьи Лии Веру эти свойства успели войти в обиход. Так что вполне может быть, что их всё-таки продавят в стандарт, как получилось со многими IEшными «нововведениями» 90-х (overflow-x/y, text-align-last и т.п.). Посмотрим.