Как работает функция minmax()
Одна из невероятно полезных новинок спецификации CSS Grid Layout — функция minmax() . Эта функция открывает нам возможность писать более мощный и лаконичный CSS, позволяя задавать в качестве значения для грид-полосы функцию, включающую и минимальное, и максимальное значения.
Функция minmax()
Функция minmax() принимает два параметра, минимальное значение и максимальное.
minmax(min, max)
Если указанное максимальное значение окажется меньше минимального, оно игнорируется, и функция воспринимается как представляющая только минимальное значение.
Функция minmax() принимает 6 типов значений:
- Единицы длины
- Проценты
- Гибкие размеры
- max-content
- min-content
- auto
Рассмотрим примеры каждого из них.
Длина
Наверное, самое простое значение, что мы можем использовать с функцией minmax() — обычная длина. Возьмем, например, этот простой грид, с тремя колонками и одним рядом.
С помощью функции minmax() мы можем указать, что желтая грид-ячейка остается в пределах от 100px до 200px . При изменении размеров окна абсолютное значение будет меняться, но всегда между этими границами.
.grid
Вторая и третья колонки сжимаются и расширяются до заполнения оставшегося свободного места поровну, но первая всегда остается шириной от 100px до 200px .
Проценты
Помимо обычных единиц длины, с функцией minmax() можно использовать и проценты. Допустим, к примеру, что мы захотели, чтобы желтая грид-ячейка занимала максимум 50% грида, но не ужималась меньше 200px.
.grid
Как бы мы не сужали окно браузера, желтая ячейка никогда не станет меньше 200px. Но когда место есть, она растягивается до максимума в половину ширины грида.
Гибкие размеры
Гибкие размеры — новая единица, тоже введенная спецификацией CSS Grid Layout, как и функция minmax() . Эта величина, для которой используется единица fr , представляет собой долю свободного пространства в грид-контейнере. Например, скажем, у нас есть грид шириной 100px с двумя колонками. У одной колонки фиксированная ширина 20px , а у другой ширина 1fr . У второй колонки фактически будет ширина 80px , поскольку она занимает всё оставшееся свободное место в гриде.
На данный момент единица fr может использоваться только для максимального значения в функции minmax() (хотя в спецификации отмечено, что в будущем может появиться возможность применять ее и для минимального значения). Возвращаясь к нашему примеру, можно указать, что наша желтая ячейка должна быть шириной минимум 200px. Если окно браузера станет шире этого, эта ячейка должна быть размером 1fr , т.е. равна двум другим колонкам.
.grid
Поскольку при больших размерах окна ширина всех колонок 1fr, они делят пространство в гриде поровну.
max-content
Ключевое слово max-content — специальное значение, представляющее собой «идеальный размер» ячейки. Это наименьший возможный размер ячейки, при котором содержимое умещается в ней свободно. Например, если содержимое ячейки — предложение текста, идеальной шириной ячейки будет полная длина этого предложения, если записать его в одну строку без переносов.
Если взять наш предыдущий пример, давайте укажем для желтой грид-ячейки и минимальный, и максимальный размер, равный max-content .
.grid
Как видно, колонка растягивается в ширину, чтобы вместить всю длину строки. Поскольку и максимальному, и минимальному значениям указано max-content , ширина колонки остается постоянной (прим. перев.: того же эффекта можно было бы добиться и без minmax , указав просто grid-template-columns: max-content 1fr 1fr ).
min-content
Ключевое слово min-content , как и max-content — особое значение. Оно представляет собой наименьший возможный размер, при котором в ячейке еще не возникает переполнения, если этого переполнения можно хоть как-то избежать.
Чтобы показать различие между min-content и max-content , можно взять содержимое из предыдущего примера, но в оба значения для функции minmax() подставить min-content .
.grid
Видно, что содержимое ячейки переносится так, чтобы занимать как можно меньше места по горизонтали, не вызывая переполнения.
auto
Наконец, у нас есть auto . В зависимости от того, используется оно как максимальное или минимальное значение в функции minmax() , его смысл меняется.
Если значение auto используется в качестве максимума, оно эквивалентно значению max-content . А если в качестве минимума, то значение auto представляет собой наибольший минимальный размер для ячейки. Этот «наибольший минимальный размер» отличается от значения min-content и задается свойствами min-width/min-height .
В качестве иллюстрации — вот что происходит, если задать желтой грид-ячейке в нашем примере auto для минимума и максимума.
.grid
Использование функции minmax() : отзывчивый дизайн без медиавыражений
Как мы видели, использование функции minmax() подходит в нескольких случаях, и ее можно использовать несколькими способами. Но, наверное, самое популярное и полезное применение функции minmax() — возможность создавать отзывчивые макеты без помощи каких-либо медиавыражений.
Возьмем для примера такой грид:
У каждой колонки в гриде минимальная ширина 200px. При изменении размеров окна браузера число колонок меняется, чтобы вместить их идеальную ширину. С помощью CSS-гридов и функции minmax() это делается всего лишь 2 строчками CSS:
.grid
Помимо функции minmax() , здесь еще два ключевых момента:
- repeat() : эта функция позволяет нам указывать одно и то же значение для нескольких колонок в гриде. Она принимает два значения: количество повторений и значение, которое надо повторить.
- auto-fit : это ключевое слово можно использовать с функцией repeat() вместо количества повторений. Оно гибко меняет используемое число колонок в зависимости от ширины каждой из них.
Правда, одно, на мой взгляд серьезное, ограничение этого приема — то, что это работает только при равной ширине всех колонок. Мы вынуждены пользоваться функцией repeat() с ключевым словом auto-fit , так как это дает возможность сделать число колонок гибким. Но всё же и это может быть крайне полезным решением в подходящих обстоятельствах.
P.S. Это тоже может быть интересно:
- «Запашки» кода React-компонентов
- Убираем сдвиги в верстке наложением в CSS Grid
- Не боритесь с каскадом, управляйте им!
Если вам понравилась статья, поделитесь ей!
Подробности об использовании CSS-функции minmax() в Grid-макетах
Существует множество руководств, в которых рассматриваются общие вопросы работы с CSS Grid, с механизмом, позволяющим создавать сеточные макеты. Я и сам немало об этом писал. Но я обратил внимание на то, что у многих разработчиков возникают сложности с использованием CSS-функции minmax() . Пожалуй, дело тут в том, что большинство существующих публикаций на эту тему либо не вдаются в детали, либо не включают в себя достаточного количества пояснений и примеров из реального мира. А minmax() — это очень мощная и полезная функция. Именно по этой причине я и решил написать данную статью. Это — нечто вроде «полного руководства по minmax() », задача которого — дать читателям то, чего не дают им другие публикации на эту тему.
Здесь мы в подробностях обсудим возможности функции minmax() в применении к сеточным макетам, поговорим о том, как, когда и почему ей стоит пользоваться. Тот, кто проработает эту статью, сможет полноценно и со знанием дела применять эту функцию в своих проектах.
Общие вопросы использования minmax() в Grid-макетах
В спецификации CSS о функции minmax(min, max) сказано, что она определяет диапазон размеров, которые больше или равны min и меньше или равны max .
Эту функцию можно использовать в качестве значения, задающего параметры столбцов или строк Grid-макета. Рассмотрим простой пример:
.o-grid
Вот как это будет выглядеть на схеме.
Результат применения функции minmax() при создании Grid-макета
Проанализируем этот макет:
- Здесь имеется сетка с тремя столбцами.
- Ширина первого столбца задана как minmax(200px, 500px) . Минимальная ширина этого столбца составляет 200px , максимальная — 500px .
- Два других столбца имеют ширину 1fr . Это означает, что они займут оставшееся свободное пространство.
Горизонтальная полоса прокрутки
В результате оказывается, что функция minmax() , сама по себе, не поддерживает создание отзывчивых макетов. А это значит, что поведением страницы приложения на экранах разной ширины нам нужно управлять самостоятельно. Ниже, в разделе практических примеров, мы к этому вернёмся.
Проверка правильности использования функции minmax()
Если значение min , переданное функции minmax(min, max) , больше значения max , то значение max будет проигнорировано. В результате в конструкции minmax(min, max) реально использоваться будет лишь минимальное значение.
Если значение min больше значения max — значение max игнорируется
Кроме того, важно помнить о том, что значение вроде 1fr нельзя использовать в качестве значения min . Оно может быть использовано только в роли значения max . При этом подобная ситуация хуже, чем та, когда min больше, чем max ! Система проигнорирует всю конструкцию, содержащую подобное объявление.
Нельзя использовать 1fr в качестве значения min
Использование нуля в качестве значения min функции minmax()
Что произойдёт в том случае, если попытаться воспользоваться конструкцией вида minmax(0, 500px) ? Пожалуй, вы уже знаете ответ на этот вопрос. Ширина столбца будет, как минимум, нулевой, и при этом она не превысит 500px . То есть — ширина столбца будет меняться в достаточно широких пределах.
Ширина столбца может изменяться в диапазоне от 0 до 500px
Простой сеточный макет
Представим, что нам надо создать сеточный макет, состоящий из 3 колонок. Мы поступим так:
.o-grid
Колонки будут иметь минимальную ширину в 200px . Вот как они будут выглядеть.
Макет, минимальная ширина столбцов которого равна 200px
Избежать троекратного повторения конструкции minmax(200px, 1fr) можно, воспользовавшись функцией repeat() :
.o-grid
Вышеприведённые стили вполне работоспособны, но пользоваться подобными конструкциями не рекомендуется. Поговорим о том, почему это так.
▍Ручное изменение количества столбцов
Если в подобном макете понадобится изменить количество столбцов, то делать это нужно будет вручную, редактируя код. Как по мне, так это не имеет смысла. Технология CSS Grid способна на большее, чем может показаться на первый взгляд.
▍Проблема появления горизонтальной полосы прокрутки
Вышеописанный приём управления количеством столбцов сеточного макета может привести к появлению горизонтальной полосы прокрутки. Дело в том, что мы жёстко задаём количество столбцов. В результате браузер не может их переупорядочить в том случае, если ширина области просмотра окажется слишком маленькой. В результате и появляется горизонтальная полоса прокрутки.
Горизонтальная полоса прокрутки
Как справиться с этой проблемой? Надо сообщить браузеру о том, что количество столбцов должно быть уменьшено в том случае, если ширины области просмотра недостаточно для вывода всего макета.
При разработке Flexbox-макетов это делается путём добавления свойства flex-wrap: wrap к родительскому элементу макета:
.parent
Flexbox-макет, в котором используется свойство flex-wrap: wrap, и макет, в котором это свойство не используется
При проектировании Grid-макетов для достижения подобного эффекта можно воспользоваться ключевыми словами auto-fill и auto-fit .
Сеточный макет, в котором применяются auto-fit/auto-fill, и макет, в котором эти ключевые слова не применяются
Использование ключевых слов auto-fit и auto-fill
Для того чтобы справиться с проблемой жёсткой настройки количества столбцов сеточного макета, мы можем воспользоваться возможностями ключевых слов auto-fit и auto-fill . При этом надо отметить, что между ними существует довольно-таки тонкое различие.
Так, при использовании auto-fit и при наличии свободного места элементы сетки будут растянуты. А применение auto-fill приводит к тому, что элементы растягиваться не будут. В результате дополнительное свободное пространство окажется незанятым, ширина элементов меняться не будет.
Результаты применения ключевых слов auto-fill и auto-fit
При использовании этих ключевых слов может получиться один и тот же результат. Это зависит от ширины области просмотра страницы. Но при определённой ширине области просмотра различия между ними будут уже вполне заметными.
Вот видеозапись, в которой показано поведение макетов, созданных, соответственно, с использованием auto-fill и auto-fit .
Исследование поведения макетов, созданных с использованием ключевых слов auto-fill и auto-fit
▍Распределение свободного пространства между столбцами auto-fit-макета
Вот видео, в котором прямоугольник, обведённый пунктирной линией, представляет свободное пространство. Когда, при использовании ключевого слова auto-fit , ширина области просмотра достаточно велика, браузер «свернёт» это свободное пространство и распределит его ширину между элементами сетки.
Распределение свободного пространства между столбцами auto-fit-макета
▍Распределение свободного пространства между столбцами auto-fill-макета
Если говорить о применении ключевого слова auto-fill , то тут браузер поступает со свободным пространством иначе. А именно, при увеличении ширины области просмотра ширина элементов не увеличивается. При этом размер свободного пространства (оно, в этом видео, выделено пунктиром) растёт.
Распределение свободного пространства между столбцами auto-fill-макета
Сценарии использования и практические примеры
▍Карточки, основанные на сеточном макете
Полагаю, что функцию minmax() чаще всего используют для оформления карточек, применяя её при создании элемента-контейнера.
.wrapper
Когда я начал изучать технологию Grid, я неуютно чувствовал себя, глядя на свойство grid-template-columns , использованное в этом примере. Тут важно обратить внимание на то, как поведёт себя страница в областях просмотра, ширина которых меньше 250px . Дело в том, что в таких ситуациях на экране появится горизонтальная полоса прокрутки.
Появление горизонтальной полосы прокрутки в области просмотра, ширина которой меньше 250px
Решить эту проблему можно двумя способами. Первый заключается в использовании медиа-запросов. В основе этого способа лежит идея, в соответствии с которой grid-template-columns устанавливается в 1fr . А когда ширина области просмотра достаточно велика — применяется minmax() :
.wrapper < display: grid; grid-template-columns: 1fr; grid-gap: 1rem; >@media (min-width: 300px) < .wrapper < grid-template-columns: repeat(auto-fill, minmax(250px, 1fr)); >>
Второй подход к решению этой проблемы заключается в использовании CSS-функций сравнения. Это — современное решение. Поэтому перед его использованием нужно убедиться в том, что оно поддерживается браузером.
.wrapper
Я использовал тут, в качестве первого значения функции minmax() , функцию сравнения min() . Вот что здесь происходит:
- Если ширина области просмотра меньше, чем 250px , первым значением, передаваемым minmax() , будет 100% ширины родительского элемента.
- Если ширина области просмотра будет больше, чем 250px , тогда первым значением minmax() будет 250px .
▍Использование единицы измерения ch при настройке элемента-контейнера
Мне кажется интересным пример использования функции minmax() при создании макета, предназначенного для отображения материалов статей. В данном примере содержимое статьи центровано по горизонтали.
.wrapper
Первый и последний столбцы играют вспомогательную роль, управляя свободным пространством. Нас тут интересует центральный столбец. Обратите внимание на то, что при его настройке использована конструкция вида minmax(auto, 70ch) . Это означает, что максимальной шириной данного столбца является ширина, которую занимают 70 символов, выстроенных в одну строку. Это — идеальное количество символов на строку, обеспечивающее комфортное чтение текста.
Макет, предназначенный для вывода текста статьи
Этот макет будет хорошо смотреться на экранах разных размеров, в том числе — на мобильных устройствах. Дело в том, что ширина первой и последней колонок может уменьшаться вплоть до минимального значения, соответствующего 1rem . Вот как эта страница будет выглядеть на узком экране мобильного устройства.
Статья на экране мобильного устройства
▍Проблема, возникающая при необдуманном использовании ключевого слова auto-fit
У того, кто впервые узнал о ключевом слове auto-fit , может возникнуть желание использовать его повсюду. Но тут есть одна проблема, которая проявляется тогда, когда содержимое сетки (например — количество карточек) меняется, а разработчик не контролирует это содержимое.
.wrapper
Тут описана сетка, используемая для вывода карточек. Когда имеется 4 карточки — макет выглядит замечательно. Но если карточка всего одна — она растянется на всё свободное пространство.
Проблема необдуманного использования auto-fit
Это никуда не годится. Дело в том, что если у компонента-карточки имеется некое изображение и текст, то изображение будет растянуто так, чтобы оно заняло бы всю ширину карточки. В результате выглядеть такое изображение будет очень плохо. Вот изображение, иллюстрирующее эту проблему.
Вывод карточки с изображением
Полагаю, теперь суть этой проблемы совершенно очевидна. Поэтому предлагаю пользоваться ключевым словом auto-fit ответственно. В описанной ситуации им вполне можно воспользоваться тогда, когда в карточках нет изображений. Если же в карточках имеются изображения — пользоваться auto-fit я не рекомендую.
Пользуетесь ли вы CSS-функцией minmax() в Grid-макетах?
minmax()
Baseline is determined by this web feature being supported on the current and the previous major versions of major browsers.
minmax() это CSS функция, определяющая диапазон размеров, который больше или равен min и меньше или равен max. Используется в CSS Grids.
/* , values */ minmax(200px, 1fr) minmax(400px, 50%) minmax(30%, 300px) minmax(100px, max-content) minmax(min-content, 400px) minmax(max-content, auto) minmax(auto, 300px) minmax(min-content, auto) /* , values */ minmax(200px, 1fr) minmax(30%, 300px) minmax(400px, 50%) minmax(50%, min-content) minmax(300px, max-content) minmax(200px, auto) /* , values */ minmax(400px, 50%) minmax(30%, 300px) minmax(min-content, 200px) minmax(max-content, 200px) minmax(auto, 300px)
Синтаксис
Функция принимает два параметра, min и max.
Каждый параметр может быть значением , либо , либо , или одним из ключевых слов max-content , min-content , или auto .
Значения
A non-negative length.
A non-negative percentage relative to the inline size of the grid container in column grid tracks, and the block size of the grid container in row grid tracks. If the size of the grid container depends on the size of its tracks, then the must be treated as auto . The user agent may adjust the intrinsic size contributions of the track to the size of the grid container and increase the final size of the track by the minimum amount that would result in honoring the percentage.
A non-negative dimension with the unit fr specifying the track’s flex factor. Each -sized track takes a share of the remaining space in proportion to its flex factor.
Represents the largest max-content contribution of the grid items occupying the grid track.
Represents the largest min-content contribution of the grid items occupying the grid track.
As a maximum, identical to max-content . As a minimum it represents the largest minimum size (as specified by min-width / min-height ) of the grid items occupying the grid track.
Формальный синтаксис
Error: could not find syntax for this item
Пример
CSS
#container display: grid; grid-template-columns: minmax(max-content, 300px) minmax(200px, 1fr) 150px; grid-gap: 5px; box-sizing: border-box; height: 200px; width: 100%; background-color: #8cffa0; padding: 10px; > #container > div background-color: #8ca0ff; padding: 5px; >
HTML
div id="container"> div> Item as wide as the content,br /> but at most 300 pixels. div> div>Item with flexible width but a minimum of 200 pixels.div> div>Inflexible item of 150 pixels width.div> div>
Результат
Спецификации
Specification |
---|
CSS Grid Layout Module Level 2 # valdef-grid-template-columns-minmax |
Browser compatibility
BCD tables only load in the browser
Смотрите также
- Grid Layout Guide: Basic concepts of grid layout — track sizing with minmax()
- Video tutorial: Introducing minmax()
Found a content problem with this page?
- Edit the page on GitHub.
- Report the content issue.
- View the source on GitHub.
This page was last modified on 7 авг. 2023 г. by MDN contributors.
Your blueprint for a better internet.
MDN
Support
- Product help
- Report an issue
Our communities
Developers
- Web Technologies
- Learn Web Development
- MDN Plus
- Hacks Blog
- Website Privacy Notice
- Cookies
- Legal
- Community Participation Guidelines
Visit Mozilla Corporation’s not-for-profit parent, the Mozilla Foundation.
Portions of this content are ©1998– 2023 by individual mozilla.org contributors. Content available under a Creative Commons license.
CSS-функции min(), max() и clamp()
Поддержка CSS-функций сравнения min() , max() и clamp() появилась в Firefox 8 апреля 2020 года. Это означает, что данные функции теперь поддерживаются во всех основных браузерах. Эти CSS-функции расширяют наши возможности по созданию динамических макетов и по проектированию более гибких, чем раньше, компонентов. Их можно использовать для настройки размеров элементов-контейнеров, шрифтов, отступов и многого другого. Правда, веб-дизайнеру, создающему макеты страниц с учётом возможности использования этих восхитительных функций, может понадобиться научиться думать по-новому.
Сегодня я хочу рассказать об особенностях этих функций, объяснить всё то, что может оказаться в них непонятным, и привести практические примеры их использования.
Браузерная поддержка
Сначала мне хотелось бы коснуться браузерной поддержки функций min() , max() и clamp() . Всё же, появились они сравнительно недавно. Надо отметить, что функции min() и max() пользуются одинаковым уровнем поддержки браузеров.
Поддержка функции min() (так же выглядят и сведения о поддержке max())
Ниже представлены сведения о поддержке функции clamp() .
Поддержка функции clamp()
CSS-функции сравнения
Спецификация CSS говорит нам о том, что функции сравнения min() , max() и clamp() позволяют сравнивать значения выражений и представлять одно из них. Значение, возвращаемое той или иной функцией, зависит от её особенностей. Исследуем эти функции.
Функция min()
Функция min() принимает одно или большее количество значений, разделённых запятой, и возвращает наименьшее из них. Эту функцию используют для ограничения значений CSS-свойств жёстко заданным максимальным уровнем.
Рассмотрим следующий пример. Нам нужно, чтобы максимальная ширина элемента не превышала бы 500px .
.element
При ширине области просмотра 1150px, что больше 1000px, элемент будет иметь ширину 500px
Браузеру нужно будет выбрать наименьшее значение из 50% и 500px . На результат выбора влияет ширина области просмотра. Если 50% ширины области просмотра составит более чем 500px , тогда это значение будет проигнорировано и функция возвратит 500px .
В противном случае, если 50% ширины области просмотра составляют менее 500px , для настройки ширины элемента будет использовано полученное значение. Как вы думаете, при какой ширине области просмотра 50% её ширины не превысят 500px ? Это, очевидно, 1000px . При такой ширине оба значения, переданные функции, будут одинаковыми. Если ширина области просмотра будет менее 1000px , то для настройки ширины элемента будет использована именно она.
Если ширина области просмотра менее 1000px, то для настройки ширины элемента будет использовано 50% от этой ширины
Я надеюсь, что мне удалось понятно всё это объяснить. Я долго размышлял о функции min() , стремясь проникнуть в её сущность. Поэтому мне очень хотелось бы доходчиво о ней рассказать. Вот видео, демонстрирующее результаты применения этой функции.
Ширина элемента ограничена значением в 500px
Вот интерактивный пример, использованный при записи вышеупомянутого видео. Для того чтобы увидеть функцию min() в действии — попробуйте изменить размеры окна браузера.
Функция max()
Функция max() принимает одно или несколько значений, разделённых запятыми, и возвращает наибольшее из них. Эту функцию используют для того, чтобы зафиксировать минимальное значение, которое может принимать CSS-свойство.
В следующем примере нам нужно, чтобы ширина элемента составляла бы как минимум 500px .
.element
Если 50% ширины области просмотра больше 500px — для настройки ширины элемента будет использовано именно это значение
Браузеру нужно выбрать максимальное значение из 50% и 500px . Выбор зависит от ширины области просмотра. Если 50% ширины области просмотра — это меньше, чем 500px , браузер это значение проигнорирует и использует значение 500px .
Если же 50% ширины области просмотра больше 500px , тогда ширина элемента будет установлена равной этому значению. Как видите, функция max() является противоположностью функции min() .
Для того чтобы лучше в этом разобраться — взгляните на эту интерактивную демонстрацию.
Функция clamp()
Функция clamp() позволяет ограничивать диапазон изменения некоего значения, задавая его нижний и верхний пределы. Она принимает три параметра: минимальное значение, вычисляемое (рекомендованное) значение, максимальное значение. Если вычисляемое значение не выходит за пределы, ограничиваемые минимальным и максимальным значениями, переданными функции, то она возвратит именно это значение.
.element
Здесь мы настраиваем ширину элемента, которая не должна быть меньше 200px и больше 1000px . Если значение в 50% не выходит за эти пределы — используется именно это значение. Вот как это выглядит.
Если 50% ширины области просмотра попадают в диапазон 200px-1000px — для задания ширины элемента будет использоваться именно это значение. В данном случае это 575px
Разберём этот пример:
- Ширина элемента никогда не будет меньше 200px .
- Второй параметр функции, заданный как 50% , будет использоваться только в том случае, если ширина области просмотра будет больше 400px и меньше 2000px .
- Ширина элемента не превысит 1000px .
Здесь можно поэкспериментировать со страницей, при стилизации которой используется эта функция.
▍Как вычисляются результаты функции clamp()?
На MDN можно найти сведения о том, что, когда в качестве значения CSS-свойства используется функция clamp() , она является эквивалентом конструкции, в которой применяются функции max() и min() . Взгляните на следующий пример:
.element < width: clamp(200px, 50%, 1000px); /* Это - эквивалент следующего выражения */ width: max(200px, min(50%, 1000px)); >
Значение 50% зависит от ширины области просмотра браузера. Представим, что ширина области просмотра составляет 1150px .
.element < width: max(200px, min(50%, 1000px)); /* Представим, что ширина области просмотра составляет 1150px */ width: max(200px, min(575px, 1000px)); /* Промежуточный результат */ width: max(200px, 575px); /* Итоговый результат */ width: 575px; >
▍Контекст имеет значение
Вычисленное значение зависит от контекста. При указании вычисляемого значения можно использовать различные единицы измерения: % , em , rem , vw/vh . Даже если значение выражено в процентах, при его расчёте может использоваться либо ширина области просмотра — в том случае, если элемент находится в теге , либо ширина другого элемента, являющегося контейнером элемента.
▍Математические выражения
Стоит сказать о том, что при использовании функции clamp() можно передавать ей математические выражения, что избавляет нас от необходимости использования функции calc() . Спецификация говорит нам о том, что в каждом из аргументов clamp() можно использовать полные математические выражения. Поэтому здесь нет нужды во вложенных функциях calc() . Кроме того, если к итоговому значению нужно применить несколько ограничений, функции можно передавать более двух аргументов.
Взгляните на следующий пример:
.type < /* Ограничиваем font-size значениями, находящимися между 12px и 100px */ font-size: clamp(12px, 10 * (1vw + 1vh) / 2, 100px); >
Что CSS-функции сравнения изменят в том, как мы проектируем макеты страниц?
Часто бывает так, что дизайнер, проектируя страницу, ориентируется и на мобильные, и на настольные устройства, рассчитывая на два сценария её использования. А при работе над некоторыми проектами приходится принимать во внимание и большее количество сценариев.
Я вижу эту ситуацию так, как показано ниже.
Наверху — то, как проектируют страницы сегодня. Внизу — то, чего можно ожидать в будущем
Верхняя часть иллюстрации представляет собой то, как страницы проектируют в наши дни. Тут можно видеть несколько шагов, представляющих разные области просмотра, на вывод в которых должна быть рассчитана страница. Эти шаги могут, например, представлять собой значение некоего свойства. На нижней части иллюстрации представлен непрерывный диапазон значений, который можно получить, ограничивая это значение неким минимумом и максимумом. Полагаю, что в будущем, например, при настройке размера шрифта, дизайнеры будут поступать примерно так, как показано ниже.
Минимальное, рекомендованное и максимальное значения свойства
Как по мне, так это просто замечательно. Меня восхищает идея работы над проектами, компонентам которых нужна определённая гибкость. Конечно, не всем компонентам нужно быть динамическими, но некоторые из них вполне могут такими быть.
Сценарии использования
▍Боковая панель и основная область страницы
Слева — боковая панель. Справа — основная область страницы
Обычно боковые панели страниц имеют фиксированную ширину, а ширина основных областей гибко подстраивается под область просмотра. Мы можем расширить возможности боковой панели и сделать её более динамичной, сделать так, чтобы она, при достаточно большой области просмотра, занимала бы больше места. Для того чтобы этого достичь, нужно ограничить размер минимальной ширины боковой панели с использованием функции max() .
Рассмотрим следующий пример.
.wrapper < display: flex; >aside < flex-basis: max(30vw, 150px); >main
Минимальной шириной элемента aside будет 150px . Он примет размер 30vw в том случае, если ширина области просмотра больше 500px (500 * 30% = 150).
▍Размер шрифта заголовка
Гибкая настройка размера шрифта заголовка
Отличным сценарием использования функции clamp() является гибкая настройка размера шрифта заголовков. Представим, что нам нужно, чтобы минимальным размером шрифта заголовка было бы 16px , а максимальным — 50px . Благодаря использованию функции clamp() мы можем сделать так, чтобы размер шрифта находился бы в пределах этих значений, не уходя ни ниже, ни выше.
.title
Функция clamp() — это идеальное решение вышеописанной задачи. Она позволяет обеспечить задание такого размера шрифта, благодаря которому текст остаётся доступным и удобным для чтения при разных размерах области просмотра. Если тут, например, воспользоваться функцией min() , тогда мы потеряем контроль над размером шрифта на странице, выводимой в маленьких областях просмотра.
.title < font-size: min(3vw, 24px); /* Не рекомендуется, так как ухудшает доступность */ >
Ниже показана иллюстрация этой идеи.
Использование функции min() приводит к тому, что на маленьком экране текст окажется слишком мелким
На экране мобильного устройства размер шрифта оказывается слишком маленьким. Поэтому не рекомендуется использовать для настройки размеров шрифтов лишь функцию min() . Конечно, размер шрифта можно перенастроить с использованием медиазапроса, но тогда совершенно теряется смысл применения CSS-функций сравнения.
Как уже было сказано, функцию min() можно использовать внутри функции max() . Это позволяет воспроизвести возможности функции clamp() .
.title
Здесь можно поэкспериментировать с примером.
Хочу отметить, что после дискуссии в Твиттере оказалось, что не вполне правильно использовать 10vw в качестве вычисляемого значения для размера шрифта. А именно, речь идёт о том, что это вызовет проблемы с доступностью в том случае, если пользователь изменит масштаб страницы в браузере.
Поэтому лучше поступить так:
.title
Здесь в качестве вычисляемого размера шрифта указано выражение (1rem + 5vw) . Это решает проблему.
▍Декоративные заголовки
Декоративный полупрозрачный заголовок, выведенный с использованием шрифта очень большого размера
Видите большой полупрозрачный текст, расположенный под основным текстом заголовка? Это — декоративный заголовок, размеры которого должны согласовываться с размерами области просмотра. Для формирования такого заголовка можно воспользоваться функцией max() с передачей ей значения, выраженного в единицах измерения vw . Это позволит сделать так, чтобы размер шрифта не был бы меньше заданного значения.
.section-title:before
▍Вывод плавных градиентов в разных областях просмотра
При настройке градиентов средствами CSS может понадобиться их динамическая настройка, направленная на то, чтобы сделать градиенты, выводимые на экранах мобильных устройств, более плавными. Взгляните на следующий пример. Здесь имеется такой градиент:
.element
Градиент на мобильном экране характеризуется слишком резким переходом между цветами
Обратите внимание на то, что на мобильном экране чётко видна граница разделения цветов. Это плохо. Исправить ситуацию можно с помощью старого доброго медиазапроса. (Опа, похоже, я уже считаю медиазапросы «старой доброй технологией»).
@media (max-width: 700px) < .element < background: linear-gradient(135deg, #2c3e50, #2c3e50 25%, #3498db) >>
Хотя это — нормальный способ решения проблемы, в подобной ситуации мы можем использовать CSS-функцию min() .
.element
В результате получится то, что показано ниже.
Градиент выглядит плавным при его просмотре на любом экране
→ Вот демонстрация этой идеи
▍Полупрозрачный градиент
Когда нужно разместить текст поверх фотографии, то под него следует «подложить» градиент. Это позволит облегчить чтение текста. Так же, как и в предыдущем примере, параметры градиента должны зависеть от размеров области просмотра. Взгляните на следующий рисунок.
Гибкая настройка градиента на экранах разных размеров
.element
Благодаря этому небольшому улучшению градиент на мобильных устройствах будет выглядеть гораздо лучше, чем прежде. Если размер градиента равняется, на настольном экране, 50 % родительского элемента, то на мобильном устройстве это уже должно быть что-то в районе 30 %. Задать минимальное значение размера градиента можно с помощью функции max() .
▍Динамические внешние отступы
Настройка внешних отступов
Для настройки динамических внешних отступов элементов можно использовать единицы измерения, связанные с характеристиками области просмотра. Однако такой подход не всегда показывает себя хорошо. Дело в том, что пользователь может просматривать страницу на повёрнутом экране мобильного устройства с очень большой вертикальной высотой. Вот как решить эту проблему с использованием медиазапросов:
h1, h2, h3, h4, h5 < margin: 7vh 0 1.05rem; >@media (max-height: 2000px) < h1, h2, h3, h4, h5 < margin: 2.75rem 0 1.05rem; >>
Хотя этот код работает правильно, того же самого эффекта можно добиться с помощью всего одной строчки кода:
h1, h2, h3, h4, h5
Благодаря использованию функции min() мы задаём максимальное значение отступа в 2.75rem . Как видите, это очень просто и удобно.
▍Ширина контейнера
Динамическая настройка ширины контейнера
Предположим, нам нужен элемент-контейнер, ширина которого должна составлять 80% от ширины его родительского элемента. При этом ширина контейнера не должна превышать 780px . Как создать подобный контейнер? Обычно в такой ситуации поступают примерно так:
.container
Но использование функции min() позволяет ограничить максимальную ширину контейнера так:
.container
▍Вертикальный внутренний отступ
Функция clamp() нравится мне тем, что она идеально подходит для ограничения размеров внутренних отступов разделов страниц. Взгляните на следующий пример, в котором показана настройка верхней части страницы (hero-раздела).
Настройка внутренних отступов раздела, расположенного в верхней части страницы
Гибко настроить отступы подобного раздела можно, воспользовавшись всего одной строкой CSS-кода.
.hero
▍Границы и тени
Вот видео, в котором показан элемент, имеющий широкую границу.
Элемент с широкой границей
В некоторых случаях в дизайне страниц используются элементы с широкими границами и с большими радиусами скругления углов. При выводе подобных элементов на мобильных экранах их границы нужно сделать меньше. То же самое касается и радиусов скругления углов. Использование функции clamp() позволяет динамически настраивать параметры границ, привязывая их к ширине области просмотра.
.element
Здесь можно поэкспериментировать с рабочим примером.
▍Расстояние между ячейками Grid-макета
Интересный вариант использования функции clamp() заключается в настройке свойства grid-gap в Grid-макетах. В частности, речь идёт о том, чтобы на мобильных экранах расстояние между ячейками сетки было бы меньше, чем на настольных.
.wrapper
Если вас интересуют вопросы использования CSS-функций сравнения при проектировании Grid-макетов, взгляните на эту хорошую статью.
→ Вот пример к этому разделу
▍Использование в CSS-функциях сравнения значений без единиц измерения
Я, в ходе экспериментов с CSS-функциями, решил узнать о том, что получится, если передать функции clamp() в качестве минимального значения 0 . Вот как это выглядит в коде:
.element
Это — неправильно оформленный CSS-код. Полагаю, дело в том, что числа без единиц измерения использовать тут не следует.
▍Резервные механизмы для браузеров, не поддерживающих min(), max() и clamp()
Как и в случае с любыми другими новыми возможностями CSS, применяя функции min() , max() и clamp() , нужно позаботиться о резервных механизмах. Для создания этих механизмов можно воспользоваться одним из следующих подходов.
1. Ручная настройка резервного механизма
Здесь под ручной настройкой понимается добавление в код свойства, пользующегося широкой поддержкой браузеров. Это свойство должно быть расположено перед свойством, в котором используются CSS-функции сравнения. Вот как это может выглядеть:
.hero
Здесь браузеры, поддерживающие clamp() , проигнорируют первое выражение. А те, которые эту функцию не поддерживают, воспользуются первым способом настройки отступа.
2. Использование CSS-директивы supports
Директиву @supports , предназначенную для проверки поддержки браузерами различных технологий, можно использовать для выяснения того, умеет ли браузер работать с CSS-функциями сравнения. Я предпочитаю пользоваться этим решением, а не тем, ручным, которое описано в первом пункте. Дело в том, что любой браузер, поддерживающий функции сравнения, должен поддерживать и директиву @supports .
.hero < /* Используется по умолчанию в браузерах, не поддерживающих min() */ padding: 4rem 1rem; >@supports (width: min(10px, 5vw)) < /* Улучшение для браузеров, которые поддерживают min() */ .hero < padding: clamp(2rem, 10vmax, 10rem) 1rem; >>
▍О доступности контента
В то время как CSS-функции сравнения дают нам новый способ создания более гибких веб-страниц, используя их, нужно проявлять осторожность. Например, применение одной лишь функции min() для настройки свойства font-size недостаточно. Дело в том, что на мобильных устройствах шрифт, размер которого задан с использованием только этой функции, может оказаться слишком маленьким. При настройке особенно важного содержимого страниц нужно помнить об ограничении минимальных и максимальных значений параметров. Иначе это может ухудшить впечатления пользователей от работы с проектом.
А пользуетесь ли вы CSS-функциями min() , max() и clamp() ?
- Блог компании RUVDS.com
- Веб-разработка
- CSS