Гибкие размеры с clamp
В адаптивном каталоге хочется менять некоторые величины плавно: заголовок может быть немного крупнее на широком экране, а промежутки между карточками — свободнее. Но бесконечный рост по ширине окна неудобен, как и слишком мелкая надпись на телефоне. Функция clamp выбирает предпочтительное значение между заданными нижней и верхней границами.
В двенадцатом уроке мы уже использовали готовое выражение для заголовка. Теперь разберём его устройство и применим тот же приём к промежутку и внутреннему отступу. Результат — три ограниченные величины в прежнем каталоге. Количество столбцов продолжает определять Grid, а форму и ссылки не приходится пересоздавать при каждом размере окна.
Предпочтительная величина внутри диапазона
Запись clamp(minimum, preferred, maximum) сравнивает три вычисленных величины совместимого типа. Пока предпочтительное значение лежит между границами, оно используется напрямую. Когда оно меньше минимума или больше максимума, результат ограничивается соответствующей стороной. Это вычисление значения свойства, а не три отдельные медиагруппы с резкими переключениями.
В styles.css найдите три существующих места: пользовательское свойство --lab-gap в base, font-size заголовка и padding-inline карточки в components. Замените только их значения следующими. Остальные свойства этих правил, в том числе высота строки, внутренние ряды и цвета, сохраняются. Не добавляйте второй набор одноимённых объявлений в конце: здесь мы уточняем принятые значения.
.layout-lab { --lab-gap: clamp(.75rem, .5rem + 1vw, 1.5rem); }
.layout-lab .lab-title { font-size: clamp(1.75rem, 1.25rem + 2vw, 3rem); }
.layout-lab .course-card { padding-inline: clamp(1rem, .75rem + 1vw, 1.5rem); }
Промежуток ожидается в пределах от .75rem до 1.5rem, заголовок — от 1.75rem до 3rem, горизонтальный отступ карточки — от 1rem до 1.5rem. Предпочтительная часть каждого выражения сочетает размер относительно корневого шрифта и долю ширины окна. Поэтому увеличение окна влияет на величину, но не отменяет выбранные нижнюю и верхнюю границы.
Эта запись не должна изменить число курсов. Она также не гарантирует, что на каждом экране заголовок будет ровно в одну строку. Количество строк зависит от доступного места, текста и текущего шрифта. Хорошая ограниченная величина помогает выбрать масштаб, а перенос остаётся обычной обязанностью текстовой компоновки.
Разбор одного числового примера
Для мысленного расчёта временно предположим корневой размер шрифта шестнадцать пикселей и ширину окна тысячу пикселей. В предпочтительной части заголовка 1.25rem даст двадцать пикселей, а 2vw — двадцать. Получатся сорок пикселей. Нижняя граница равна двадцати восьми, верхняя — сорока восьми, поэтому в этом условии выбирается предпочтительная величина.
При ширине окна триста двадцать пикселей предпочтительная часть даёт двадцать плюс шесть целых четыре десятых, то есть меньше двадцати восьми. Результат ограничивается нижней границей. При ширине две тысячи пикселей получается шестьдесят, и результат ограничивается сорока восемью. Это расчёт под явно названными предпосылками, а не размеры, измеренные на нашем устройстве.
Если корневой размер другой, часть rem и обе границы пересчитываются. Поэтому нельзя переносить найденные числа как универсальные пиксельные точки перелома. Использование rem связывает масштаб с настройкой шрифта, а часть vw — с шириной viewport. Предпочтительное выражение не становится полностью независимым от окна только потому, что в нём присутствует одно относительное значение.
Внутри математических функций можно писать сумму без внешнего calc, как показано в листинге. У знаков сложения и вычитания сохраняйте пробелы, чтобы запись разбиралась однозначно. Не смешивайте число без единицы с длиной ради случайного сокращения: выражение должно соответствовать типу свойства. Смысл трёх аргументов описан в MDN о clamp.
Гибкий размер и ограничение контейнера
Ширина общей оболочки по-прежнему задана через min. Там задача другая: не выйти за доступное окно и одновременно не стать шире 72rem. Для неё не требуется обязательная нижняя граница. Добавление clamp с большим минимумом могло бы, наоборот, заставить оболочку выходить за маленькое окно. Выбирайте функцию по нужному ограничению, а не по новизне синтаксиса.
Внутренний отступ карточки теперь зависит от viewport, а не от собственной ширины карточки. На большом экране узкий столбец тоже может получить максимальный отступ. Это явное ограничение нашего простого примера. Если компонент размещается в разных областях одного окна, размеры относительно контейнера потребовали бы отдельного решения. Мы сейчас разбираем вычисление диапазона, не обещаем универсальную независимость карточки от окружения.
Перед увеличением промежутка полезно посмотреть минимальную ширину столбца. Внешняя сетка учитывает свободное пространство после своих gaps, поэтому более широкие промежутки могут уменьшить число помещающихся карточек. Это ожидаемая связь двух механизмов, а не ошибка: clamp управляет величиной шага, Grid затем решает размещение с этим шагом. Нельзя рассматривать отступы как свободные от стоимости в макете.
Не задавайте размер всем текстам исключительно в vw. Такой текст может стать слишком мелким на узком окне и не следовать изменению пользовательского масштаба так, как вы ожидаете. Нижние и верхние значения в rem улучшают модель, но сами по себе не доказывают доступность. Для настоящей страницы нужно отдельно смотреть увеличение текста, масштаб браузера и переносы; эти проверки ещё предстоят.
Когда диапазон записан неудобно
Нижняя граница должна отражать допустимый минимальный размер, а верхняя — максимальный. Если записать их наоборот, функция не начнёт угадывать намерение автора: алгоритм имеет определённый порядок вычисления, и конфликт границ разрешается по нему. Для учебного проекта проще заранее выбрать возрастающий диапазон и проверить его смысл словами, а затем переводить в CSS.
Слишком близкие границы тоже могут не дать заметного плавного изменения. Это не ошибка поддержки: предпочтительная часть быстро достигает ограничения. Например, если почти все реальные окна оказываются выше верхней точки, наблюдается постоянный максимальный размер. Не обещайте читателю эффект по одному наличию vw в выражении; сравните предпочтительную часть с границами хотя бы на нескольких условных ширинах.
Для отдельного опыта временно замените предпочтительную часть заголовка на 8vw, сохраняя границы. Ожидается, что максимум будет достигаться гораздо раньше. Затем верните 1.25rem + 2vw. Такой опыт показывает изменение скорости роста, а не изменение самого максимума. Параметры можно разбирать независимо, что полезнее бесконечного подбора всей строки на глаз.
В базовом файле современная функция может быть проигнорирована движком, который её не понимает. Если проект поддерживает такое окружение, нужно предшествующее простое значение или отдельный совместимый файл. Это не повод повторять весь макет под каждым свойством. В завершающем снимке сравним современную запись с осмысленной более простой основой.
Теперь три величины каталога растут в заданных пределах, а их влияние можно объяснить численно. Следующий урок добавит небольшую метку первого курса и разберёт, как её координаты связываются с конкретной карточкой, а не случайно со всей страницей.
Полное состояние этого шага находится в layout-lab/lesson-21 внутри исходников продолжения. Каждый снимок открывается отдельно; подключать CSS разных уроков одновременно не нужно.