Это перевод “CSS Custom Properties — The Basics” — первой из серии статей Серджио Гомеса о пользовательских свойствах CSS. В ней рассказываются самые основы: что такое пользовательские свойства и как ими пользоваться.
Вы уже слышали о пользовательских свойствах CSS (также известных как CSS переменные) или даже имеете о них некоторое представление? Возможно, вы знаете о них из поста на developers.google.com? Если вы ещё не разобрались в особенностях их поддержки браузерами, не слышали о лучших практиках и не знаете чем они лучше переменных в Sass или Less — читайте дальше!
Поддержка браузерами
Начнём с главного: где работают пользовательские свойства CSS? На самом деле поддержка уже довольно хорошая: полная в Chrome, Opera, Firefox и Safari; Edge в разработке. Отслеживать можно на Can I use CSS Variables (Custom Properties).
Это значит, что их уже можно использовать для прогрессивного улучшения, а вскоре и как основной метод. В конце статьи немного о том как повторить функциональность пользовательских свойств с плагинов PostCSS.
Задайте значение, любое значение
Что же такое пользовательское свойство? Если коротко, это CSS свойство, которое может быть названо и использовано разработчиком. В отличии от встроенных свойств, таких как color или position, каждое из которых браузер понимает определённым образом, у пользовательского свойства нет иного значения, кроме того, которое ему зададите вы.
Пользовательские свойства отличаются от обычных просто по имени — у них есть префикс ‘--
’. Браузер ничего не делает с новым свойством. Если задать значение свойству color
, то у элементов, соответствующих селектору изменится цвет текста, если задать значение свойству --text-color
, то немедленных изменений не произойдёт.
В пользовательских свойствах CSS можно хранить любое валидное CSS значение.
Используйте повторно
От пользовательских свойств было бы мало толку, если бы вы могли только задавать им значения. Как минимум, нужно ещё и получать их обратно!
Для этого есть функция var()
.
Здесь мы присваиваем фону кнопки значение, которое хранится в пользовательском свойстве --theme-color
. Поначалу может казаться, что нет большой разницы между этим способом и прямым присваиванием значения. Но преимущества становятся более явными, когда мы начинаем использовать --theme-color
во многих селекторах и свойствах.
Значения по-умолчанию
Что если --theme-color
нигде не задано? var()
может принимать необязательный второй параметр, значение которого используется по-умолчанию.
Важно: Если вы хотите использовать в качестве значения по-умолчанию другое пользовательское свойство, корректный синтаксис
background-color: var(--theme-color, var(--fallback-color))
;
Область видимости и каскад
Где нужно задавать эти значения, прежде чем использовать? Пользовательские свойства следуют стандартным правилам насчёт области видимости и каскадирования, так что вы уже знаете как это работает!
Например, для чего-то вроде --theme-color
лучше всего использовать глобальную область видимости, чтобы значение было доступно везде. Проще всего это сделать с помощью псевдо-класса :root
:
Значение будет доступно в любом месте документа и его смогут использовать все ваши кнопки, заголовки и картинки.
Но что если вы хотите, чтобы у каждой части вашего сайта был свой цвет? Вы делаете всё так же, как и раньше, но теперь вы задаёте одно пользовательское свойство вместо того чтобы менять каждое свойство где он используется.
И конечно, вы всегда можете сделать исключения, задавая такие сложные селекторы, какие вам нужны.
Математика CSS
В функции calc()
часто совмещают разные единицы измерения:
Во время исполнения браузер вычисляет окончательный размер в пикселях, который зависит от ширины родителя.
Ещё один козырь в рукаве calc()
— его можно использовать с пользовательскими свойствами! Такая комбинация может быть очень полезна, поэтому ей уделено особое внимание в спецификации пользовательских свойств.
Можно даже совмещать разные единицы измерения, при условии что конечный результат будет осмысленным.
Взаимодействие CSS и JavaScript
Сравнивая пользовательские свойства с переменными в Sass, Less, PostCSS или других препроцессорах нужно учитывать, что пользовательские свойства — это настоящие сущности в браузере. Это значит их можно динамически менять во время исполнения, в отличии от результата работы препроцессоров.
Пользовательские свойства любого элемента доступны для методов getPropertyValue
и setProperty
.
Изменение значения пользовательского свойства сразу же повлияет на все свойства, которые от него зависят, как если бы вы меняли их напрямую. Значит, это отличный способ изменять сразу множество элементов с помощью скриптов.
Более подробно эта тема и лучшие практики использования пользовательских свойств в следующей статье.
Приложение: плагины PostCSS
Если вы хотите начать использовать пользовательские свойства CSS прямо сейчас, но вам нужна работа в браузерах, которые их пока не поддерживают, можете восполнить пробелы с помощью плагинов PostCSS.
Примите во внимание, что это сработает для организации и повторного использования CSS, но динамическая функциональность, такая как изменение пользовательских свойств с помощью JavaScript будет недоступна.
Вот краткий обзор основных случаев использования пользовательских свойств и их поддержки в паре популярных плагинов.
Функциональность | Пример кода | postcss-custom-properties |
postcss-css-variables |
---|---|---|---|
Определение в области видимости:root |
:root { --color: red;} |
Да. | |
Определение в других областях видимости | body { --color: red;} |
Нет. | Да. Может привести к неправильному поведению |
Получение значения | .foo { color: var(--color);} |
Да. | |
Получение значения с фолбэком | .foo { color: var(--color, red);} |
Да. | |
Определение внутри директивы | @media (min-size: 600px) { :root { --color: red; }} |
Нет. | Да. Может привести к неправильному поведению |
Использование внутри псевдоселектора | .foo:hover { --color: red;} |
Нет. | Да. Может привести к неправильному поведению |
Вычисления | .foo { text-size: calc(2 * var(--size));} |
Да, с помощью postcss-calc. | |
Изменение с помощью JavaScript | el.style.setProperty( '--color', 'red'); |
Нет. Невозможно с помощью препроцессоров. |