Должно ли отображаться содержимое CSS, если оно включает необъявленную переменную CSS?

#css #css-variables #css-content

#css #css-переменные #css-content

Вопрос:

Следующий CSS-код будет генерировать разные результаты в зависимости от того, определена переменная или нет --test2 :

 html::before {
    content: "test1:" var(--test1) " test2:" var(--test2);
} 

Если --test1 и --test2 определены, содержимое теста будет отображаться в окне просмотра. Если --test1 определено, но --test2 не определено, ни одно из тестовых содержимого не отображается.

Правильное ли это поведение, и если да, то почему?

Ответ №1:

Из спецификации:

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

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


Из той же спецификации:

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

Так что лучше подумайте о запасном варианте:

 html::before {
    content: "test1:" var(--test1,"") " test2:" var(--test2,"");
} 

Комментарии:

1. Большое вам спасибо за ваш отличный ответ и дополнительный пример кода. Я пытаюсь понять, почему разработчики спецификаций хотели content бы стать недействительными , если какая-либо его часть содержит переменную, определенную как CSS initial . Есть какие-нибудь мысли по этому поводу?

2. @RockPaperLz-MaskitorCasket не просто рассматривает content , потому что это применимо ко всем свойствам, и это логично. Если часть внутри свойства не может быть разрешена, то результат не определен, поэтому мы возвращаемся к исходному ИЛИ унаследованному (не недействительному, есть разница). Пример: padding:5px var(--p) 0 <— если вы не определяете p , будет ли это 0 или что? браузер просто проигнорирует все значение и будет использовать padding:initial

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

4. @RockPaperLz: Я думаю, что это привело бы к значительной сложности при незначительном выигрыше. Я согласен с вашим выводом.