Главная » Статьи » 3 вещи о переменных CSS, которые вы могли не знать

3 вещи о переменных CSS, которые вы могли не знать

3 вещи о переменных CSS, которые вы могли не знать

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

что происходит, когда функция var() использует неопределенную переменную,

как работают резервные значения,

и как инструменты разработчика браузера могут вам помочь.

Неопределенные переменные

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

CSS и HTML — это сверхустойчивые языки, в которых ошибки прощаются, а одна крошечная ошибка не мешает отображению всей страницы.

Таким образом, использование неопределенной переменной не приведет к ошибке парсинга и не помешает загрузить, проанализировать или отобразить таблицу стилей. На самом деле, вы можете даже не осознавать, что что-то пошло не так, без тщательного исследования.

Возможны следующие причины использования неопределенной переменной:

вы просто допустили опечатку в имени переменной,

вы пытаетесь использовать переменную, существование которой вы предполагали, но это не так,

или вы пытаетесь использовать полностью допустимую переменную, но она не видна там, где вы хотите ее использовать.

Давайте рассмотрим последний пример.

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

Для примера давайте посмотрим этот код:

ol li { --foo: red; }
ul li { color: var(--foo); }

Конечно, ваш конкретный случай, вероятно, будет более сложным, чем этот, с гораздо большим количеством правил и гораздо более сложными селекторами. Но здесь происходит следующее: чтобы элементы ul li имели красный цвет, им также необходимо соответствовать правилу ol li, в котором этот цвет фактически определен. А этого, вероятно, не произойдет.

Сегодня, во многих случаях переменные CSS, как правило, определяются в каком-то селекторе верхнего уровня, таком как :root или html, и поэтому доступны во всем дереве DOM (эти селекторы соответствуют элементам-предкам всех других элементов на странице).

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

Итак, разобравшись с этим, давайте посмотрим, как браузеры работают с неопределенными переменными:

Если свойство не наследуется (например, border), то для свойства устанавливается его начальное значение.

Если оно наследуется (например, color), то для свойства устанавливается его унаследованное значение. Если их нет, то устанавливается исходное значение.

Давайте рассмотрим 2 примера, чтобы проиллюстрировать это:

:root { --main-color: #f06;
} .my-lovely-component { border: 1px solid var(--main-colo);
}

В первом примере выше допущена опечатка в var(-main-colo), в результате чего браузер не может определить, каким должно быть окончательное значение свойства border. Поскольку свойство border не наследуется в CSS, браузер оказывается в ситуации 1. Поэтому он устанавливает значение в его начальное состояние, которое и является medium none currentColor (см. Исходные значения на MDN).

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

:root { --main-color: #f06;
} body { color: gold;
} .my-lovely-component { color: var(--secondary-color);
}

В этом случае использовалась неопределенная переменная .my-lovely-component для значения color. Теперь, поскольку это свойство наследуется, браузер будет проходить DOM вверх, пока не найдет предка, который действительно определяет значение цвета. К элементу body применено правило, которое задает gold в качестве значения, так что в конечном итоге именно оно и будет использоваться.

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

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

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

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

Резервные значения и вложенность

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

color: var(--theme-color, red);

В этом случае происходит следующее: если браузер не найдет —theme-color, он вернется к использованию значения red. Итак, зачем вам это использовать? Я вижу несколько причин, по которым это может быть интересно:

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

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

Позвольте мне привести пример, чтобы прояснить этот второй случай:

.my-component { color: var(--active-color, black);
}
.my-component:hover { --active-color: red;
}

В этом примере, пока на элемент не наводится курсор, его свойство цвета использует неопределенную переменную (действительно, свойство —active-color еще не применяется к элементу), поэтому браузер использует резервное значение. Как только пользователь наводит курсор на элемент, второе правило начинает применяться и —active-color становится определенным, поэтому элемент становится красным.

Конечно, это условный пример, и вы могли бы просто определить второе правило color: red и позволить ему переопределить первое. Но иногда нужно использовать переменную сразу в нескольких свойствах.

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

Вы когда-нибудь видели что-то подобное:

color: var(--foo, var(--bar, var(--baz, var(--are, var(--you, var(--crazy)))));

Это абсолютно действительно, но, вероятно, совершенно бесполезно. Здесь происходит то, что запасное значение само по себе является другой функцией var(). И поскольку это так, оно (в свою очередь) также может использовать резервное значение и так далее…

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

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

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

В итоге действительно примерно следующее:

--my-variable: one, two, three;

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

content: var(--foo, one, two, three);

Хотя на самом деле это выглядит так, будто часть one, two, three представляет собой три разных параметра функции var(), на самом деле это всего лишь одно значение. Не запутайтесь.

Советы и приемы DevTools

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

Автозаполнение имен переменных

Это очень полезно при внесении некоторых быстрых изменений в панель Elements / Inspector, и если на вашем сайте определено множество различных переменных: DevTools автоматически предложит список существующих переменных, когда вы начнете вводить var(.

3 вещи о переменных CSS, которые вы могли не знать

Приведенный выше снимок экрана сделан в Firefox, но и Edge, и Chrome также поддерживают эту функцию.

Определение вычисленного значения

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

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

3 вещи о переменных CSS, которые вы могли не знать

Приведенный выше снимок экрана сделан в Edge, но то же самое касается и Chrome и Firefox. Интересно, что если всплывающая подсказка не появляется, это верный признак того, что используемая переменная не определена.

Цветовые типы

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

:root { --i-look-like-a-color: black;
}

Даже зная, что black является допустимым цветом, на данный момент мы не можем предположить, что он действительно будет использоваться как таковой. В конечном итоге он может быть использован в свойстве animation-name или где-то еще.

Тем не менее, DevTools по-прежнему показывает небольшой образец цвета рядом с переменными css, которые выглядят как цвета. Это сделано для удобства, потому что они, скорее всего, действительно будут цветами! И даже если это не так, это не будет проблемой для пользователей.

3 вещи о переменных CSS, которые вы могли не знать

Будущие возможности

Вот 2 вещи, которые, я думаю, были бы очень полезны, но пока не существуют:

переход от функции var() туда, где объявлена используемая в ней переменная,

быстро увидеть, что функция var() использует неопределенную переменную.

Как оказалось, я сейчас работаю именно над этим в DevTools для Edge и Chrome на основе Chromium! Надеюсь, эта статья была полезной, и вы узнали из нее несколько полезных вещей! Удачного кодирования!

Автор: Patrick Brosset

Источник: patrickbrosset.com

Редакция: Команда webformyself.