Главная » Статьи » Обрезка по высоте строки — простая формула CSS для удаления из текста верхнего пространства

Обрезка по высоте строки — простая формула CSS для удаления из текста верхнего пространства

Обрезка по высоте строки — простая формула CSS для удаления из текста верхнего пространства

От автора: естественное поведение текстовых элементов включает в себя некоторое пространство сверху (и снизу) самого элемента, основанное на значении высоты строки. В некоторых случаях вам может потребоваться удалить эти пробелы, поскольку они могут создавать несоответствия в дизайне вашей страницы.

В этой статье мы рассмотрим, как делается обрезка CSS для удаления этого пространства из текстовых элементов с использованием простого миксина SCSS.

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

Миксин

Вот миксин, который вы можете использовать, чтобы удалить верхнее пространство из текстового элемента:

@mixin lhCrop($line-height) { &::before { content: ''; display: block; height: 0; width: 0; margin-top: calc((1 - #{$line-height}) * 0.5em); }
}

Включите его в текстовый элемент, который хотите изменить, убедившись, что строка line-height передается как аргумент миксина:

.text-to-crop { @include lhCrop(1.2); //line-height: 1.2
}

Во фреймворке, которые мы построили для библиотеки компонентов CodyHouse, значения высоты строки выражаются как переменная CSS; это означает, что мы можем использовать эти переменные CSS для вызова миксина lhCrop:

:root { /* line-height */ --heading-line-height: 1.2; --body-line-height: 1.4; --article-line-height: 1.58;
} .text-to-crop { @include lhCrop(var(--heading-line-height));
}

Одно из преимуществ этого заключается в том, что значение обрезки будет автоматически обновляться, если вы решите изменить значение переменных CSS (без необходимости изменять вызов миксин) или если переменная line-height модифицируется при разных медиа-запросах (без необходимости повторного использования миксина).

Пояснение миксина

При использовании миксина lhCrop создается псевдо-элемент ::before с отрицательным отступом, который сокращает пространство над вашим текстовым элементом.

Идея использования псевдо-элемента с отрицательным отступом была впервые введена Кевином Пауэллом. Он также создал инструмент Text Crop Tool, который позволяет создать собственный миксин в соответствии с семейством шрифтов, которые вы используете в своем проекте.

Для нашего миксина, вот как мы получили значение для margin-top:

Общая высота текстового элемента (высота заглавной буквы + верхнее пространство + нижнее пространство) равна высоте строки, умноженной на размер шрифта (если вы используете число для высоты строки);

Предположили, что высота заглавной буквы равна размеру шрифта (это приближение, больше об этом в разделе Ограничения);

Это означает, что сумма верхнего пространства и нижнего пространства будет:

total-space = font-size*line-height - font-size = (line-height - 1)*font-size = (line-height - 1)*1em

Обратите внимание, что мы использовали 1em в качестве font-size; это связано с тем, что размер шрифта псевдо-элемента ::before по умолчанию равен размеру шрифта элемента, к которому он привязан. Если предположить, что нижнее и верхнее пространства равны, это дает вам:

top-space = (line-height - 1)*1em/2 = (line-height - 1)*0.5em

Противоположное этому значение верхнего пространства дает нам значение, используемое в миксине (мы хотим, чтобы отрицательный отступ обрезал верхнее пространство).

Мы могли бы создать подобный миксин для нижнего пространства (или включить его в миксин lhCrop), но этого нам пока не нужно (поэтому мы, вероятно, не будем его включать). Если же вам это нужно, то вот что вы должны сделать:

создать псевдо-элемента ::after (на этот раз вы хотите удалить пространство внизу текста);

добавить отрицательный margin-bottom (вы можете использовать то же значение, что и для margin-top в миксине lhCrop).

Ограничения

Миксин lhCrop основан на двух упрощениях:

Высота заглавной буквы равна размеру шрифта; это обычно не так. Например, если мы берем семейство шрифтов Roboto, то заглавная буква составляет около 75% от размера шрифта;

Пространство сверху большой буквы равно пространству внизу; опять же, это обычно не так.

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

Вы можете немного улучшить миксин, если хотите отбросить первое упрощение. В качестве примера возьмем семейство шрифтов Roboto, если высота заглавной буквы равна не 1*font-size, а 0.75*font-size, то указанное выше значение отступа будет:

margin-top: (0.75 - line-height)*0.5em

Миксин lhCrop может быть изменен, чтобы учитывать эту переменную:

@mixin lhCrop($line-height, $capital-letter: 1) { &::before { content: ''; display: block; height: 0; width: 0; margin-top: calc((#{$capital-letter} - #{$line-height}) * 0.5em); }
}

На этот раз мы можем передать миксину второе значение: по умолчанию это значение равно 1 (поэтому высота заглавной буквы равна размеру шрифта), но вы можете использовать другое значение, если вам нужно больше контроля. В этом случае, вот как вы бы использовали миксин:

.text-to-crop { @include lhCrop(1.2, 0.75); //using Roboto font family
}

Если вы планируете использовать эту модифицированную версию миксина, то целесообразно было бы определить в файле _typography.scss переменную —capital-letter для каждого из ваших шрифтов и использовать эту переменную при вызове миксина lhCrop:

:root { /* line-height */ --heading-line-height: 1.2; --body-line-height: 1.4; --article-line-height: 1.58; /* capital letters - used in combo with the lhCrop mixin */ --font-primary-capital-letter: 0.75; --font-secondary-capital-letter: 0.69;
} .text-to-crop { @include lhCrop(var(--body-line-height), var(--font-primary-capital-letter));
}

Это делает систему довольно простой в поддержке: если вам нужно изменить семейство шрифтов, то нужно только обновить переменную  —capital-letter, без необходимости изменять вызовы миксина. Вот пример этого миксина в действии:

Что касается второго упрощения, вам нужно будет учитывать descender (нижнее пространство) и ascender (верхнее пространство + заглавная буква) семейства шрифтов, которые вы используете.

Мы фактически не углублялись в эти настройки, поскольку это не было необходимо для наших случаев использования.
Если вам кажется, что вам нужна точность до пикселя или если шрифт, который вы используете, имеет значительный дисбаланс между верхним и нижним отступами, то инструмент Text Crop Tool, вероятно, является лучшим решением для вас.

На данный момент мы решили перейти к упрощенной версии миксина (мы не включили второй аргумент $capital-letter), поскольку эксперименты показали, что достаточная точность достигается и без него.

Автор: Claudia Romano

Источник: https://medium.com/

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