CSS-live.ru

Развлечения с 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);
}

gradient-stops

А теперь объединим оба трюка:

funsville

В браузере, который не поддерживает обрезку фона по тексту (напр. 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));
}

start

Но это становится труднее, если вы пытаетесь обратиться к последним нескольким строкам из произвольного количества текста. В этом случае, нам необходимо, чтобы верхняя цветная полоса шла от верха до низа текста за вычетом нескольких строк. К счастью можно сделать это при помощи 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;
}

fade

Есть также и другие способы сделать это, например, наложение поверх текста псевдоэлемента с градиентом (с указанием 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 и вычесть один где нужно.

lines

Размещение изображений на каждой строке

Ещё одна вещь, которую можно сделать, зная точный line-height, это заставить background-size ему соответствовать, по крайней мере по вертикальной оси. Тогда можно заставить его повторяться по вертикали, и фоновое изображение будет размещаться построчно.

.text
  background-image: url(image.svg);
  background-size: $lh $lh;
  background-repeat: repeat-y;
  padding-left: $lh*2;
}

ticks

Демо

P.S. Это тоже может быть интересно:

9 комментариев

        1. Действительно занятно, судя по всему, шрифт и градиенты по-разному отмасштабировались. Похоже, это лечится заданием -webkit-text-size-adjust: none.

          Приношу извинения за спам-фильтр — он здесь немножко параноик и настораживается, видя много ссылок в комментах)

  1. "Так что же это за позорные фичи?

    -webkit-background-clip: text;
    -webkit-text-fill-color                "    Отзовите статьи, лекции, примеры и т.п., пропагандирующие эти фичи без каких-либо предупреждений !!! " 

    Котят не жалко?   

    1. Жалко… Предупреждение, что способ нестандартный, в статье есть (прямо перед примером кода). Понятно, что оно мало кого остановит…

      Но, к сожалению, близкое к монопольному положение Вебкита/Блинка продолжает делать свое черное дело, и за два года после той статьи Лии Веру эти свойства успели войти в обиход. Так что вполне может быть, что их всё-таки продавят в стандарт, как получилось со многими IEшными «нововведениями» 90-х (overflow-x/y, text-align-last и т.п.). Посмотрим.

Оставить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *

Получать новые комментарии по электронной почте. Вы можете подписаться без комментирования.