Scss как объявить переменную без значения. Введение в CSS переменных. Установка величин по умолчанию

CSS-переменные, или, точнее, кастомные CSS-свойства, доступны в Chrome начиная с 49 версии. Они могут быть полезны для уменьшения количества повторяющегося кода в CSS, создания впечатляющих эффектов вроде смены тем на лету и, потенциально, создания полифилов для будущих возможностей CSS.

Хаос в CSS

Обычная практика при разработке приложения - составить набор фирменных цветов, которые будут использоваться, чтобы поддержать единый стиль. Увы, многократное использование этих цветов в CSS не только является рутинной работой, но ещё и создаёт пространство для возникновения ошибок. Если в какой-то момент один из цветов нужно будет поменять, разработчик может неосторожно воспользоваться поиском и заменой по всему документу, что в большом проекте может быть довольно опасно.

В последнее время многие разработчики стали использовать CSS-препроцессоры типа SASS или LESS, которые решают эту проблему с помощью переменных. Хотя эти инструменты заметно увеличили продуктивность разработки, препроцессорные переменные имеют очень серьёзный недостаток: они статичны и не могут меняться на лету. Появление возможности динамически менять переменные не только позволит на лету менять темы сайта или приложения, но также означает значительное расширение возможностей отзывчивого дизайна и возможность создания полифилов для будущих свойств CSS. С выходом Chrome 49 переменные стали доступны в виде кастомных CSS-свойств.

Кастомные свойства в двух словах

Кастомные свойства расширяют наш CSS-инструментарий двумя новыми возможностями:

  • Автор кода может присваивать произвольные значения свойствам с придуманными им самим именами.
  • Функция var() позволяет затем использовать эти значения в других свойствах.

Краткий пример для демонстрации:

:root { --main-color : #06c ; } #foo h1 { color : var (--main-color); }

Функция var() возвращает значение кастомного свойства и заменяется им, в результате чего получается color: #06c; . Если кастомное свойство где-то определено в таблице стилей, оно будет доступно функции var .

На первый взгляд синтаксис может показаться странным. Многие разработчики недоумевают: «Почему бы просто не использовать $foo в качестве имён переменных?» Это было сделано специально для повышения гибкости и возможности в перспективе создавать макросы для $foo . Более подробно об этом можно прочесть в статье одного из авторов спецификации, Таба Аткинса (Tab Atkins).

Синтаксис кастомных свойств

Синтаксис кастомных свойств довольно прост:

Header -color : #06c ;

Обратите внимание, что кастомные свойства регистрозависимы, то есть --header-color и --Header-Color - это два разных свойства. Хотя синтаксис поначалу может показаться незамысловатым, на самом деле он позволяет сделать довольно много. К примеру, ниже - пример валидного кастомного свойства:

--foo: if (x > 5 ) this.width = 10 ;

Хотя это выражение не будет работать в качестве переменной (а также не будет валидным значением любого обычного свойства), потенциально оно может быть прочитано и обработано на лету с помощью JavaScript. Это означает, что кастомные свойства могут открыть доступ ко всевозможным интересным техникам, недоступным с нынешними CSS-препроцессорами. Так что если вы, позёвывая, думаете что-то вроде «Какая разница, у меня есть SASS…», подумайте ещё раз! Это не те переменные, с которыми вы привыкли работать.

Каскад

Кастомные свойства следуют стандартным правилам каскада, так что вы можете определить одно и то же свойство на разных уровнях специфичности:

:root { --color: blue; } div { --color: green; } #alert { --color: red; } * { color: var(--color); } <p > У меня синий цвет, унаследованный от root!p > <div > А для меня установлен зелёный!div > <div id ="alert" > Ну а для меня - красный! <p > И для меня красный: из-за наследования!p > div >

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

:root { --gutter : 4px ; } section { margin : var (--gutter); } @media (min-width: 600px ) { :root { --gutter : 16px ; } }

Необходимо отметить, что вышеприведённый приём невозможно повторить используя CSS-препроцессоры, потому что они неспособны переопределять переменные внутри медиавыражений. У этой возможности огромный потенциал!

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

:root { --primary-color : red; --logo-text : var (--primary-color); }

Функция var()

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

var ( [, ]?)

Здесь - имя определённого автором кастомного свойства, - фолбек, который будет использован, если упомянутое кастомное свойство не является валидным. Фолбек может быть списком, разделённым запятыми, он будет преобразован к единому значению. Например, var(--font-stack, "Roboto", "Helvetica"); определяет фолбек "Roboto", "Helvetica" . Обратите внимание, что краткая запись некоторых свойств (как в случае внешних и внутренних отступов) разделяется не запятыми, а пробелами, так что валидный фолбек для внутренних отступов будет выглядеть примерно так:

p { padding : var (--pad, 10px 15px 20px); } /* В стилях компоненты: */ .component .header { color : var (--header-color, blue); } .component .text { color : var (--text-color, black); } /* В стилях основного приложения: */ .component { --text-color : #080 ; /* header-color не установлен, поэтому остаётся синим в соответствии с фолбеком */ }

Этот метод особенно пригодится для стилизации веб-компонент, использующих Shadow DOM, поскольку кастомные свойства могут пересекать теневые границы. Автор веб-компоненты может создать начальный дизайн при помощи фолбеков, а потом настроить стили при помощи кастомных свойств:

<x-foo > #shadow <style > p { background-color : var (--text-background, blue); } style >
<p > У этого текста жёлтый фон, потому что так указано в документе! Иначе был бы синий. p > x-foo > /* В стилях основного приложения: */ x-foo { --text-background: yellow; }

При использовании var() нужно иметь в виду несколько нюансов. Например, переменные не могут быть именами свойств:

.foo { --side : margin-top; var (--side): 20px ; }

Это не является эквивалентом присваивания margin-top: 20px; . Более того, второе объявление не является валидным, и выбросит ошибку.

Аналогично, невозможно создать значение, часть которого берётся из переменной:

.foo { --gap : 20 ; margin-top : var (--gap)px ; }

Это тоже не является эквивалентом margin-top: 20px; . Чтобы собрать значение, понадобится кое-что другое: функция calc() .

Создание значений с помощью calc()

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

.foo { --gap : 20 ; margin-top : calc (var(--gap) * 1px ); /* зашибись */ }

Работа с кастомными свойствами в JavaScript

Чтобы получить значение кастомного свойства, используйте метод getPropertyValue() объекта CSSStyleDeclaration.

<p > Этот абзац красного цвета!p > /* JS */ var styles = getComputedStyle(document.documentElement); var value = String(styles.getPropertyValue("--primary-color")).trim(); // value = "red"

Аналогично, чтобы динамически менять значение кастомного свойства, используйте метод setProperty() объекта CSSStyleDeclaration .

/* CSS */ :root { --primary-color: red; } p { color: var(--primary-color); } <p > А теперь этот абзац зелёного цвета!p > /* JS */ document.documentElement.style.setProperty("--primary-color", "green");

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

/* CSS */ :root { --primary-color: red; --secondary-color: blue; } <p > Здорово! Этот абзац синего цвета!p > /* JS */ document.documentElement.style.setProperty("--primary-color", "var(--secondary-color)");

Поскольку кастомные свойства могут ссылаться на другие кастомные свойства, можете представить какие интересные динамические эффекты можно будет делать подобным образом.

Поддержка браузерами

На данный момент кастомные свойства поддерживаются в Chrome 49, Firefox 42, Safari 9.1, и iOS Safari 9.3.

Оригинальная статья: CSS Variables: Why Should You Care? Статью вычитывали:

Всем привет, тема переменных в CSS давно ходит по интернету, однако не все знают о том, что это такое, да и сама технология не так давно вышла в релиз. И хоть использовать её во многих случаях рановато, уже пора понимать что она из себя представляет и как ею пользоваться. Давайте попробуем разобраться с технологией вместе. Обращу ваше внимание, что эта статья для тех, кто не знает о CSS переменных (кастомных свойствах) или только слышал о них. Если вы знакомы и умеете работать с данной фичей, то вам данная статья будет не интересна.

Итак, тема с переменными в стилях уже затерта до дыр, т.к. они давным давно существуют в препроцессорах. Это удобно, я уже плохо представляю себе написание стилей без возможности сохранить где-то определенное значение (цвет, величину, название шрифта, тип маркера у списка, всё что может придти в голову...). Однако препроцессоры не могут дать нам той гибкости, которую дают нативные переменные в CSS, и скоро вы поймете, почему.

Для начала нужно понять, как объявлять и использовать переменные. Переменные объявляются в селекторах:

:root { --body-background: #ccc; } body { background-color: var(--body-background); }
Как видно из листинга выше, переменные объявляются двумя дефисами перед именем:
--variable-name

Чтобы использовать переменную, необходимо воспользоваться функцией var . Она имеет 2 параметра. Это, естественно, имя переменной, а вторым необязательным параметром идёт значение свойства, которое необходимо использовать в случае отсутствия переменной.

На этом набор новых возможностей с приходом переменных, разумеется, не заканчивается. Имея переменные в арсенале CSS, мы получаем большую гибкость в написании стилей. Например, теперь чтобы составить медиазапрос для экранов <320px в ширину, не нужно переопределять свойство целиком. Достаточно изменить значение переменной. Т.е.

Title { --wrapper-width: 50%; width: var(--wrapper-width); } @media (max-width: 320px) { --wrapper-width: 100%; }
Всё! Этого достаточно, чтобы свойство width изменило свое значение!

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

Что насчёт JavaScript?

Управляя аттрибутом style, можно изменить стиль, прибегая к минимальным затратам усилий. Приведу грубый пример на React.

Title { --background: blue; background-color: var(--background); }
changeColor() { this.setState({ style: {"--background": "green"} }); }

Title

Теперь по клику на элемент с классом title будет меняться цвет фона у элемента. Круто? Ещё бы! Не нужно добавлять новый класс, переопределять свойство или делать другие действия, способствующие изменению фонового цвета у элемента.

Ремарка

Если кто-то не знаком с React или кому-то просто непонятно, что произошло. Мы просто средствами JavaScript изменили аттрибут style у элемента, изменив значение переменной
--background


Используя переменные, изменять css извне стало проще, методов использования можно придумать массу, а мы пойдем дальше.

Области видимости

Нужно сказать пару слов об области видимости CSS переменных, здесь всё просто. Объявленная переменная доступна всем селекторам дочерних элементов данного селектора. Т.е. в листинге ниже использовать переменную --b в тэге html будет нельзя. А вот переменная --a в body и всех дочерних элементах будет работать без проблем (если её конечно не переопределят где-то ниже).

Html { --a: #ccc; } body { --b: #a3a3a3; }
(я знаю, что цвета в примерах скучные, но я плохо помню цвета по hex-коду:))

Переменные и calc

Как и любое числовое значение свойства, вы можете использовать переменную в функции calc .

Title { --title-width: 300px; width: calc(var(--title-width) + 150px); }
Круто! Особенно если учесть что переменную --title-width , можно менять как внутри CSS, так и извне.

Заметьте, что величину мы обязаны положить в переменную. Дописать px , % , rem и т.д. к вызванной переменной у нас не получится. Однако ничто не мешает нам умножить с помощью функции calc значение на единицу в необходимой нам величине.

Title { --title-width: 300; /* так не сработает */ width: var(--title-width)px; /* так сработает */ width: calc(var(--title-width) * 1px); }

В заключение

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

Custom properties (sometimes referred to as CSS variables or cascading variables ) are entities defined by CSS authors that contain specific values to be reused throughout a document. They are set using custom property notation (e.g., --main-color: black; ) and are accessed using the var() function (e.g., color: var(--main-color) ;).

Complex websites have very large amounts of CSS, often with a lot of repeated values. For example, the same color might be used in hundreds of different places, requiring global search and replace if that color needs to change. Custom properties allow a value to be stored in one place, then referenced in multiple other places. An additional benefit is semantic identifiers. For example, --main-text-color is easier to understand than #00ff00 , especially if this same color is also used in other contexts.

Custom properties are subject to the cascade and inherit their value from their parent.

Basic usage

Declaring a custom property:

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

Using the custom property:

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

First steps with custom properties

Let"s start with this simple CSS that applies the same color to elements of different classes:

One { color: white; background-color: brown; margin: 10px; width: 50px; height: 50px; display: inline-block; } .two { color: white; background-color: black; margin: 10px; width: 150px; height: 70px; display: inline-block; } .three { color: white; background-color: brown; margin: 10px; width: 75px; } .four { color: white; background-color: brown; margin: 10px; width: 100px; } .five { background-color: brown; }

We"ll apply it to this HTML:

1:
2: Text 5 - more text

Which leads us to this:

Notice the repetition in the CSS. The background color is set to brown in several places. For some CSS declarations, it is possible to declare this higher in the cascade and let CSS inheritance solve this problem naturally. For non-trivial projects, this is not always possible. By declaring a custom property on the element and is identical to the selector html, except that its specificity is higher."> :root pseudo-class and using it where needed throughout the document, a CSS author can reduce the need for repetition:

:root { --main-bg-color: brown; } .one { color: white; background-color: var(--main-bg-color); margin: 10px; width: 50px; height: 50px; display: inline-block; } .two { color: white; background-color: black; margin: 10px; width: 150px; height: 70px; display: inline-block; } .three { color: white; background-color: var(--main-bg-color); margin: 10px; width: 75px; } .four { color: white; background-color: var(--main-bg-color); margin: 10px; width: 100px; } .five { background-color: var(--main-bg-color); }

Text - more text

This leads to the same result as the previous example, yet allows for one canonical declaration of the desired property value.

Inheritance of custom properties

Custom properties do inherit. This means that if no value is set for a custom property on a given element, the value of its parent is used. Take this HTML:

With the following CSS:

Two { --test: 10px; } .three { --test: 2em; }

In this case, the results of var(--test) are:

  • For the class="two" element: 10px
  • For the class="three" element: 2em
  • For the class="four" element: 10px (inherited from its parent)
  • For the class="one" element: invalid value , which is the default value of any custom property

Keep in mind that these are custom properties, not actual variables like you might find in other programming languages. The value is computed where it is needed, not stored for use in other rules. For instance, you cannot set a property for an element and expect to retrieve it in a sibling"s descendant"s rule. The property is only set for the matching selector and its descendants, like any normal CSS.

Custom property fallback values

Fallback values aren"t used to fix the browser compatibility. If the browser doesn"t support CSS custom Properties, the fallback value won"t help. It"s just a backup for the browser which supports CSS Custom Properties to choose a different value if the given variable isn"t defined or has an invalid value.

The first argument to the function is the name of the custom property to be substituted. The second argument to the function, if provided, is a fallback value, which is used as the substitution value when the referenced custom property is invalid. The function only accepts two parameters, assigning everything following the first comma as the second parameter. If that second parameter is invalid, such as if a comma-separated list is provided, the fallback will fail. For example:

Two { color: var(--my-var, red); /* Red if --my-var is not defined */ } .three { background-color: var(--my-var, var(--my-background, pink)); /* pink if my-var and --my-background are not defined */ } .three { background-color: var(--my-var, --my-background, pink); /* Invalid: "--my-background, pink" */ }

Including a custom property as a fallback, as seen in the second example above, is the correct way to provide more than one fallback. The technique has been seen to cause performance issues as it takes more time to parse through the variables.

Note : The syntax of the fallback, like that of custom properties , allows commas. For example, var(--foo, red, blue) defines a fallback of red, blue - anything between the first comma and the end of the function is considered a fallback value.

Validity and values

The classical CSS concept of validity, tied to each property, is not very useful in regard to custom properties. When the values of the custom properties are parsed, the browser doesn"t know where they will be used, so must, therefore, consider nearly all values as valid .

Unfortunately, these valid values can be used, via the var() functional notation, in a context where they might not make sense. Properties and custom variables can lead to invalid CSS statements, leading to the new concept of valid at computed time.

What happens with invalid variables?

When the browser encounters an invalid var() substitution, the initial or inherited value of the property is used.

Consider the code snippet below.

HTML

This paragraph is initial black.

CSS

:root { --text-color: 16px; } p { color: blue; } p { color: var(--text-color); }

As expected, the browser substitutes the value of --text-color in place of var(--text-color) , but 16px is not a valid property value for color . After substitution, the property doesn’t make any sense. The browser handles this situation in two steps:

  1. Check if the property color is inheritable. Yes, but

    Doesn"t have any parent with color property. So move on to the next step.

  2. Set the value to its default initial value , i.e., black.

Result

The paragraph color will not be blue because invalid substitution is replaced by the initial value, not by the fallback. If you had written color: 16px without any variable substitutes, then it was a syntax error. The previous declaration will then be used.

Note : While a syntax error in a CSS property / value pair will lead to the line being ignored, using a cascaded value, invalid substitution -- using a custom property value that is invalid -- is not ignored, leading to the value to be inherited.

Values in JavaScript

To use the values of custom properties in JavaScript, it is just like standard properties.

// 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);

По мере роста проекта его CSS файлы разрастаются и засоряются. Справиться с этим помогут CSS переменные, они дают возможность повторно использовать повторяющиеся CSS свойства.
Раньше переменные можно было использовать только в Less или Sass, но это препроцессоры и требуют компиляции перед использованием. Теперь переменные доступны в чистом CSS.

Объявление и использование переменных в CSS

На переменные в CSS распространяются те же ограничения и правила наследования, что и на обычные CSS правила. Самый простой способ использовать их — объявить их глобально в псевдо-классе :root , так все остальные селекторы смогут его наследовать.

:root{ --awesome-blue: #2196F3; }

Для доступа к значению переменной надо использовать конструкцию var(…) . Обратите внимание, что имена зависят о регистра, то есть —foo != —FOO .

Some-element{ background-color: var(--awesome-blue); }

Поддержка

На данный момент Firefox поддерживает переменные в CSS. В Google Chrome начиная с версии 49 это возможность включена, если вы используете версию 48 или более старую, то вы можете вручную включить поддержку, перейдя на страницу chrome://flags/ и включить Enable experimental Web Platform features .

Пример 1 — Цветовые схемы

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

Теперь, если заказчик захотел поменять цвет на странице, мы можем изменить весь стиль поменяв одну строку (строку объявления переменной). Без переменных нам пришлось бы менять все места, где используется этот цвет.

Пример 2 — Понятные названия для сложных свойств

Еще одна замечательная возможность, которую дают CSS переменные — спрятать сложное свойство за коротким понятным именем. Хороший пример — CSS свойства с несколькими параметрами, например: box-shadow , transform и font .

Объявив переменную с понятным именем мы сможем использовать её не тратя время на разбор сложного свойства.

Пример 3 — Динамические переменные

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

Наведите на зеленый и на синий блоки.

Заключение

Как видите переменные довольно просты в использовании и их определенно стоит попробовать. Рассмотрим еще пару вещей, на которые стоит обратить внимание:

  • Функция var() имеет второй параметр, который будет использован в качестве значения, если переменная вызовет ошибку: width: var(--custom-width, 20%);
  • При объявлении собственного правила так же можно использовать переменные: --base-color: #f93ce9; --background-gradient: linear-gradient(to top, var(--base-color), #444);
  • Переменные можно использовать с еще одним нововведением в CSS — функцией calc(). Однако работает это пока только в Firefox: --container-width: 1000px; max-width: calc(var(--container-width) / 2);

На этом все! Попробуйте использовать CSS переменные, но пока избегайте их в серьезных проектах.

Функция var() позволяет вставлять значения пользовательских переменных в значения стилевых свойств. var() нельзя использовать в именах селекторов и в свойствах.

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

Aside { --my-font: Helvetica, Arial, sans-serif; }

Для обращения к переменной --my-font используется запись var(--my-font) , которую можно вставлять в качестве значения свойства. При этом область видимости переменной ограничена указанным селектором (aside в данном случае) и применение var(--my-font) в другом селекторе не даст результата. Для создания глобальных переменных их следует описать внутри селектора :root .

Обозначения

Описание Пример
<тип> Указывает тип значения. <размер>
A && B Значения должны выводиться в указанном порядке. <размер> && <цвет>
A | B Указывает, что надо выбрать только одно значение из предложенных (A или B). normal | small-caps
A || B Каждое значение может использоваться самостоятельно или совместно с другими в произвольном порядке. width || count
Группирует значения. [ crop || cross ]
* Повторять ноль или больше раз. [,<время>]*
+ Повторять один или больше раз. <число>+
? Указанный тип, слово или группа не является обязательным. inset?
{A, B} Повторять не менее A, но не более B раз. <радиус>{1,4}
# Повторять один или больше раз через запятую. <время>#
×

Значения

<переменная> Имя переменной, обозначается двумя дефисами впереди (--my-font). <значение> Резервное значение, которое подставляется вместо заданного, в том случае, если переменная не определена. Через запятую можно указать несколько значений.

Пример

var()

Кнопки

В данном примере вводятся две переменные: --primary-color и --info-color . Переменная --white не определена, поэтому подставляется указанное значение по умолчанию. Для селектора p.info значение переменной --primary-color переопределяется.

Спецификация

Каждая спецификация проходит несколько стадий одобрения.

  • Recommendation (Рекомендация ) - спецификация одобрена W3C и рекомендована как стандарт.
  • Candidate Recommendation (Возможная рекомендация ) - группа, отвечающая за стандарт, удовлетворена, как он соответствует своим целям, но требуется помощь сообщества разработчиков по реализации стандарта.
  • Proposed Recommendation (Предлагаемая рекомендация ) - на этом этапе документ представлен на рассмотрение Консультативного совета W3C для окончательного утверждения.
  • Working Draft (Рабочий проект ) - более зрелая версия черновика после обсуждения и внесения поправок для рассмотрения сообществом.
  • Editor"s draft (Редакторский черновик ) - черновая версия стандарта после внесения правок редакторами проекта.
  • Draft (Черновик спецификации ) - первая черновая версия стандарта.
×