Создание плавной типографической шкалы с помощью CSS clamp()#
Общие сведения#
Долгое время во многих дизайн-системах реализовывалось статическое определение размера шрифта, с набором переменных размера шрифта, которые постепенно увеличивались и уменьшались по обе стороны от базового размера шрифта ( baseline font size):
html {
--font-size-sm: 0.75rem;
--font-size-base: 1rem;
--font-size-md: 1.125rem;
--font-size-lg: 1.5rem;
}
Однако такой подход имел существенное ограничение: поскольку каждый шаг типографической шкалы представлял собой * фиксированный размер шрифта*, приходилось писать медиа-запросы, чтобы увеличить или уменьшить размеры текста на разных ширинах экрана и обеспечить читаемость. Это не только приводило к разрастанию CSS-кода, но и было утомительно в реализации — дизайнерам приходилось предоставлять два набора значений: для мобильных и для десктопных экранов. Кроме того, шрифт менялся резко в момент пересечения брейкпоинта, вместо того чтобы масштабироваться плавно.
Плавная типографика (fluid typography) — современное решение этой проблемы. Она позволяет каждому размеру шрифта в
шкале адаптироваться между минимальным и максимальным значением. Это одна из самых популярных тем в современном CSS:
написано множество статей о том, как лучше реализовать плавное масштабирование, а также появилось множество *
open-source инструментов*, которые позволяют просто скопировать и вставить готовые CSS-объявления font-size с
использованием плавного масштабирования прямо в ваш проект. Всё это стало возможно благодаря функции clamp() в CSS
и мощности единиц, зависящих от размера окна просмотра (viewport units).
Самая сложная часть при работе с clamp() — это вычисление правильного “предпочтительного” (preferred) значения.
Это можно сделать вручную, но интуитивно понимать значения в viewport-единицах бывает непросто, если вы не работаете с
простыми процентами.
Чтобы решить эту проблему, можно создать переиспользуемую функцию на Sass, которая оборачивает нативную clamp() и
автоматически вычисляет оптимальное среднее значение, если заданы минимальные и максимальные размеры шрифта, а также
минимальная и максимальная ширина экрана.
В завершение, эту функцию можно использовать для программной генерации CSS-переменных, образующих модульную типографическую шкалу, полностью основанную на плавной адаптации.
Если вы не используете Sass, подход, описанный в этой статье, можно применить практически в любом контексте, где
доступны простые математические операции — включая чистый CSS с помощью функции calc(). Последний вариант
получается немного более громоздким, поэтому, если есть возможность, лучше воспользоваться препроцессором, таким как
Sass.
Альтернативно, вы можете воспользоваться инструментом Fluid Type Scale Calculator — это open-source-проект, который я опубликовал. Он позволяет настраивать параметры и копировать готовые переменные для плавной типографики прямо в ваш проект.

Как работает clamp()?#
Если кратко, функция clamp() принимает предпочтительное значение и ограничивает его в заданных пределах — между минимумом и максимумом.
.element {
font-size: clamp(min, preferred, max);
}
Функция clamp() всегда старается вернуть предпочтительное значение, если оно находится между минимальным и
максимальным пределом.
Если же предпочтительное значение меньше минимума, clamp() вернёт минимум.
Если оно больше максимума, функция вернёт максимум.
Отсюда и название — clamp буквально «зажимает» значение между двумя границами.
Во всех примерах этой статьи используется размер шрифта, поскольку именно на нём сосредоточен урок. Однако стоит
отметить, что clamp() можно применять для плавного масштабирования любого числового CSS-свойства — например,
отступов (padding), полей (margin), размеров (width, height), границ (border) и многого другого.
Идеальное сочетание: clamp() и единицы vw#
На первый взгляд функция clamp() может показаться не особо интересной, но она становится очень мощной, когда
предпочтительное значение выражено в единицах ширины окна просмотра (vw). Это позволяет задавать плавные
величины, которые пересчитываются при каждом изменении ширины окна.
Таким образом, можно заменить медиа-запросы при масштабировании шрифтов на динамические значения, которые изменяются линейно.
1 единица vw равна 1% текущей ширины окна просмотра.
Например, если окно имеет ширину 360 пикселей, то 10vw будет равняться 36 пикселям.
Используя clamp() и vw вместе, мы можем создать адаптивное значение, которое изменяется в зависимости от ширины
окна, но при этом всегда остаётся в пределах заданного минимума и максимума.
Например, предположим, что у нас есть следующий CSS для задания размера шрифта:
p {
font-size: clamp(1rem, 4vw, 1.5rem);
}
У нас есть следующие значения:
Минимум:
1rem(16 px)Предпочтительное:
4vwМаксимум:
1.5rem(24 px)
Браузер сначала попытается вернуть предпочтительное значение — в данном случае это 4vw (4 % ширины окна
просмотра).
Значит, браузеру нужно сначала определить ширину окна и вычислить, сколько это будет в пикселях.
Вот несколько примеров:
Ширина окна |
Мин |
Макс |
Предпочтительное |
Возвращаемое |
|---|---|---|---|---|
320 px |
16 px |
24 px |
12.8 px |
16 px |
500 px |
16 px |
24 px |
20 px |
20 px |
1000 px |
16 px |
24 px |
40 px |
24 px |
Это уже выглядит многообещающе, но, как упоминалось ранее, есть один существенный недостаток при использовании
clamp() в чистом виде:
нам приходится вручную рассчитывать предпочтительное значение, а думать в единицах vw бывает не слишком удобно,
если мы не оперируем простыми соотношениями.
К счастью, если мы используем Sass, это можно упростить, создав пользовательскую функцию clamp(), которая *
автоматически вычисляет предпочтительное значение* и подставляет его в стандартное CSS-выражение clamp().
Но прежде чем это сделать, нужно понять, какая математическая зависимость существует между размером шрифта и шириной окна просмотра, чтобы найти точную формулу.
Нахождение предпочтительного значения для clamp() с помощью линейной интерполяции#
До сих пор мы не рассматривали, как именно вычисляется предпочтительное значение для clamp().
Теоретически, туда можно подставить любое произвольное число и надеяться, что оно «будет смотреться нормально», как в
приведённом примере.
Однако на деле мы можем рассчитать точное значение математически.
Для начала нужно понять, что нам редко когда нужны просто абстрактные минимальный и максимальный размеры шрифта — мы обычно привязываем их к конкретным ширинам экрана. То есть вместо того чтобы говорить:
Хочу, чтобы шрифт был от 16 px до 19 px,
мы должны сформулировать задачу точнее:
Хочу, чтобы минимальный размер шрифта (16 px) использовался при ширине окна 400 px, а максимальный размер (19 px) — при ширине 1000 px.
Теперь у нас не два, а четыре значения:
Минимальный размер шрифта — 16 px
Максимальный размер шрифта — 19 px
Минимальная ширина экрана, при которой используется минимум — 400 px
Максимальная ширина экрана, при которой используется максимум — 1000 px
Так как минимальный брейкпоинт соответствует минимальному размеру шрифта, а максимальный — максимальному, логично объединить их в пары в виде точек (x, y):
Минимум: (400 px, 16 px)
Максимум: (1000 px, 19 px)
Если изобразить это на графике, где
ось X — это ширина окна (viewport width),
ось Y — это размер шрифта,
то получится, что при увеличении ширины окна от 400 до 1000 px, размер шрифта также линейно увеличивается.
Линия между этими двумя точками и есть предпочтительное значение для clamp() — то, что функция будет вычислять при
изменении ширины окна.

По мере увеличения ширины окна просмотра размер шрифта растёт линейно — до достижения максимального значения.
У нас есть две точки ((x, y)), и уравнение прямой, проходящей через эти точки, как раз и будет выражением для *
предпочтительного значения* в clamp().
Мы уже знаем минимальные и максимальные значения для clamp(), значит, это уравнение — недостающее звено.
Уравнение прямой#
Уравнение прямой задаётся в наклонно-перехватной форме: [ y = mx + b ]
где:
m — это угловой коэффициент (slope), который показывает, как быстро изменяется (y) (размер шрифта) при изменении (x) (ширины окна),
b — это пересечение с осью Y (y-intercept), то есть значение (y), когда (x = 0).
Чтобы найти наклон (m), нужно вычислить разницу между значениями шрифта и разделить её на разницу между ширинами окна:
[ m = \frac{y_2 - y_1}{x_2 - x_1} ]
где:
(y_1) и (y_2) — минимальный и максимальный размеры шрифта,
(x_1) и (x_2) — минимальная и максимальная ширина окна просмотра.
Таким образом, если, например:
минимальный размер шрифта (y_1 = 16px),
максимальный (y_2 = 19px),
минимальная ширина окна (x_1 = 400px),
максимальная ширина окна (x_2 = 1000px),
тогда:
[ m = \frac{19 - 16}{1000 - 400} = \frac{3}{600} = 0.005 ]
Это и есть скорость роста шрифта при изменении ширины окна: на каждые 100 пикселей увеличения ширины шрифт становится больше на 0.5 пикселя.
m = (maxFontSize - minFontSize) / (maxBreakpoint - minBreakpoint)
Начнём с основного уравнения: [ y = mx + b ]
У нас есть две точки: ((x_1, y_1)) и ((x_2, y_2)). По определению, наклон (m) и пересечение с осью Y (b) одинаковы для обеих точек, так как это одна и та же прямая. Значит, можно записать два уравнения для этих двух точек:
y2 = m(x2) + b
y1 = m(x1) + b
Теперь вычтем второе уравнение из первого:
y2 - y1 = m(x2 - x1)
Из этого выражения можно найти наклон (m):
m = (y2 - y1) / (x2 - x1)
В нашем примере:
значения x — это ширина окна просмотра (viewport width),
значения y — это размер шрифта (font size).
Таким образом, коэффициент (m) показывает, насколько изменяется размер шрифта при изменении ширины экрана.
Вот перевод текста:
Подставляя числа из нашего примера, мы получаем следующий результат:
m = (19px - 16px) / (1000px - 400px) = 3px/600px = 0.005
Это говорит нам о том, что в нашем конкретном примере размер шрифта увеличивается на 0,005px на каждую единицу ширины области просмотра (viewport width). Мы можем подставить это значение обратно в формулу линейной функции ($y = mx + b$) вместе с одной из двух исходных точек, чтобы вычислить ординату точки пересечения с осью Y ($y$-intercept). Неважно, какую из двух точек мы подставим в уравнение, потому что линия проходит через обе. Я буду использовать минимальное значение:
y = mx + b
16px = 0.005(400px) + b
b = 16px - 0.005(400px) = 16px - 2px = 14px
Отлично! Теперь у нас есть две ключевые части информации, описывающие нашу линию:
Наклон ($m$, slope): 0,005
Точка пересечения с осью Y ($b$, y-intercept): 14px
Это дает нам следующее уравнение для предпочтительного значения (preferred value) функции clamp:
preferredValue = y = mx + b = 0.005(x) + 14px
В CSS нам нужно выразить наклон, используя соответствующие единицы области просмотра (viewport units), что делается
путем умножения наклона на 100, чтобы получить процент. Это дает следующее объявление clamp:
p { font-size: clamp(16px, 0.5vw + 14px, 19px);}
Мы это сделали! Имея только минимальную и максимальную точку, мы нашли правильное предпочтительное значение для
clamp. Если вы не доверяете математике, попробуйте подставить несколько чисел. Таблица ниже подтверждает, что
предпочтительное значение возвращает минимальный размер шрифта в нашей минимальной контрольной точке (breakpoint) и
максимальный размер шрифта в нашей максимальной контрольной точке. При размерах экрана между минимальной и максимальной
конечными точками уравнение для предпочтительного значения clamp дает адаптивное значение.
Ширина области просмотра |
Предпочтительное значение |
|---|---|
400px (мин. контрольная точка) |
$0.005 * 400px + 14px = 16px$ |
700px (середина) |
$0.005 * 700px + 14px = 17.5px$ |
1000px (макс. контрольная точка) |
$0.005 * 1000px + 14px = 19px$ |
В качестве заключительного шага мы захотим выразить значения в пикселях в rem (relative to the root element’s font-size), чтобы учитывать настройки размера шрифта в браузере. Для этого мы разделим каждое значение в пикселях на * 16px* (базовый размер шрифта для всех браузеров):
Продолжение перевода:
p { font-size: clamp(1rem, 0.5vw + 0.875rem, 1.1875rem);}
Отлично! Подводя итог, вот шаги, которые мы предприняли для получения этого решения:
Мы взяли минимальную и максимальную точки, каждая из которых состоит из размера шрифта и соответствующей контрольной точки.
Мы нашли уравнение линии между этими двумя точками.
Мы подставили это уравнение в качестве предпочтительного значения для
clamp.Наконец, мы преобразовали все пиксели в rem.
Теперь, когда мы выполнили это упражнение вручную, мы можем перевести его в код.
Создание Пользовательской Функции clamp на Sass#
Мы хотим написать функцию Sass, которая принимает минимальное и максимальное значения и соответствующие им контрольные точки:
p {
font-size: clamped(16px, 19px, 400px, 1000px);
}
Мы установим значения по умолчанию для контрольных точек, чтобы нам не приходилось всегда их передавать. Затем функция должна вернуть следующий CSS, выполняя все вычисления внутри:
p { font-size: clamp(1rem, 0.5vw + 0.875rem, 1.1875rem);}
Чтобы установить значения по умолчанию для минимальной и максимальной контрольных точек, мы начнем с создания карты для наших медиа-контрольных точек и импортируем некоторые пространства имен Sass (необходимы только при использовании Dart Sass):
_functions.scss
@use "sass:math";
@use "sass:map";
$media-breakpoints: (
mobile: 400px,
desktop: 1000px,
// ...здесь могут быть другие значения
);
Далее мы создадим нашу функцию Sass и установим минимальную и максимальную контрольные точки по умолчанию на mobile и
desktop соответственно. Таким образом, мы можем передавать переопределения в каждом конкретном случае, но использовать
логику по умолчанию: “минимум равен mobile”, а “максимум равен desktop”.
_functions.scss
$default-min-bp: map.get($media-breakpoints, "mobile");
$default-max-bp: map.get($media-breakpoints, "desktop");
@function clamped($min-px, $max-px, $min-bp: $default-min-bp, $max-bp: $default-max-bp) {
// код здесь
}
Теперь нам просто нужно найти наклон и точку пересечения с осью Y для уравнения, представляющего предпочтительное
значение для clamp — линию между минимальной и максимальной точками. Вот код для этой части:
_functions.scss
$slope: math.div($max-px - $min-px, $max-bp - $min-bp);
$intercept-px: $min-px - $slope * $min-bp;
$slope-vw: $slope * 100;
И это вся информация, которая нам нужна! Последний шаг — вернуть из нашей функции Sass стандартное объявление clamp
на чистом CSS, интерполируя все соответствующие значения в строке:
@return
clamp
(
#{$min-px}, #{$slope-vw}vw + #{$intercept-px}, #{$max-px}
)
;
Однако, как упоминалось ранее, мы не хотим использовать пиксели для размеров шрифта. Чтобы исправить это, мы можем создать еще одну функцию Sass, которая будет преобразовывать пиксели в rem (возможно, она у вас уже есть в кодовой базе):
_functions.scss
@function to-rems($px) {
$rems: math.div($px, 16px) * 1rem;
@return $rems;
}
И мы будем использовать ее для преобразования всех наших пикселей в rem. Вот окончательный код:
_functions.scss
@function clamped($min-px, $max-px, $min-bp: $default-min-bp, $max-bp: $default-max-bp) {
$slope: math.div($max-px - $min-px, $max-bp - $min-bp);
$slope-vw: $slope * 100;
$intercept-rems: to-rems($min-px - $slope * $min-bp);
$min-rems: to-rems($min-px);
$max-rems: to-rems($max-px);
@return clamp(#{$min-rems}, #{$slope-vw}vw + #{$intercept-rems}, #{$max-rems});
}
Наконец, обратите внимание, что в зависимости от того, какие значения вы передаете в эту функцию, вы можете получить
очень длинные числа с плавающей запятой. Вы можете определить пользовательскую функцию округления, чтобы усечь их (не
дайте себя обмануть встроенной функцией Sass math.round; она округляет до ближайшего целого числа). Следующий код
является модификацией этого удобного gist от пользователя GitHub terkel:
_functions.scss
@function rnd($number, $places: 0) {
$n: 1;
@if $places > 0 {
@for $i from 1 through $places {
$n: $n * 10;
}
}
@return math.div(math.round($number * $n), $n);
}
А затем обновим clamped, чтобы использовать ее:
_functions.scss
@function clamped($min-px, $max-px, $min-bp: $default-min-bp, $max-bp: $default-max-bp) {
$slope: math.div($max-px - $min-px, $max-bp - $min-bp);
$slope-vw: rnd($slope * 100, 2);
$intercept-rems: rnd(to-rems($min-px - $slope * $min-bp), 2);
$min-rems: rnd(to-rems($min-px), 2);
$max-rems: rnd(to-rems($max-px), 2);
@return clamp(#{$min-rems}, #{$slope-vw}vw + #{$intercept-rems}, #{$max-rems});
}
Превосходно! Теперь этот код Sass:
p {
font-size: clamped(16px, 19px);
}
Компилируется в следующий CSS:
p { font-size: clamp(1rem, 0.5vw + 0.88rem, 1.19rem);}
Напомним, что это точно такой же результат (но округленный), который мы получили вручную в нашем более раннем
исследовании. Но используя математические возможности Sass, мы смогли абстрагировать это в многократно используемую
функцию. Теперь мы можем передавать любые минимальные и максимальные значения в нашу утилиту clamp, и она
гарантирует адаптивное и плавно меняющееся масштабирование. Более того, это можно использовать не только для размера
шрифта.
Но давайте не будем останавливаться на достигнутом! Теперь мы будем использовать эту функцию для создания плавной типографской шкалы (fluid type scale).
Продолжение перевода:
Создание Плавающей Типографской Шкалы с clamp#
В модульной типографской шкале вы начинаете с базового размера шрифта и определяете набор постепенно увеличивающихся и уменьшающихся «шагов» по обе стороны от базового. Следующий по величине размер шрифта от базового — это выбранное вами отношение (ratio), умноженное на базовый размер шрифта. Второй по величине размер шрифта — это базовый размер шрифта, умноженный на квадрат отношения. Аналогично, если вы создаете постепенно уменьшающиеся размеры шрифта, вы делите базовый размер шрифта на ваше отношение.
Эту взаимосвязь можно очень естественно выразить с помощью степеней, где размер шрифта для данного шага — это базовый размер шрифта, умноженный на некоторую степень модульного отношения. В таблице ниже приведены примеры значений, предполагая базовый размер шрифта 16px (1rem) и модульное отношение 1.2 (формально известное как малая терция (minor third)).
Шаг |
Значения |
|---|---|
sm |
$16 \times (1.2)^{-1}$ |
base |
$16 \times (1.2)^{0}$ |
md |
$16 \times (1.2)^{1}$ |
lg |
$16 \times (1.2)^{2}$ |
xl |
$16 \times (1.2)^{3}$ |
Наивный Подход: Создание Типографской Шкалы Вручную#
В качестве первого шага мы могли бы создать пользовательские свойства для всех наших размеров шрифта и использовать неявную модульную шкалу, вычисляя минимальные и максимальные значения вручную (например, с помощью калькулятора):
html {
--font-size-sm: clamped(13.33px, 16px);
--font-size-base: clamped(16px, 19.2px);
--font-size-md: clamped(19.2px, 23.04px);
--font-size-lg: clamped(23.04px, 27.65px);
--font-size-xl: clamped(27.65px, 33.18px);
--font-size-xxl: clamped(33.18px, 39.81px);
--font-size-xxxl: clamped(39.81px, 47.78px);
}
Это компилируется в следующий набор переменных плавной типографики:
html {
--font-size-sm: clamp(0.83rem, 0.44vw + 0.72rem, 1rem);
--font-size-base: clamp(1rem, 0.53vw + 0.87rem, 1.2rem);
--font-size-md: clamp(1.2rem, 0.64vw + 1.04rem, 1.44rem);
--font-size-lg: clamp(1.44rem, 0.77vw + 1.25rem, 1.73rem);
--font-size-xl: clamp(1.73rem, 0.92vw + 1.5rem, 2.07rem);
--font-size-xxl: clamp(2.07rem, 1.11vw + 1.8rem, 2.49rem);
--font-size-xxxl: clamp(2.49rem, 1.33vw + 2.16rem, 2.99rem);
}
Но мы можем сделать лучше!
Программное Генерирование Плавающей Типографской Шкалы#
Предыдущий подход работает, но он не идеален. Если вы когда-либо захотите использовать другую модульную шкалу, вам придется вручную обновлять все минимальные и максимальные значения. Вместо этого мы хотим настроить многократно используемый и простой в применении шаблон для плавающего размера шрифта; мы не хотим выполнять никаких вычислений вручную. Итак, в этом разделе мы рассмотрим, как еще больше автоматизировать процесс, программно генерируя пользовательские свойства CSS для наших размеров шрифта с помощью циклов Sass.
Хорошая новость в том, что основная работа уже проделана, особенно если мы изменим таблицу, чтобы вычислить как минимальный, так и максимальный размеры шрифта для каждого модульного шага. Опять же, это предполагает базовый размер шрифта 16px и желаемое модульное отношение 1.2.
Модульный шаг |
Мин. размер шрифта |
Макс. размер шрифта |
|---|---|---|
sm |
$16 \times (1.2)^{-2}$ |
$16 \times (1.2)^{-1}$ |
base |
$16 \times (1.2)^{0}$ |
$16 \times (1.2)^{1}$ |
md |
$16 \times (1.2)^{1}$ |
$16 \times (1.2)^{2}$ |
lg |
$16 \times (1.2)^{2}$ |
$16 \times (1.2)^{3}$ |
xl |
$16 \times (1.2)^{3}$ |
$16 \times (1.2)^{4}$ |
Мы начнем с создания следующих переменных:
_variables.scss
@use "sass:math";
$type-base: 16px;
$type-scale: 1.2;
$type-steps: "sm", "base", "md", "lg", "xl", "xxl", "xxxl";
$type-base-index: list.index($type-steps, "base");
Список $type-steps содержит имена всех шагов в нашей типографской шкале. Нам также необходимо знать индекс базового
размера шрифта ($type-base-index), чтобы мы могли генерировать правильные степени для каждого шага.
Теперь мы выполним цикл по модульным шагам и объединим все, что мы узнали до сих пор, чтобы программно генерировать переменные шрифта:
index.scss
html {
@for $i from 1 through length($type-steps) {
$step: list.nth($type-steps, $i);
$min: $type-base * math.pow($type-scale, $i - $type-base-index);
$max: $type-base * math.pow($type-scale, $i - $type-base-index + 1);
--font-size-#{$step}: #{clamped($min, $max)};
}
}
Который выдает тот же результат, что и раньше:
html {
--font-size-sm: clamp(0.83rem, 0.44vw + 0.72rem, 1rem);
--font-size-base: clamp(1rem, 0.53vw + 0.87rem, 1.2rem);
--font-size-md: clamp(1.2rem, 0.64vw + 1.04rem, 1.44rem);
--font-size-lg: clamp(1.44rem, 0.77vw + 1.25rem, 1.73rem);
--font-size-xl: clamp(1.73rem, 0.92vw + 1.5rem, 2.07rem);
--font-size-xxl: clamp(2.07rem, 1.11vw + 1.8rem, 2.49rem);
--font-size-xxxl: clamp(2.49rem, 1.33vw + 2.16rem, 2.99rem);
}
Самая сложная часть здесь — это логика степеней для минимального и максимального значений:
$min: $type-base * math.pow($type-scale, $i - $type-base-index);
$max: $type-base * math.pow($type-scale, $i - $type-base-index + 1);
Мы выполняем $i - $type-base-index для минимального размера шрифта каждого шага, поскольку наш базовый модульный шаг
не обязательно должен быть первым элементом в списке (например, если у нас есть меньшие шаги, как sm в приведенном
выше примере). Поэтому мы получаем его индекс и вычитаем его из текущего индекса, чтобы получить правильное смещение для
минимальной степени. Добавление единицы к этому результату дает нам максимальную степень. В таблице ниже это
проиллюстрировано для нескольких модульных шагов.
Шаг |
$i$ (индекс) |
$type-base-index$ |
$i - type-base-index$ (степень для Min) |
$i - type-base-index + 1$ (степень для Max) |
|---|---|---|---|---|
sm |
1 |
2 |
-1 |
0 |
base |
2 |
2 |
0 |
1 |
md |
3 |
2 |
1 |
2 |
Короче говоря, код циклически проходит по каждому шагу шрифта и генерирует минимальное и максимальное значения,
используя нашу желаемую типографскую шкалу. Затем эти минимальные и максимальные значения передаются нашей
пользовательской функции clamped, которая автоматически вычисляет предпочтительное значение. Мы получаем тот же
результат, что и в предыдущем разделе, но теперь мы можем настроить базовый размер шрифта и типографскую шкалу, просто
изменив две переменные. Все просто работает!
Опять же, вы можете захотеть округлить значения с помощью функции, которую мы создали ранее.
Использование Различных Типографских Шкал для Мобильных и Десктопных Устройств#
Подход, который мы только что рассмотрели, включает выбор минимального размера шрифта для базового модульного шага и вывод максимального размера шрифта для каждого шага с использованием некоторой степени нашего выбранного отношения ( например, $1.2$). Но это не всегда дает желаемые результаты. В зависимости от выбранной вами типографской шкалы, в конечном итоге вы все равно можете получить слишком большие размеры шрифта на мобильных устройствах, даже если ваши размеры шрифта технически являются плавными (fluid).
Вместо этого вы можете захотеть, чтобы минимальный и максимальный размеры шрифта были независимыми. В этом случае, вместо того чтобы указывать только минимальный размер шрифта и одно отношение типографской шкалы, нам фактически нужны * два отдельных набора переменных*: один для минимального (мобильного) и один для максимального (десктопного). Таким образом, если раньше у нас был только один базовый размер шрифта, теперь нам понадобятся два: явный минимальный и максимальный базовый размер шрифта.
_variables.scss
$type-base-min: 16px;
$type-base-max: 19px;
Аналогично, нам понадобится соответствующее минимальное и максимальное отношение типографской шкалы:
_variables.scss
$type-scale-min: 1.2;
$type-scale-max: 1.333;
И теперь мы изменим наш цикл, чтобы использовать эти новые переменные для минимального и максимального значений соответственно:
index.scss
html {
@for $i from 1 through length($type-steps) {
$step: list.nth($type-steps, $i);
$power: $i - $type-base-index;
$min: $type-base-min * math.pow($type-scale-min, $power);
$max: $type-base-max * math.pow($type-scale-max, $power);
--font-size-#{$step}: #{clamped($min, $max)};
}
}
Это дает вам больший контроль над размером шрифта, поскольку вы больше не привязаны к одной типографской шкале как для мобильных, так и для десктопных устройств. Теперь вы можете свободно выбирать разное отношение для каждой контрольной точки. Я рекомендую использовать меньшее отношение для мобильных устройств, чем то, которое используется на десктопе. Это гарантирует, что размер вашего шрифта остается оптимально читаемым на маленьких устройствах.
Мы рассмотрели только одно применение этой техники: создание плавной типографской шкалы (fluid type scale). Но правда в том, что вы можете повторно использовать функцию clamped для отступов (margins), внутренних отступов (padding) и практически любого другого числового свойства.