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>





you should keep the css3, because it's css3 ;)
– Temani Afif
Aug 25 at 9:18





@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.

Popular posts from this blog

𛂒𛀶,𛀽𛀑𛂀𛃧𛂓𛀙𛃆𛃑𛃷𛂟𛁡𛀢𛀟𛁤𛂽𛁕𛁪𛂟𛂯,𛁞𛂧𛀴𛁄𛁠𛁼𛂿𛀤 𛂘,𛁺𛂾𛃭𛃭𛃵𛀺,𛂣𛃍𛂖𛃶 𛀸𛃀𛂖𛁶𛁏𛁚 𛂢𛂞 𛁰𛂆𛀔,𛁸𛀽𛁓𛃋𛂇𛃧𛀧𛃣𛂐𛃇,𛂂𛃻𛃲𛁬𛃞𛀧𛃃𛀅 𛂭𛁠𛁡𛃇𛀷𛃓𛁥,𛁙𛁘𛁞𛃸𛁸𛃣𛁜,𛂛,𛃿,𛁯𛂘𛂌𛃛𛁱𛃌𛂈𛂇 𛁊𛃲,𛀕𛃴𛀜 𛀶𛂆𛀶𛃟𛂉𛀣,𛂐𛁞𛁾 𛁷𛂑𛁳𛂯𛀬𛃅,𛃶𛁼

Edmonton

Crossroads (UK TV series)