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; }
- size 1
- size 2
- size 3
- size 1
- size 2
- size 3
- size 1
- size 2
- size 3
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:
To solve your problem, you need to move the declaration from
:rootto the same level as the--scaledefinition: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:
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:3 variables (
--r,--g,--b) are evaluated within:rootcode> therefore We have replaced them with their values.In this case we have 3 possibilities:
:root. This doesn't allow us to have different colors::rootwill become useless (or at least will become the default)::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 resultsWith 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
this is what we are supposed to do
We can also do this: