2

What is the scope of CSS variables?

Variable scope , the availability range of the variable. Variables are not always valid and available, and limiting the scope of availability of a variable is the scope of the variable. The position of a CSS variable declared in the CSS hierarchy determines its scope of availability in the entire hierarchy.

Generally speaking, CSS variables are only visible to the child elements of the element in which they are declared. For example, in the following example, the --bgColor variable is visible to the child element:

<div class="parent">
  parent
  <div class="child">child</div>
</div>
.parent {
    --bgColor: pink;
}
.child {
    background: var(--bgColor);
}


But if the reverse is not visible:

.child {
    --bgColor: pink;
}
.parent {
    background: var(--bgColor);
}

Scope type

CSS variables follow the lexical scope (static scope) rules, and there are two scope types- global scope and local scope .

Global scope

The CSS variables declared in :root are variables of the global scope, which can be used anywhere in CSSOM.

/* 定义全局变量 */
:root{
  --primary-color: pink;
}

/* 任意位置都可以访问全局变量 */
.wrapper{
  background: var(--primary-color);
}

Local scope

The variables declared in other CSS levels are only visible to that CSS level and its children.

<div class="parent text">
  parent
  <div class="child text">child</div>
</div>
.parent {
  --fontSize: 24px;
  --lineHeight: 1.8;
}

.child {
  --fontSize: 18px;
  --lineHeight: 1.6;
}
.text {
  font-size: var(--fontSize);
  line-height: var(--lineHeight);
}


In the above example, you can declare and access variables in different CSS blocks with the same name.
Local scope can always access variables in outer scope or global scope, but not vice versa.

Variable promotion

Like JavaScript, CSS variable life can be promoted , that is, CSS variables can be used before they are declared. Before the browser renders the corresponding HTML element style, the declaration of CSS variables will be promoted and moved to the top of CSSOM.

body {
    background-color: var(--bgColor);
}

:root {
    --bgColor: pink;
}
body {
    background-color: var(--bgColor);
}

:root {
    --bgColor: pink;
}

As in the above example, the CSS variable --bgColor can be used before the declaration of the :root CSS variables can be accessed first and then declared. This feature makes CSS variables a very powerful feature.

Variable default value

As in the following example, the second value 1.2 separated by commas is the default value, that is, if --scale is not assigned, the value 1.2 is used.

.bigger {
  transform: scale(var(--scale, 1.2));
}

When using the var() function, you can assign one or more fallback attribute values (separated by commas), such as setting the font:

html {
  font-family: var(--fonts, Helvetica, Arial, sans-serif);
}

You can also use a series of variable rollbacks, but you need to use var() nest:

.bigger {
  transform: scale(var(--scale, var(--secondFallbackScale, 1.2));
}

If --scale is not defined, the next value, --secondFallbackScale , will be tried. If --secondFallbackScale also undefined, it will eventually fall back to 1.2.

Modular

The power of CSS variables is that the scope features help design a clean and modular system.

When we want theme , we can set CSS variables in the root element of the module so that the variables can be passed down without affecting elements outside the module.

<html>
    <body>
        <div class="mod">
            <p>
                段落 1
            </p>
        </div>
        <p>
            段落 2
        </p>
    </body>
</html>
.mod {
    --modBgColor: pink;
    --modMainColor: blueviolet;
}

p {
    background: var(--modBgColor);
    color: var(--modMainColor);
}

Untitled 3.png

The CSS variable declared in .mod <p> to "Paragraph 1" of mod , so the set background color and font color will take effect on "Paragraph 1."

<p> element will not be affected because it does not belong to .mod or its child elements, and the CSS variables --modBgColor and --modMainColor are not visible to it.

This is the power of the CSS variable scope .

Variable assignment variable

CSS variables can also use variable assignment variables. In the following example, CSS variables are used to render a gradient background color:

<div class="gradient"></div>
<div class="gradient"></div>
:root {
  --color1: pink;
  --color2: aquamarine;

  --bg: linear-gradient(to right, var(--color1), var(--color2));
}

.gradient {
  margin: 10px auto;
  width: 200px;
  height: 100px;
  background: var(--bg);
}

Untitled 4.png

Variable does not take effect

Now, if you want the gradient color of the second module to transition from pink to lavender, simply add the class name theme-2 to the second module and assign the variable —color2 lavender color:

.theme-2 {
  --color2: lavender;
}

However, variable and not entered into force, the problem is --bg in :root is declared and assigned a gradual change in the value of red to green, you can use this variable because it is a global variable can be accessed in theme-2 modified in —-color2 value does not Update —-bg and convert it into a js statement to make it easier to understand:

let color1 = 'red';
let color2 = 'aquamarine';
let bg = `${color1}-${color2}`;
function gradient() {
    color2 = 'lavender';
    console.log(bg);
}
gradient();  // red-aquamarine

Solution: Assign values at the level of using variables

:root {
  --color1: pink;
  --color2: aquamarine;
}

.gradient {
  --bg: linear-gradient(to right, var(--color1), var(--color2));
  background: var(--bg);
}

.theme-2 {
  --color2: lavender;
}

Put the assignment of —-bg .gradient level, and the —-color2 variable will take effect:

Need fair use

:root {
  --prop1: lol;
  --prop2: var(--prop1) var(--prop1);
  --prop3: var(--prop2) var(--prop2);
  --prop4: var(--prop3) var(--prop3);
  ...
    --prop30: var(--prop29) var(--prop29);
}

If rendered and run indefinitely, the above code snippet will cause the browser to try to create approximately one billion —-prop1 ('lol'), which is enough to keep most systems out of memory. This example was tested in 2019 with a MacBook Pro with 32gb RAM, and Safari stopped responding after 30 seconds of running. At that time, all WebKit kernel browsers were easily attacked through CSS variables. Now browsers have dealt with this situation accordingly. Variables that have been assigned more than 65536 times by variable references will be treated as invalid values.

Actual combat exercise (for example 🌰)

We can use the feature of the scope of CSS variables in different scenarios. The following example demonstrates how to use CSS variables to implement a switchable theme switch.

https://codepen.io/bobolovecat/pen/vYZJPop

We created two of scope, which are representative of a bright theme .theme-bright and dark themes .theme-dark . The same variable name is used in these two local scopes, and each variable is only effective for the corresponding module of the theme.

summary

The use of the CSS variable scope feature and var() variable fallback helps us design a clean and modular system. But also pay attention to the scope level and reasonable use of CSS variable assignment to avoid overly complex code structure and affect page rendering performance.

refer to

The Big Gotcha With Custom Properties
A Complete Guide to Custom Properties
Understanding the Scope in CSS Variables - Part 2 - Webkul Blog


球球
552 声望18 粉丝

中二少女