Как сохранить наследуемое значение внутри переменной CSS (также известной как пользовательское свойство)
Давайте рассмотрим этот упрощенный пример, чтобы проиллюстрировать проблему:
:root {
--color:rgba(20,20,20,0.5); /*определено как значение по умолчанию*/
}
.box {
width:50px;
height:50px;
display:inline-block;
margin-right:30px;
border-radius:50%;
position:relative;
}
.red {background:rgba(255,0,0,0.5);}
.blue {background:rgba(0,255,0,0.5);}
.box:before{
content:"";
position:absolute;
top:0;left:0;right:0;bottom:0;
border-radius:50%;
transform:translateX(30px);
background:var(--color);
filter:invert(1);
}
<!-- мы можем добавить любой цвет, который захотим -->
<div class="box red" style="--color:rgba(0,255,0,0.5);">
</div>
<div class="box blue" style="--color:rgba(0,255,255,0.5);">
</div>
<!-- мы можем добавить тот же цвет, но это не будет динамично -->
<div class="box red" style="--color:rgba(255,0,0,0.5);">
</div>
<!-- было бы хорошо иметь возможность наследовать значение, но это не сработает -->
<div class="box red" style="--color:inherit;">
</div>
В приведенном выше коде мы можем манипулировать фоном псевдоэлемента с помощью переменной CSS. В некоторых случаях нам нужно иметь тот же цвет, что и у основного элемента, но поскольку мы не знаем, какой цвет используется, мы не можем задать его вручную, и лучшим способом будет использование значения inherit
.
Как объяснено здесь: Почему свойство display, заданное для наследования с помощью переменной CSS, не работает? использование inherit
не сработает.
Есть ли способ сохранить наследуемое значение в переменной CSS и использовать его позже в любом свойстве (в нашем примере — в background
)?
Свободный перевод вопроса How to store inherit value inside a CSS variable (aka custom property)? от участника @Temani Afif.
Ответы (1 шт):
В таком случае мы можем рассмотреть fallback значение переменной CSS. Как объяснено в спецификации, мы можем написать что-то вроде этого:
background:var(--color,inherit)
Делая это, мы говорим нашему свойству (background) использовать inherit
в случае, если --color
не определен.
Это может решить проблему, но в нашем случае этого будет недостаточно, поскольку --color
всегда определяется на уровне :root
и будет унаследован псевдоэлементом, поэтому мы никогда не будем использовать резервное значение.
Чтобы исправить это, мы можем рассмотреть initial
значение, чтобы отменить определение нашего пользовательского свойства и принудительно использовать резервное значение. Как описано в спецификации:
initial значение пользовательского свойства — пустое значение; то есть вообще ничего. Это начальное значение имеет особое взаимодействие с нотацией var(), которое объясняется в разделе, определяющем var().
и
Чтобы заменить var() в значении свойства:
Если пользовательское свойство, указанное первым аргументом функции var(), испорчено анимацией, а функция var() используется в свойстве анимации или в одной из его длинных записей, то для остальной части этого алгоритма следует рассматривать пользовательское свойство как имеющее
initial
значение.Если значение пользовательского свойства, названного первым аргументом функции var(), отличается от
initial
значения, замените функцию var() значением соответствующего пользовательского свойства. В противном случае,если функция var() имеет резервное значение в качестве второго аргумента, замените функцию var() fallback (резервным) значением. Если в резервном значении есть ссылки на var(), замените и их.
В противном случае свойство, содержащее функцию var(), будет недействительно на момент вычисления значения.
Тогда наш код будет выглядеть так:
:root {
--color:rgba(25,25,25,0.5); /*определено как значение по умолчанию*/
}
.box {
width:50px;
height:50px;
display:inline-block;
margin-right:30px;
border-radius:50%;
position:relative;
}
.red {background:rgba(255,0,0,0.5);}
.blue {background:rgba(0,0,255,0.5);}
.box:before{
content:"";
position:absolute;
top:0;left:0;right:0;bottom:0;
border-radius:50%;
transform:translateX(30px);
background:var(--color,inherit);
filter:invert(1);
}
<div class="box red" style="--color:initial;">
</div>
<div class="box blue" style="--color:initial;">
</div>
<div class="box" style="background:grey;--color:initial;">
</div>
Нам просто нужно установить initial
значение для пользовательского свойства, чтобы принудительно использовать inherit
в качестве значения в фоновом режиме.
Использование initial
также может быть полезно для остановки распространения переменной CSS на определенном уровне, поскольку по умолчанию она наследуется всеми элементами.
Ниже код:
root {
--color: blue;
}
.container div{
border:5px solid var(--color,red);
padding:5px;
}
.stop {
--color:initial;
}
.green {
--color:green;
}
<div class="container">
<div>
<div>
<div class="stop"> <!-- we stop at this level -->
<div>
</div>
</div>
</div>
</div>
</div>
<div class="container stop"> <!-- we stop at this level -->
<div>
<div>
<div class="green"> <!-- we redefine at this level -->
<div>
</div>
</div>
</div>
</div>
</div>
1: речь идет о наследовании custom (пользовательского) свойства, а не background (фонового) свойства.
Свободный перевод ответа от участника @Temani Afif.