От автора: функциональные обозначения являются частью CSS Values and Units Module спецификации, где также описаны полезные математические функции типа calc(), а в рамках level 4 функции min() и max(). Эти мощные функции открывают верстальщикам возможности, связанные с логикой в CSS. В этой статье мы обсудим CSS Math Functions calc(), min() и max(), а также как эти три функции можно использовать в работе. Поехали!
Что же такое функциональные обозначения?
Functional Notations – один из девяти главных разделов (раздел №9, если быть точным) спецификации W3C CSS Values and Units Module. Начиная с Level 4 Editor’s Draft, в функциональных обозначениях появились подразделы. toggle(), позволяющий переключаться между значениями, а также атрибутные ссылки через attr(). Есть еще один интересный подраздел «Математические выражения», в котором описаны наши друзья calc(), min() и max().
Обратимся к определению W3C, чтобы понять, что такое функциональные обозначения:
«Функциональное обозначение – тип значения компонента, который может представлять более сложные типы или выполнять определенные обработки. Синтаксис начинается с названия функции, после чего сразу следует левая круглая скобка. Далее идет аргумент(ы) и закрывающая круглая скобка.»
Для незнающих это «название функции» типа calc, далее ( и закрывающая ). Но что внутри скобок?
Математические выражения
Как было сказано, «математические выражения» — это подраздел функциональных обозначений, но что это, и что они делают? Опять обратимся к W3C, там сказано:
«Математические функции calc(), min() и max() позволяют выполнять математические выражения по сложению (+), вычитанию (-), умножению (*) и делению (/)в значениях компонента.»
То есть calc(), min() и max() – это «математические функции», позволяющие использовать «выражения» внутри круглых скобок для «вычисления значений». Ну, теперь понятно. Термин «выражения» лишь простой способ сказать «внутри круглых скобок разрешена математическая логика».
В Level 4 было представлено новое определение, дополняющее то, что мы уже знаем:
«Компоненты математической функции могут представлять буквальные значения, другие математические функции или другие выражения типа attr(), которые вычисляют значение по допустимому типу аргумента (например, length).»
Что понимается под «другими математическими функциями» — calc(), min() и max(), но они также заявляют, что эти функции можно вкладывать друг в друга. Можно писать calc(min()), min(calc()), calc(max(min())), calc(min(attr())) и т.д. Однако я настоятельно советую максимально избегать вложенности, несмотря на то, что спецификация предлагает такую возможность.
А теперь скажем «привет» еще раз парочке невероятных математических функций, которые почти потеряли шанс пожать руку CSS Working Group.
С возвращением min() и max()
Функции min() и max() – две математические функции, оставившие свой след в CSS после почти полного удаления из Values and Units Level 4 Editor’s Draft. Благодаря Lea Verou, подул ветер перемен, который заставил их вернуться, и я действительно рад этому.
«Values 3 ушла на CR, возможно, пора вернуть min() и max() в Values 4?
Верстальщики придумывают крайне странные хаки с calc(), эмулируя эти функции в font-size и line-height, и называют их «CSS locks». Если загуглить CSS locks, вы увидите, насколько распространены эти хаки, что говорит о явной необходимости этих функций.
Также по мере роста популярности CSS переменных необходимость в min() и max() растет еще стремительнее. Помню, как проблемы, заставившие нас выкинуть их 6 лет назад, теперь можно решить с помощью невалидного в концепции расчетного значения времени, которое появилось в Variables.» – Lea Verou
После предложения Lea на GitHub функции min() и max() были официально возвращены в редакторский черновик CSS level 4 Values and Units, включая последние наработки Webkit. Разработчики могут лично экспериментировать и исследовать их в WebKit Nightly (на 24.10.2017). Вот этот WebKit комит, где магическим образом была добавлена поддержка min() и max().
Быстрый обзор clamp()
В ветке Lea Verou на GitHub появился комментарий, где Tab Atkins предлагает функцию clamp() – еще один интригующий слух. Clamp() буквально должна «зажимать» значение в рамках значений.
«…действительно соглашусь, что clamp(), хотя технически и будет излишней, зачастую очень полезна, поэтому, возможно, заслуживает существования.»
Боже мой! Она бы добавилась в математические выражения. Функция типа clamp() – определенно победа для адаптивности сегодняшнего дня, она станет хорошим другом языка.
1 |
clamp(minN, midN, maxN) |
Текущие обсуждения остановились на этом синтаксисе, и я один из тех, кто с ним согласен. Он понятен и логически читаем. Представляю, что будет с min() и max(), если clamp() увидит свет в будущем.
Хватит болтовни, давайте поговорим о реальных математических функциях calc(), min() и max().
Знакомьтесь, calc()
Одна из моих любимых математических функций в CSS. С ее помощью можно колдовать все что угодно. Синтаксис не слишком грубый, как только вы поймете его. А также у функции звездная поддержка.
1 2 3 |
.my-element { width: calc(50% - 10rem); } |
В примере выше идет название функции (calc), следом скобки с «выражениями» или… математической логикой.
«Функция calc() разрешает математические выражения сложения (+), вычитания (-), умножения (*) и деления (/) в значениях компонента.» — W3C
Причудливый вариант фразы «в круглых скобках можно использовать вычисления».
Что касается выражений, то верстальщики могут передавать общие значения типа 50%, 2em, 40 и calc(). Разрешенные типы значений length, frequency, angle, time, percentage, number и integer. Я обожаю использовать и тестировать в реальных проектах единицы вьюпорта (vh,vw, vmin, vmax). Единицы вьюпорта представляют собой значения разрешения экрана и особенно полезны в шрифтах, что мы скоро увидим.
calc() в реальных примерах
Пример выше – один из примеров работы с адаптивной типографикой. Сочетая медиа запросы, Sass, calc() и вьюпорт единицы, Mike доказывает нам, насколько идеально адаптивная типографика может масштабироваться в определенных пиксельных значениях.
Еще одно демо со шрифтами, calc() и вьюпорт единицами от Tim Brown, от которого у вас упадет челюсть. Это демо он использовал в своей статье «обсуждение CSS locks». Советую почитать, если интересуетесь шрифтами.
С помощью вьюпорт единиц и calc() можно создать один из любимейших шаблонов. В демо выше с помощью calc() высота футера вычитается из высоты вьюпорта (vh). Умное решение от Chris Coyier для нашего друга «The Sticky Footer». Демо также отлично работает в паре с CSS переменными.
Конечно, есть и другие случаи. Например, в приложениях и динамических состояниях, как в демо David Khourshid. David использует calc() для фона, значений сдвига, трансформаций, фильтров, прозрачности и даже ширины. Отличное демо для тех, кто хочет изучить React вместе с CSS переменными.
Теперь разберем две другие математические функции, которые вам обязательно понравятся. Это min() и max().
min() и max(): определение ограничений
Как ранее говорилось, эти функции все еще зарождаются, поэтому демо с ними не отличаются красотой. Но пусть это не останавливает вас от экспериментов. Для работы с min() и max() необходимо загрузить WebKit nightly. После загрузки запускайте Nightly (черная иконка) и приступайте к работе.
1 2 |
min(expression, [expression]) max(expression, [expression]) |
Помните определение выражений? Это был лишь причудливый способ сказать «математическая логика». Например:
1 2 |
min(1 * 10vw, 2 / 50vw) max(1 * 10vw, 2 / 50vw) |
Выражения разделяются запятой, после чего идет следующее выражение. Можно обратиться к спецификации, где ясно говорится:
«Вычисленное значение функции min() или max() представляет собой список выражений, разделенных запятой» — W3C
Если вы пропустили эту очень важную часть объяснения, то в спецификации сказано «список выражений, разделенных запятой», прямо как в коде выше.
«Функции min() и max() представляют наименьшее (наименьшее отрицательное) и наибольшее (наибольшее положительное) вычисление, разделенное запятой.» — W3C
Поняли? Тут сказано «наименьшее (наименьшее отрицательное) и наибольшее (наибольшее отрицательное)». W3C дали разрешение писать отрицательные числа в наших выражениях.
Теперь посмотрим, как min() и max() покажет себя а рабочем демо. Держите шляпы.
min() и max() в реальной жизни
Ниже показано демо, показывающее несколько случаев использования min() и max() в компонентах width и font-size. У width есть минимальное и максимальное ограничения, font-size также зажат в минимальных и максимальных значениях. Не забывайте, что демо будет работать только в WebKit Nightly на момент написания статьи. Хотите посмотреть в действии, можно посмотреть GIF (слишком большая для вставки на страницу).
В демо выше я начинаю с того, что ограничиваю width в одной строке.
1 |
width: min(max(100px * 2, 70vw), 500px); |
С помощью способа выше я могу подключить среднее ограничение. Эта строка кода говорит браузеру «попробуй задать ширину в 70vw, но не давай есть стать меньше 200px (100px * 2) или больше 500px». Достичь такого же результата можно и другим способом.
1 |
min(max(minN, midN), maxN) |
Чтобы более подробно объяснить, это выражение приравнивается к минимуму, середине и максимальному ограничению. Вложение max() в min() помогает зажать значения в необходимые ограничения.
1 2 |
min-width: 200px max-width: 500px |
С помощью min-width и max-width мы можем достичь того же эффекта, как с min() и max(). Интересно, устареют ли свойства типа min-width в угоду математическим функциям типа main() и max().
С font-size я точно так же использую min/max для создания адаптивного шрифта.
1 |
font-size: min(max(1rem, 4vw), 2rem); |
Я говорю браузеру «попробуй задать размер шрифта 4vw, но не позволяй ему быть меньше 1rem и больше 2rem». К сожалению, здесь нет эквивалентов типа min-font-size и max-font-size, как для ширины. Однако в CSS Fonts Module Level 4 они могут быть добавлены.
Это потрясающая новость, а когда дело касается ограничивающих значений в CSS, верстальщики тоже в восхищении.
Просто наберите в поиске «CSS locks»
Если набрать в поисковике CSS Locks, найдется куча статей и демо. По тегу CSS Locks на CodePen также можно найти множество демо. Кто не знает, что такое CSS locks, позвольте объяснить.
Техника замыкания позволяет плавно переходить между двумя значениями в зависимости от текущего размера вьюпорта. Tim Brown назвал этот метод CSS locks в свой статье «гибкая типографика на CSS locks». Однако впервые эта техника была представлена Mike Riethmuller в своей статье «точный контроль адаптивной типографики».
Их можно использовать в паре с calc() и вьюпорт единицами в заголовках и основном тексте для масштабирования в зависимости от размеров экрана. Такой тип ограничений называется CSS locks.
Замыкание на EQCSS
В демо выше от Tommy Hodgins с помощью EQCSS ограничивается font-size с помощью JS. CSS отдыхает. Насколько плохо перемешивать JS с CSS решайте сами.
Замыкание на CSS переменных и JS
Я написал JS хелпер, которой с помощью CSS «замыкает» размер шрифта заголовков, основного текста и высоту строк при изменении размеров экрана и событиях на странице без подключения медиа запросов.
Эти свойства нацелены «блокировать» при определенных значениях, однако везде есть свои подводные камни. В программировании у каждого подхода есть свои плюсы и минусы. Из-за событий и переключаемых CSS свойств вы, скорее всего, столкнетесь с перерисовкой и сборкой макета при изменении размера экрана. Поэтому используйте этот подход экономно или по-другому «не используйте его везде на странице».
Парочка мудростей при стилизации через JS.
Если вы используете JS для применения стилей, это всегда будет медленнее CSS. Все что можно делать в CSS, делайте в CSS.
При использовании JS для применения стилей производительность зависит от сложности выполняемых операций и количества элементов на странице, над которыми выполняются операции. Постарайтесь писать стили так, чтобы ограничить количество JS-вставок, чтобы определить, какие стили применять и попробовать ограничить количество элементов в HTML, которые будут обрабатываться через JS.
Поймите, какие события вызывают перерасчет стилей. Вы хотите, чтобы стили не менялись в зависимости от действий браузера, но вы также хотите ограничить количество запущенных обработчиков событий за раз. Вот тут очень важно ограничить количество элементов, к которым будет применяться JS. Если вы используете UI библиотеку, то в ней могут быть события и колбек-функции, которые можно использовать для вызова перерасчета стилей в JS. Знайте, какие обработчики событий будут в браузере на странице, где будут запускаться JS стили, а также попробуйте ограничить количество необходимых обработчиков событий. Ограничьте количество элементов, за которыми необходимо следить, подцепите похожие обработчики в глобальные события, используйте события фреймворка для более плотной интеграции и попробуйте новые браузерные API типа Resize Observer и Mutation Observer, если они могут вам помочь.
Заключение
Теперь когда вы попробовали на вкус математические функции в CSS, надеюсь, они вдохновят вас или убедят начать использовать стабильные свойства и экспериментировать с новыми. Если вы уже работаете с calc() или экспериментировали с min() и max(), пишите в комментариях. Хорошо покодить!
Автор: Dennis Gaebel
Источник: //webdesign.tutsplus.com/
Редакция: Команда webformyself.