Spec-Zone.ru › CSS

Использование пользовательских свойств CSS (переменных)

Пользовательские свойства (иногда называемые переменными CSS или каскадными переменными) — это сущности, определённые авторами CSS, которые представляют собой конкретные значения, которые можно повторно использовать по всему документу. Они задаются с помощью правила @property или с помощью синтаксиса пользовательских свойств (например, --primary-color: blue;). К пользовательским свойствам можно обратиться с помощью функции CSS var() (например, color: var(--primary-color);).

У сложных веб-сайтов очень много CSS, и это часто приводит к многократному повторению значений CSS. Например, часто можно увидеть, что один и тот же цвет используется в сотнях различных мест в стилевых файлах. Изменение цвета, который был продублирован во многих местах, требует поиска и замены во всех правилах и файлах CSS. Пользовательские свойства позволяют определить значение в одном месте, а затем ссылаться на него в нескольких других местах, что упрощает работу с ним. Другим преимуществом является читабельность и семантика. Например, --main-text-color легче понять, чем шестнадцатеричный цвет #00ff00, особенно если цвет используется в разных контекстах.

Пользовательские свойства, определённые с использованием двух тире (--), подчиняются каскаду и наследуют своё значение от родителя. Правило @property позволяет получить больший контроль над пользовательским свойством и указать, наследует ли оно своё значение от родителя, какое у него начальное значение и какие должны быть ограничения типа.

Примечание: Переменные не работают внутри медиа-запросов и запросов к контейнерам. Вы можете использовать функцию var() в любой части значения в любом свойстве на элементе. Вы не можете использовать var() для имён свойств, селекторов или чего-либо помимо значений свойств, что означает, что вы не можете использовать его в медиа-запросе или запросе к контейнеру.

Объявление пользовательских свойств

В CSS вы можете объявить пользовательское свойство, используя два тире в качестве префикса для имени свойства, или с помощью правила @property. В следующих разделах описано, как использовать эти два метода.

Использование префикса из двух тире (--)

Пользовательское свойство с префиксом из двух тире начинается с --, за которым следует имя свойства (например, --my-property), и значение свойства, которое может быть любым допустимым значением CSS. Как и любое другое свойство, оно записывается внутри правила. Следующий пример демонстрирует, как создать пользовательское свойство --main-bg-color и использовать значение <named-color> brown:

section {
  --main-bg-color: brown;
}

Селектор, заданный для правила (элементы <section> в приведённом выше примере), определяет область, в которой можно использовать пользовательское свойство. По этой причине распространённой практикой является определение пользовательских свойств для псевдокласса :root, чтобы к ним можно было обратиться глобально:

:root {
  --main-bg-color: brown;
}

Это не всегда обязательно: у вас может быть веская причина для ограничения области действия ваших пользовательских свойств.

Примечание: Имена пользовательских свойств чувствительны к регистру — --my-color будет рассматриваться как отдельное пользовательское свойство от --My-color.

Использование правила @property

Правило @property позволяет вам более точно определять пользовательское свойство, имея возможность ассоциировать с ним тип, задавать значения по умолчанию и управлять наследованием. В следующем примере создаётся пользовательское свойство под названием --logo-color, которое ожидает значение типа <color>:

@property --logo-color {
  syntax: "<color>";
  inherits: false;
  initial-value: #c0ffee;
}

Если вы хотите определить или работать с пользовательскими свойствами в JavaScript вместо непосредственного использования CSS, для этого существует соответствующий API. Подробнее об этом вы можете прочитать на странице CSS Properties and Values API.

Обращение к пользовательским свойствам с помощью var()

Независимо от выбранного вами способа определения пользовательского свойства, вы используете его, обращаясь к свойству в функции var() вместо стандартного значения свойства:

details {
  background-color: var(--main-bg-color);
}

Первые шаги с пользовательскими свойствами

Давайте начнём с HTML, к которому мы хотим применить некоторые стили. Есть контейнер

<div>, который содержит несколько дочерних элементов, некоторые из которых содержат вложенные элементы:

<div class="container">
  <div class="one">
    <p>One</p>
  </div>
  <div class="two">
    <p>Two</p>
    <div class="three">
      <p>Three</p>
    </div>
  </div>
  <input class="four" placeholder="Four" />
  <textarea class="five">Five</textarea>
</div>

Мы будем использовать следующий CSS для стилизации нескольких различных элементов на основе их классов (ниже не показаны некоторые правила макета, чтобы мы могли сосредоточиться на цветах). В зависимости от их классов, мы задаём элементам cornflowerblue или aquamarine фоновые цвета:

/* For each class, set some colors */
.one {
  background-color: cornflowerblue;
}
.two {
  color: black;
  background-color: aquamarine;
}
.three {
  background-color: cornflowerblue;
}
.four {
  background-color: cornflowerblue;
}
.five {
  background-color: cornflowerblue;
}

Это даёт следующий результат:

Существует возможность использовать пользовательские свойства для замены повторяющихся значений в этих правилах. После определения --main-bg-color в области .container и обращения к его значению в нескольких местах обновлённые стили выглядят так:

/* Define --main-bg-color here */
.container {
  --main-bg-color: cornflowerblue;
}

/* For each class, set some colors */
.one {
  background-color: var(--main-bg-color);
}
.two {
  color: black;
  background-color: aquamarine;
}
.three {
  background-color: var(--main-bg-color);
}
.four {
  background-color: var(--main-bg-color);
}
.five {
  background-color: var(--main-bg-color);
}

Использование псевдокласса :root

Для некоторых объявлений CSS возможно объявить это выше в каскаде и позволить наследованию CSS решить эту проблему. Для непростых проектов это не всегда возможно. Объявив пользовательское свойство для псевдокласса :root и используя его там, где необходимо по всему документу, автор CSS может уменьшить необходимость в повторении:

/* Define --main-bg-color here */
:root {
  --main-bg-color: cornflowerblue;
}

/* For each class, set some colors */
.one {
  background-color: var(--main-bg-color);
}
.two {
  color: black;
  background-color: aquamarine;
}
.three {
  background-color: var(--main-bg-color);
}
.four {
  background-color: var(--main-bg-color);
}
.five {
  background-color: var(--main-bg-color);
}

Это приводит к тому же результату, что и в предыдущем примере, но позволяет сделать одно каноническое объявление желаемого значения свойства (--main-bg-color: cornflowerblue;), что очень полезно, если вы хотите изменить значение по всему проекту позже.

Наследование пользовательских свойств

Пользовательское свойство, определённое с использованием двух тире --, а не @property, всегда наследует значение от своего родителя. Это показано в следующем примере:

<div class="one">
  <p>One</p>
  <div class="two">
    <p>Two</p>
    <div class="three"><p>Three</p></div>
    <div class="four"><p>Four</p></div>
  </div>
</div>
div {
  background-color: var(--box-color);
}

.two {
  --box-color: cornflowerblue;
}

.three {
  --box-color: aquamarine;
}

Результаты var(--box-color) в зависимости от наследования следующие:

  • class="one": неверное значение, которое является значением по умолчанию для пользовательского свойства, определённого таким образом
  • class="two": cornflowerblue
  • class="three": aquamarine
  • class="four": cornflowerblue (унаследованное от родителя)

Один аспект пользовательских свойств, который демонстрируют примеры выше, заключается в том, что они не ведут себя точно так же, как переменные в других языках программирования. Значение вычисляется там, где оно необходимо, а не хранится и повторно используется в других местах стилевого файла. Например, вы не можете установить значение свойства и ожидать, что значение будет получено в правиле потомка сестры. Свойство устанавливается только для сопоставленного селектора и его потомков.

Использование @property для управления наследованием

Правило @property позволяет явно указать, наследует ли свойство или нет. В следующем примере создаётся пользовательское свойство с помощью правила @property. Наследование отключено, определён тип данных <color>, и начальное значение равно cornflowerblue.

Родительский элемент задаёт --box-color значением green и использует --box-color в качестве значения для своего фонового цвета. Дочерний элемент также использует background-color: var(--box-color), и мы ожидали бы, что у него будет цвет green, если наследование было включено (или если оно было определено с помощью синтаксиса с двумя тире).

<div class="parent">
  <p>Parent element</p>
  <div class="child">
    <p>Child element with inheritance disabled for --box-color.</p>
  </div>
</div>
@property --box-color {
  syntax: "<color>";
  inherits: false;
  initial-value: cornflowerblue;
}

.parent {
  --box-color: green;
  background-color: var(--box-color);
}

.child {
  width: 80%;
  height: 40%;
  background-color: var(--box-color);
}

Поскольку inherits: false; установлено в правиле, а значение для свойства --box-color не объявлено в области .child, вместо значения green, которое было бы унаследовано от родителя, используется начальное значение cornflowerblue:

END_OF_DOCUMENT_MARKER

Значения по умолчанию пользовательских свойств

Вы можете определить значения по умолчанию для пользовательских свойств, используя функцию var() и правило initial-value @property.

Примечание: Значения по умолчанию не используются для решения проблем совместимости в случаях, когда пользовательские свойства CSS не поддерживаются, так как значение по умолчанию в этом случае не поможет. Значения по умолчанию применяются в том случае, когда браузер поддерживает пользовательские свойства CSS и может использовать другое значение, если нужная переменная еще не определена или имеет неверное значение.

Определение значений по умолчанию в функции var()

Используя функцию var(), вы можете определить несколько значений по умолчанию, когда заданная переменная еще не определена; это может быть полезно при работе с Пользовательскими элементами и Теневым DOM.

Первый аргумент функции — имя пользовательского свойства. Второй аргумент — необязательное значение по умолчанию, используемое в качестве замещающего значения, когда указанное пользовательское свойство некорректно. Функция принимает два параметра, присваивая всё после первой запятой как второй параметр. Если второй параметр некорректен, то значение по умолчанию не сработает. Например:

.one {
  /* Red if --my-var is not defined */
  color: var(--my-var, red);
}

.two {
  /* pink if --my-var and --my-background are not defined */
  color: var(--my-var, var(--my-background, pink));
}

.three {
  /* Invalid: "--my-background, pink" */
  color: var(--my-var, --my-background, pink);
}

Включение пользовательского свойства в качестве значения по умолчанию, как показано во втором примере выше (var(--my-var, var(--my-background, pink))), является правильным способом предоставления нескольких значений по умолчанию с помощью функции var(). Однако следует учитывать влияние этого метода на производительность, так как для анализа вложенных переменных требуется больше времени.

Примечание: Синтаксис значения по умолчанию, как и у пользовательских свойств, допускает запятые. Например, var(--foo, red, blue) определяет значение по умолчанию red, blue — всё между первой запятой и концом функции считается значением по умолчанию.

Значения по умолчанию, использующие начальное значение @property

Помимо использования var(), начальное значение initial-value, определенное в правиле @property, может использоваться как механизм значения по умолчанию. В действительности, мы уже видели это в разделе @property наследования.

В следующем примере устанавливается начальное значение --box-color для свойства cornflowerblue с помощью правила @property. В правиле, следующего за этим правилом, мы хотим установить значение --box-color в aquamarine, но в имени значения допущена ошибка. То же самое относится к третьему случаю <div>, где мы использовали значение 2rem для пользовательского свойства, которое ожидает правильное <color> значение. Оба значения 2rem и aqumarine являются неверными цветовыми значениями, поэтому применяется начальное значение cornflowerblue:

@property --box-color {
  syntax: "<color>";
  initial-value: cornflowerblue;
  inherits: false;
}

.one {
  --box-color: aquamarine;
  background-color: var(--box-color);
}

.two {
  --box-color: aqumarine;
  background-color: var(--box-color);
}

.three {
  --box-color: 2rem;
  background-color: var(--box-color);
}

Некорректные пользовательские свойства

Каждому свойству CSS можно присвоить определенный набор значений. Если вы пытаетесь присвоить свойству значение, которое не входит в его набор допустимых значений, оно считается некорректным.

Когда браузер сталкивается с недопустимым значением для обычного свойства CSS (например, значением 16px для свойства color), он отбрасывает объявление, и элементам присваиваются значения, которые они имели бы, если бы объявление не существовало. В следующем примере мы видим, что происходит, когда обычное объявление CSS некорректно; color: 16px; отбрасывается, и вместо него применяется предыдущее правило color: blue:

<p>This paragraph is initially black.</p>
p {
  color: blue;
}

p {
  /* oops, not a valid color */
  color: 16px;
}

Однако, когда парсятся значения пользовательских свойств, браузер еще не знает, где они будут использоваться, поэтому он должен рассматривать почти все значения как допустимые. К сожалению, эти допустимые значения могут использоваться с помощью функционального обозначения var() в контексте, где они могут быть некорректными. Свойства и пользовательские переменные могут привести к некорректным заявлениям CSS, что приводит к понятию допустимого во время вычисления.

Когда браузер сталкивается с заменой недопустимого var(), то используется начальное или унаследованное значение свойства. Этот пример похож на предыдущий, за исключением того, что мы используем пользовательское свойство.

Браузер заменяет значение --text-color на var(--text-color), но 16px не является допустимым значением свойства для color. После подстановки свойство не имеет смысла, поэтому браузер обрабатывает эту ситуацию в два этапа:

  1. Проверить, является ли свойство color наследованием. Оно является, но у этого <p> нет родителя со свойством color, установленным.
  2. Установить значение на его стандартное начальное значение, которое является черным.
<p>This paragraph is initially black.</p>
:root {
  --text-color: 16px;
}

p {
  color: blue;
}

p {
  color: var(--text-color);
}

В таких случаях правило @property может предотвратить неожиданные результаты, позволив определить начальное значение свойства:

<p>This paragraph is initially black.</p>
@property --text-color {
  syntax: "<color>";
  inherits: false;
  initial-value: cornflowerblue;
}

:root {
  --text-color: 16px;
}

p {
  color: blue;
}

p {
  color: var(--text-color);
}

Значения в JavaScript

Для использования значений пользовательских свойств в JavaScript, как и для стандартных свойств.

// get variable from inline style
element.style.getPropertyValue("--my-var");

// get variable from wherever
getComputedStyle(element).getPropertyValue("--my-var");

// set variable on inline style
element.style.setProperty("--my-var", jsVar + 4);

См. также

  • Синтаксис пользовательских свойств
  • @property правило
  • var()
  • API свойств и значений CSS
  • Модуль CSS пользовательских свойств для каскадных переменных

© 2005–2024 MDN contributors.
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.
https://developer.mozilla.org/en-US/docs/Web/CSS/Using_CSS_custom_properties

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API