CSS scope custom properties are not recognized when used to evaluate variables in the parent scope
P粉006847750
P粉006847750 2023-11-01 21:53:10
0
1
490

I'm trying to scale the size via avarcustom property so that the classes can be composed without coupling. The desired effect is that the 3 lists will have 3 different scales, but as shown on CodePen, all 3 lists have the same scale. I'm looking for an explanation of scoping and CSS custom property techniques that can achieve this with composable, loosely coupled code.


: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; }
  1. size 1
  2. size 2
  3. size 3
  1. size 1
  2. size 2
  3. size 3
  1. size 1
  2. size 2
  3. size 3


P粉006847750
P粉006847750

reply all (1)
P粉440453689

In your case you have evaluated the--scalecustom properties at the root level to define the--size-*properties and then defined the- -scaleAgainwithin child elements. This will not trigger the evaluation again as it has already been done in theupper layer.

The following is a simple example to illustrate this problem:

.box { --color: var(--c, blue); } span { color: var(--color); }
I will not be red because the property is already evaluated and --color is set to blue using the default value
I will be red because at the time of the evaluation --c is red (inherited from the upper div)

To solve your problem, you need to move the declaration from:rootto the same level as the--scaledefinition:

.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; }
  1. size 1
  2. size 2
  3. size 3
  1. size 1
  2. size 2
  3. size 3
  1. size 1
  2. size 2
  3. size 3

In this case,--scaleis defined at the same level as its evaluation, so--size-*will be defined correctly for each case.


FromSpecification:

In the first case you're stuck at3because no value is specified for--scaleat the root level. In the last case we are stuck with2because we defined--scaleat the same level and we have its value.


In all cases we should avoid any evaluation at the:rootlevel as it is simply not useful. The root level is the top level in the DOM, so all elements will inherit the same value, it is impossible to have different values within the DOM unless we evaluate the variable again.

Your code is equivalent to this code:

:root { --size-1: calc(1 * 1 * 1rem); --size-2: calc(2 * 1 * 1rem); --size-3: calc(3 * 1 * 1rem); }

Let’s give another example:

:root { --r:0; --g:0; --b:255; --color:rgb(var(--r),var(--g),var(--b)) } div { color:var(--color); } p { --g:100; color:var(--color); }
some text

some text

Intuitively, we might think that we can change--colorby changing one of the 3 variables defined at the:rootlevel, but we cannot do this with the above operation code Same as this:

:root { --color:rgb(0,0,255) } div { color:var(--color); } p { --g:100; color:var(--color); }
some text

some text

3 variables (--r,--g,--b) are evaluated within:rootcode> therefore We have replaced them with their values.

In this case we have 3 possibilities:

  • Use JS or other CSS rules to change variables within:root. This doesn't allow us to have different colors:

:root { --r:0; --g:0; --b:255; --color:rgb(var(--r),var(--g),var(--b)) } div { color:var(--color); } p { --g:200; /*this will not have any effect !*/ color:var(--color); } :root { --g:200; /*this will work*/ }
some text

some text

  • Evaluate the variable again within the desired element. In this case we lose any flexibility and the definition inside:rootwill become useless (or at least will become the default):

:root { --r:0; --g:0; --b:255; --color:rgb(var(--r),var(--g),var(--b)) } div { color:var(--color); } p { --g:200; --color:rgb(var(--r),var(--g),var(--b)); color:var(--color); }
some text

some text

  • Change the:rootselector to the universal selector*. This will ensure that our functions are defined and evaluated at all levels. In some complex cases this may produce some unwanted results

* { --r:0; --g:0; --b:255; --color:rgb(var(--r),var(--g),var(--b)) } div { color:var(--color); } p { --g:200; color:var(--color); }
some text

some text


With this in mind, we should always keep evaluation to the lowest possible point in the DOM tree, especiallyafter a variable has changed(or at the same level)

This is something we shouldn’t do

:root { --r: 0; --g: 0; --b: 0; } .color { --color: rgb(var(--r), var(--g), var(--b)) } .green { --g: 255; } .red { --r: 255; } p { color: var(--color); } h1 { border-bottom: 1px solid var(--color); }

Red

I want to be red :(

Green

I want to be green :(

this is what we are supposed to do

:root { --r:0; --g:0; --b:0; } .color { --color:rgb(var(--r),var(--g),var(--b)); } .green { --g:255; } .red { --r:255; } p { color:var(--color); } h1 { border-bottom: 1px solid var(--color); }

Red title

Yes I am red :D

Green title

Yes I am green :D

We can also do this:

:root { --r:0; --g:0; --b:0; } .color { --color:rgb(var(--r),var(--g),var(--b)); } .green { --g:255; } .red { --r:255; } p { color:var(--color); } h1 { border-bottom: 1px solid var(--color); }

Red title

Yes I am red :D

Green title

Yes I am green :D

    Latest Downloads
    More>
    Web Effects
    Website Source Code
    Website Materials
    Front End Template
    About us Disclaimer Sitemap
    php.cn:Public welfare online PHP training,Help PHP learners grow quickly!