CSS scoped custom property ignored when used to calc var in outer scope
CSS scoped custom property ignored when used to calc var in outer scope
I'm attempting to scale size via var
custom propertie in a way that the classes would compose without being coupled. The desired effect is that the 3 lists would be at 3 different scales but as demo'd on codepen all 3 lists are the same scale. I'm looking for an explanation of the scoping and a CSS custom property technique that could achieve this with composable loosely coupled code.
var
:root
--size-1: calc(1 * var(--scale, 1) * 1rem);
--size-2: calc(2 * var(--scale, 1) * 1rem);
--size-3: calc(3 * var(--scale, 1) * 1rem);
.size-1 font-size: var(--size-1)
.size-2 font-size: var(--size-2)
.size-3 font-size: var(--size-3)
.scale-1x --scale: 1
.scale-2x --scale: 2
.scale-3x --scale: 3
html
font: 1em sans-serif;
background: papayawhip;
ol
float: left;
list-style: none;
margin: 1rem;
<ol class="scale-1x">
<li class="size-1">size 1</li>
<li class="size-2">size 2</li>
<li class="size-3">size 3</li>
</ol>
<ol class="scale-2x">
<li class="size-1">size 1</li>
<li class="size-2">size 2</li>
<li class="size-3">size 3</li>
</ol>
<ol class="scale-3x">
<li class="size-1">size 1</li>
<li class="size-2">size 2</li>
<li class="size-3">size 3</li>
</ol>
@TemaniAfif You mean the
--custom-property
syntax?– ryanve
Aug 25 at 9:23
--custom-property
I mean the tag, I tagged the question with
css3
and you remove it– Temani Afif
Aug 25 at 9:25
css3
I thought
var
wasn't introduced till CSS4 @TemaniAfif– ryanve
Aug 25 at 9:28
var
@Temani Afif: Variables are CSS3 because CSS3 is defined by the working group as everything beyond CSS2, not because variables have shipping implementations. "CSS4" is not an official term. Note that Variables start out at level 1. The way people categorize certain level 3 or level 1 features as CSS3 and others as "CSS4" is... fascinating, to put it nicely.
– BoltClock♦
Sep 6 at 9:13
1 Answer
1
It's somehow tricky but in your case you have evaluated the --scale
custom property at the root level to define the --size-*
properties and then you defined the --scale
inside child elements and this will not trigger the evaluation again because it was done in an upper level.
--scale
--size-*
--scale
Here is a simple example to illustrate the issue:
.box
--color: var(--c, blue);
span
color: var(--color);
<div>
<div class="box">
<span style="--c:red">I will not be red because the property is already evaluated and --color is set to blue</span>
</div>
</div>
<div style="--c:red">
<div class="box">
<span>I will be red because at the time of the evaluation --c is red</span>
</div>
</div>
In order to make your logic work you need to move the declaration from root and make it at a same level of --scale
definition:
--scale
.scale
--size-1: calc(1 * var(--scale, 1) * 1rem);
--size-2: calc(2 * var(--scale, 1) * 1rem);
--size-3: calc(3 * var(--scale, 1) * 1rem);
.size-1 font-size: var(--size-1)
.size-2 font-size: var(--size-2)
.size-3 font-size: var(--size-3)
.scale-1x --scale: 1
.scale-2x --scale: 2
.scale-3x --scale: 3
html
font: 1em sans-serif;
background: papayawhip;
ol
float: left;
list-style: none;
margin: 1rem;
<ol class="scale-1x scale">
<li class="size-1">size 1</li>
<li class="size-2">size 2</li>
<li class="size-3">size 3</li>
</ol>
<ol class="scale-2x scale">
<li class="size-1">size 1</li>
<li class="size-2">size 2</li>
<li class="size-3">size 3</li>
</ol>
<ol class="scale-3x scale">
<li class="size-1">size 1</li>
<li class="size-2">size 2</li>
<li class="size-3">size 3</li>
</ol>
In this case, the --scale
is defined at the same level of its evaluation so --size-*
will be defined correctly for each case.
--scale
--size-*
From the specification:
To substitute a var() in a property’s value:
In your first situation, you are falling into the (3) because there is no value specified for --scale
at root level but in the last case we are falling into the (2) because we defined --scale
at the same level and we have its value.
--scale
--scale
Right but if CSS vars are actually live then why doesn't it inherit and evaluate? I'd like to avoid having the scale classes have knowledge of the size vars. Is there a way?
– ryanve
Aug 25 at 9:32
@ryanve because CSS goes from top to bottom ... imagine you are using inherit, can a parent element inherit from its child element? no ... same logic here, the root doesn't see the --scale property at the time of the evaluation. So if a child element change a property we will not get backwards to re evaluate all the parent properties, this will create cycle and it won't work
– Temani Afif
Aug 25 at 9:44
By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.
you should keep the css3, because it's css3 ;)
– Temani Afif
Aug 25 at 9:18