Современная жидкая типографика с использованием CSS Clamp
Опубликовано: 2022-03-10 Концепция гибкой типографики в веб-разработке существовала годами, и разработчикам приходилось полагаться на различные обходные пути, чтобы заставить ее работать в браузере. С новой функцией clamp
CSS создание плавной типографики никогда не было таким простым.
Обычно, когда мы реализуем адаптивную типографику , значения меняются в определенных контрольных точках. Они явно определены. Поэтому дизайнеры часто предоставляют типографские значения (размеры шрифта, высоту строки, межбуквенный интервал и т. д.) для двух, трех или даже большего размера экрана, а разработчики обычно реализуют эти требования, добавляя медиа-запросы для целевых точек останова.
Хотя элементы типографики могут выглядеть так же хорошо, как и на дизайне, это может быть не так для некоторых элементов на ширине окна просмотра, близкой к контрольным точкам. Как мы уже знаем, существует множество различных устройств и размеров экрана, доступных пользователям помимо тех, которые указаны в дизайне. Добавление большего количества промежуточных точек останова и переопределений стилей может решить проблему, но мы рискуем усложнить код, создать больше пограничных случаев и сделать код менее понятным и менее удобным в сопровождении.
Плавная типографика плавно масштабируется между минимальным и максимальным значением в зависимости от ширины области просмотра. Обычно оно начинается с минимального значения и поддерживает постоянное значение до определенной точки ширины экрана, в которой оно начинает увеличиваться. Как только он достигает максимального значения при другой ширине экрана, он поддерживает это максимальное значение с этого момента. В этой статье мы увидим, что плавная типографика также может работать в обратном порядке — начинать с максимального значения и заканчивать минимальным значением.
Этот подход уменьшает или исключает тонкую настройку для конкретных точек останова и других пограничных случаев. Хотя он в основном используется в типографике, этот гибкий подход также работает для полей, отступов, пробелов и т. д.
Обратите внимание, как в следующем примере текст заголовка плавно масштабируется и хорошо выглядит на любой ширине окна просмотра. Кроме того, обратите внимание, что содержимое по-прежнему сохраняет адаптивную типографику, а значение изменяется только в точке останова.
Хотя гибкая типографика решает вышеупомянутые проблемы, она не идеальна для всех сценариев, и гибкую типографику не следует рассматривать как замену адаптивной типографики . У каждого есть свой набор лучших практик и правильных вариантов использования, и мы рассмотрим их позже в этой статье.
В этой статье мы углубимся в гибкую типографику и рассмотрим различные подходы, которые разработчики использовали в прошлом. Мы также рассмотрим функцию clamp
CSS и то, как она упростила реализацию плавной типографики, и узнаем, как точно настроить параметры функции clamp
, чтобы контролировать начальную и конечную точки для плавного поведения. Мы также рассмотрим проблемы доступности, большинство из которых можно решить сегодня, и одну важную проблему доступности, которую мы пока не можем решить.
Первые попытки гибкой типографики
Как разработчики, мы часто используем JavaScript для дополнения отсутствующих функций CSS, пока они не будут разработаны и не будут поддерживаться в основных браузерах. На заре адаптивного веб-дизайна библиотеки JavaScript, такие как FlowType.JS, использовались для достижения плавной типографики.
Первая реальная реализация плавной типографики в CSS появилась с появлением единиц CSS calc
и viewport ( vw
и vh
).
/* Fixed minimum value below the minimum breakpoint */ .fluid { font-size: 32px; } /* Fluid value from 568px to 768px viewport width */ @media screen and (min-width: 568px) { .fluid { font-size: calc(32px + 16 * ((100vw - 568px) / (768 - 568)); } } /* Fixed maximum value above the maximum breakpoint */ @media screen and (min-width: 768px) { .fluid { font-size: 48px; } }
Этот фрагмент выглядит немного сложным, и в расчете задействовано много чисел. Итак, давайте разобьем это на сегменты и проведем общий обзор того, что происходит. Давайте сосредоточимся на селекторах и медиа-запросах, чтобы увидеть случаи, которые они охватывают.
.fluid { /* Min value */ } @media screen and (min-width: [breakpoint-min]) { .fluid { /* Preferred value between the minimum and maximum bound */ } @media screen and (min-width: [breakpoint-max]) { /* Max value */ }
В подходе, ориентированном на мобильные устройства, первый селектор фиксирует значение до минимальной границы. Первый медиа-запрос обрабатывает плавное поведение между двумя точками останова. Последняя точка останова фиксирует значение до максимальной границы. Теперь, когда мы знаем, что делает каждый селектор и медиа-запрос, давайте посмотрим, как применяются минимальные и максимальные границы и как вычисляется значение жидкости.
.fluid { font-size: [value-min]; } @media (min-width: [breakpoint-min]) { .fluid { font-size: calc([value-min] + ([value-max] - [value-min]) * ((100vw - [breakpoint-min]) / ([breakpoint-max] - [breakpoint-min]))); } } @media (min-width: [breakpoint-max]) { .fluid { font-size: [value-max] } }
Это много шаблонного кода для решения очень простой задачи фиксации значения между минимальной и максимальной границами и добавления плавного поведения между двумя точками останова.
Несмотря на объем требуемого шаблонного кода, этот подход стал настолько популярным для определения размера жидкости в целом, что стало ясно, что необходим более рациональный подход. Вот тут-то и появляется функция зажима CSS.
clamp
CSS Функция
Функция CSS clamp
принимает три значения — минимальную границу, предпочтительное значение и максимальную границу , и она фиксирует текущее значение между этими границами. Предпочтительное значение используется для определения значения между границей. Предпочтительное значение обычно включает единицы области просмотра, проценты или другие относительные единицы для достижения плавного эффекта. Это настолько надежная и гибкая функция, что наряду с фиксированными значениями она может принимать даже математические функции и выражения, а также значения из функции attr
.
clamp([value-min], [value-preferred], [value-max]);
Эту функцию можно применять к любому атрибуту, который принимает допустимый тип значения, такой как длина, частота, время, угол, процент, число и другие, поэтому ее можно использовать помимо типографики и размера.
На момент написания этой статьи поддержка браузерами функции clamp
превышает 90%, поэтому она уже хорошо поддерживается. Для неподдерживаемых настольных браузеров, таких как Internet Explorer, достаточно указать резервное значение, поскольку неподдерживаемые браузеры будут игнорировать все выражение font-size
если они не смогут проанализировать функцию clamp
.
font-size: [value-fallback]; /* Fallback value */ font-size: clamp([value-min], [value-preferred], [value-max]);
Жидкая типографика с clamp
CSS
Давайте воспользуемся функцией CSS clamp
и заполним ее следующими значениями:
- Минимальное значение — равно минимальному размеру шрифта.
- Максимальное значение — равно максимальному размеру шрифта.
- Предпочтительное значение — определяет масштабирование плавной типографики — начальную и конечную точки плавного поведения и скорости изменения. Это значение будет зависеть от размера области просмотра, поэтому мы будем использовать единицу измерения ширины области просмотра
vw
.
Давайте посмотрим на следующий пример и установим размер шрифта между 32px
и 48px
. Следующий font-size
имеет минимальное значение 32 32px
и максимальное 48px
. Текущее значение определяется единицей ширины области просмотра или, точнее, 4%
от текущей ширины области просмотра, если это значение находится между минимальной и максимальной границей.
font-size: clamp(32px, 4vw, 48px);
Давайте быстро посмотрим, какое значение будет применяться для этого примера в зависимости от ширины области просмотра, чтобы мы могли получить хорошее представление о том, как работает функция зажима CSS.
Ширина области просмотра (пикс.) | Предпочтительное значение (пикс.) | Применяемое значение (пикс.) |
---|---|---|
500 | 20 | 32 (зажато до минимальной границы) |
900 | 36 | 36 (предпочтительное значение между границами) |
1400 | 56 | 48 (зажато до максимальной границы) |
Мы можем заметить две проблемы с этим значением функции фиксации:
- Значения пикселей для min и max недоступны.
Минимальные и максимальные границы выражаются значениями в пикселях, поэтому они не будут масштабироваться, если пользователь изменит предпочтительный размер шрифта. - Значение области просмотра для предпочтительного значения недоступно.
То же, что и предыдущий случай. Это значение зависит исключительно от ширины области просмотра и не учитывает предпочтения пользователя. - Предпочтительное значение неясно.
Мы используем4vw
, что на первый взгляд может показаться магическим числом. Нам нужно знать, когда начинается и заканчивается плавное поведение, чтобы мы могли синхронизировать различные изменения размера плавного шрифта.
Мы можем легко решить первую проблему, преобразовав значения px
в значения rem
для минимальной и максимальной границ, разделив значения px
на 16 (размер шрифта браузера по умолчанию). При этом минимальные и максимальные значения будут адаптироваться к настройкам браузера пользователя.
font-size: clamp(2rem, 4vw, 3rem);
Нам нужно использовать другой подход с предпочтительным значением, так как это значение должно соответствовать размеру области просмотра. Однако мы можем легко подмешать относительное значение rem
, превратив его в математическое выражение.
font-size: clamp(2rem, 4vw + 1rem, 3rem);
Обратите внимание, что это не надежное решение для всех проблем с доступностью , поэтому все же важно проверить, можно ли достаточно увеличить плавную типографику и достаточно ли хорошо она реагирует на настройки специальных возможностей пользователя. Мы рассмотрим эти вопросы позже.
Однако мы до сих пор не знаем, как мы получили предпочтительное значение из примера ( 4vw + 1rem
) для достижения требуемого поведения жидкости, поэтому давайте посмотрим, как мы можем точно настроить предпочтительное значение и полностью понять математику, стоящую за ним. .
Функция определения размера жидкости
Предпочтительное значение влияет на поведение функции плавной типографики . Точнее, мы можем изменить, в каких точках ширины вьюпорта начинает меняться минимальное значение и в какой точке ширины вьюпорта оно достигает максимального значения.
Например, мы можем захотеть, чтобы плавное поведение начиналось с 1200px
и заканчивалось на 800 800px
ширины области просмотра. Обратите внимание, что для разных минимальных и максимальных границ требуются разные предпочтительные значения (значение окна просмотра и относительный размер), чтобы синхронизировать различные гибкие типографики.
Например, мы обычно не хотим, чтобы одно плавное поведение возникало между 1200px
и 800 800px
ширины области просмотра, а другое — между 1000px
и 750px
области просмотра. Это может привести к несоответствию размеров, как в следующем примере.
Чтобы избежать этой проблемы, нам нужно выяснить, как рассчитывается предпочтительное значение, и назначить правильное окно просмотра и относительные значения для предпочтительного значения функции фиксации.
Давайте разберемся с функцией, которая используется для его вычисления.
font-size: clamp([min]rem, [v]vw + [r]rem, [max]rem);
$$y=\frac{v}{100}*x + r$$
- x — текущее значение ширины области просмотра (
px
). - y — результирующий плавный размер шрифта для текущего значения ширины области просмотра x (
px
). - v — значение ширины области просмотра, влияющее на скорость изменения значения жидкости (
vw
). - r — относительный размер, равный размеру шрифта браузера. Значение по умолчанию —
16px
.
С помощью этой функции мы можем легко рассчитать начальную и конечную точки поведения жидкости. В нашем примере минимальное значение 2rem
( 32px
) остается постоянным до ширины области просмотра 400px
.
$32=\frac{4}{100}*x + 16$$
$$16=\frac{1}{25}*x$$
$$х=400$$
Мы можем применить ту же функцию для максимального значения и увидеть, что оно достигает максимального значения 3rem
( 48px
) при ширине окна просмотра 800px
.
Целью этого примера было просто продемонстрировать, как предпочтительное значение влияет на поведение гибкой типографики. Давайте воспользуемся той же функцией для чуть более реалистичного сценария и решим более практичный пример из реальной жизни. Мы создадим доступную плавную типографику на основе требуемых размеров шрифта и конкретных точек, где мы хотим, чтобы плавное поведение происходило.
Расчет параметров предпочтительного значения на основе конкретных начальных и конечных точек
Давайте рассмотрим практический пример, который часто встречается в реальных сценариях. Дизайнеры предоставили нам размеры шрифта и контрольные точки, которые нам, как разработчикам, необходимы для реализации гибкой типографики со следующими параметрами:
- Минимальный размер шрифта
36px
(y1) - Максимальный размер шрифта —
52px
(y2). - Минимальное значение должно заканчиваться
600px
просмотра 600 пикселей (x1). - Максимальное значение должно начинаться с
1400px
просмотра 1400 пикселей (x2).
Давайте возьмем эти значения и добавим их к функции определения размера жидкости, которую мы обсуждали ранее.
$$y=\frac{v}{100} \cdot x + r$$
В итоге мы получаем два уравнения с двумя параметрами, которые нам нужно рассчитать — значение ширины окна просмотра v
и относительный размер r
.
$$(1)\;\;\; y_1=\frac{v}{100} \cdot x_1 + r$$
$$(2) \;\;\; y_2 =\frac{v}{100} \cdot x_2 + r$$
Мы можем взять первое уравнение и превратить его в следующее выражение, которое мы можем использовать.
$$(1) \;\;\; r=y_1 - \frac{v}{100} \cdot x_1$$
Мы можем заменить r
во втором уравнении этим выражением и получить функцию для вычисления v
.
$$v=\frac{100\cdot (y_2-y_1)}{x_2 - x_1}$$
$$v=\frac{100 \cdot (52-36)}{1400 - 600}$$
$$v=2$$
Получаем значение ширины области просмотра 2vw
. Аналогичным образом мы можем выделить r
и вычислить его, используя доступные параметры.
$$r=\frac{x_1y_2 - x_2y_1}{x_1 - x_2}$$
$$r=\frac{600 \cdot 52 - 1400 \cdot 36}{600 - 1400}$$
$$r=24$$
Примечание . Это значение указано в пикселях, а относительное значение должно быть выражено в rem
, поэтому мы делим значение пикселя на 16
и 1.5rem
.
Нам также нужно преобразовать минимальную границу 36px
и максимальную границу 52px
в rem
и добавить все значения в функцию CSS clamp
.
font-size: clamp(2.25rem, 2vw + 1.5rem, 3.25rem);
Мы можем построить эту функцию, чтобы подтвердить правильность вычисленных значений.
Подводя итог, мы можем использовать следующие две функции для вычисления параметров предпочтительного значения v
(выраженного в vw
) и r
(выраженного в rem
) из размеров шрифта и точек ширины области просмотра.
$$v=\frac{100\cdot (y_2-y_1)}{x_2 - x_1}$$
$$r=\frac{x_1y_2 - x_2y_1}{x_1 - x_2}$$
Теперь, когда мы полностью понимаем, как работает функция clamp
и как рассчитывается предпочтительное значение, мы можем легко создавать последовательную и доступную гибкую типографику в наших проектах и избегать вышеупомянутых ловушек.
Использование отрицательного значения области просмотра для изменения размера жидкости
Мы также можем увеличить масштаб по мере уменьшения размера области просмотра , используя отрицательное значение для значения области просмотра. Отрицательное значение области просмотра изменит поведение жидкости по умолчанию. Нам также необходимо настроить относительный размер, чтобы поведение жидкости начиналось и заканчивалось в определенных точках, путем решения двух вышеупомянутых уравнений из предыдущего примера.
font-size: clamp(3rem, -4vw + 6rem, 4.5rem);
Я не использовал эту обратную конфигурацию в своих проектах, но вам может быть интересно, если вы когда-нибудь столкнетесь с этим требованием в своем проекте или дизайне.
Инструмент визуализации плавной типографики
Пока я работал над проектом, мне пришлось создать несколько различных конфигураций гибкой типографики. Я тестировал конфигурации в браузере, и у меня возникла идея создать инструмент, который помог бы разработчикам визуализировать и точно настроить поведение плавной типографики. Меня вдохновила одна из демонстраций из курса Джоша В. Комо «CSS для разработчиков JS», и я создал инструмент Modern Fluid Typography Tool.
Разработчики могут использовать этот инструмент для создания и тонкой настройки фрагментов кода плавной типографики, а также для визуализации поведения плавной типографики для синхронизации нескольких экземпляров. Инструмент также может генерировать ссылку на конфигурацию, поэтому разработчики могут включать ссылку в комментарии к коду или документацию, чтобы другие могли легко проверить поведение изменения размера.
Этот проект бесплатный и с открытым исходным кодом, поэтому не стесняйтесь сообщать о любых ошибках и вносить свой вклад. Я рад услышать ваши мысли и пожелания!
Проблемы доступности
Важно повторить, что использование значений rem
не делает гибкую типографику автоматически доступной для всех пользователей, а только позволяет размерам шрифта соответствовать предпочтениям пользователя. Использование функции CSS clamp
в сочетании с единицами измерения окна просмотра для достижения плавного изменения размера приводит к еще одному набору недостатков , которые нам необходимо учитывать.
Адриан Роселли тщательно протестировал и задокументировал эти проблемы в своем блоге.
«Когда вы используете единицыvw
или ограничиваете размер текста с помощьюclamp()
, есть вероятность, что пользователь не сможет масштабировать текст до 200% от его исходного размера. Если это произойдет, это означает сбой WCAG в разделе 1.4.4 Изменение размера текста (AA), поэтому обязательно проверьте результаты с увеличением».
— Адриан Роселли
Я хотел решить эту проблему с самого начала, используя JavaScript, чтобы определить, когда происходит событие масштабирования, и применить класс, который переопределит размер жидкости с помощью обычного значения rem
.
/* Apply fluid typography for default zoom level (not zoomed) */ .title { font-size: clamp(2rem, 4vw + 1rem, 3rem); } /* Revert to responsive typography if zoom is active */ body.zoom-active .title { font-size: 2rem; } @media screen and (min-width: 768px) { body.zoom-active .title { font-size: 3rem; } }
Вы можете быть удивлены, так как я узнал, что мы не можем надежно обнаружить событие масштабирования с помощью JavaScript, как мы можем обнаружить любое другое обычное событие области просмотра, например изменение размера.
На момент написания этой статьи существует спецификация Visual Viewport API с твердой поддержкой браузера на 92%, но значение масштаба (уровня масштабирования) просто не работает — оно возвращает одно и то же значение независимо от значения масштабирования (масштаба). Не говоря уже об отсутствии документации, рабочих примеров или вариантов использования. Это немного странно, учитывая, что этот API имеет такую надежную поддержку браузеров. Некоторые обходные пути существуют, но они также не являются полностью надежными и не могут определить, была ли страница увеличена при ее первой загрузке, только после того, как событие произошло.
Если бы Visual Viewport API работал должным образом, мы могли бы легко переключать класс CSS в событии масштабирования.
/* This code won't work because visualViewport.scale is buggy * and always returns the same value. This might be fixed in the future. */ function checkZoomLevel() { if (window.visualViewport.scale === 1) { document.body.classList.remove("zoom-active"); } else { document.body.classList.add("zoom-active"); } } window.addEventListener("resize", checkZoomLevel);
К сожалению, применяя гибкие размеры, мы рискуем сделать контент недоступным для некоторых пользователей, которые используют функцию масштабирования во время просмотра. До тех пор, пока мы не сможем создать надежный и более доступный запасной вариант для гибкой типографики, не забывайте использовать плавные размеры с осторожностью и проверяйте , соответствуют ли уровни масштабирования Руководству по обеспечению доступности веб-контента (WCAG).
Рекомендуемые варианты использования
Гибкая типографика лучше всего подходит для больших и заметных текстовых элементов с большей разницей между минимальным и максимальным размером. Большие заголовки будут выглядеть более резкими и неуместными на небольших окнах просмотра, если их не масштабировать соответствующим образом.
Калибровка жидкости также рекомендуется в тех случаях, когда нам необходимо поддерживать постоянный размер.
Элиз Хейн пришла к такому же выводу в своей статье о передовых методах гибкой типографики.
«Я пытался, но не смог найти много конкретных областей, где типографика, относящаяся к области просмотра, превосходит размер, основанный на контрольных точках, с точки зрения удобочитаемости. Вот два из них: настройка отображаемого текста и поддержание постоянной меры ».
— Элиза Хайн
Гибкая типографика не так эффективна и полезна, если разница между минимумом и максимумом составляет всего несколько пикселей , как это обычно бывает с основным текстом. Основной текст с небольшой разницей между минимальным и максимальным размерами шрифта не будет выглядеть неуместно на любой ширине окна просмотра, как в случае с большими размерами шрифта. В таких случаях рекомендуется использовать обычную адаптивную типографику с контрольными точками.
Заключение
Гибкая типографика должна служить не заменой адаптивной типографики, а улучшением для конкретных случаев использования. Мы должны использовать гибкую типографику для плавного масштабирования текста, который имеет большую разницу между минимальным и максимальным размером, и для поддержания постоянного размера.
При использовании нескольких элементов гибкой типографики с функцией clamp
CSS мы должны убедиться, что масштабирование жидкости синхронизировано. Мы можем сделать это, рассчитав ширину области просмотра и относительное значение и используя их в качестве предпочтительных значений в функции clamp
CSS. Мы также должны помнить об использовании относительных единиц, таких как единица rem, чтобы гибкая типографика адаптировалась к предпочтениям пользователя по размеру шрифта.
Мы также видели, как плавная типографика может ограничивать возможности масштабирования пользователя, что может вызвать проблемы с доступностью. Важно протестировать гибкую типографику с масштабированием и вернуть ее к обычной адаптивной типографике, если тестирование покажет, что содержимое недостаточно масштабируемо.
Мы должны иметь возможность решить эту проблему, переопределив значения плавной типографики, когда происходит действие масштабирования. Однако в настоящее время это невозможно сделать, так как Visual Viewport API не работает должным образом и не реагирует на пользовательские события масштабирования.
использованная литература
-
clamp()
, MDN - «Почему шрифт должен быть плавным?», Элиза Хейн.
- «Упрощенная плавная типографика», Крис Койер
- «Отзывчивый шрифт и масштабирование», Адриан Роселли
- «Отзывчивая и плавная типографика с единицами
vh
иvw
», Майкл Ритмюллер.