fantasy

I used to think this when I was working on projects:

<template>
  <h1>{{ color }}</h1>
</template>

<script>
export default {
  data () {
    return {
      color: 'red'}}}</script>

<style>
h1 {
  color: this.color;
}
</style>
Copy the code

JS and CSS belong to different contexts.

So how do you use JS variables in CSS? Then you have to use javascript to manipulate the DOM and insert variables into the style. For example, use ref to get the DOM element, and then dom.style.color = this.color.

Or in a template:

<template>
  <h1 :style="{ color }">Vue</h1>
</template>

<script>
export default {
  data () {
    return {
      color: 'red'}}}</script>
Copy the code

However, there are drawbacks to this approach. For example, it is not recommended to write styles in the style property, and it is troublesome to reuse variables. For example, if a group of DOM elements want to use this variable, you have to give the group a class name. Then mounted inside the document. The getElementsByClassName (), access to the DOM after collection to iterate over each element, add DOM. For its style, color = this. Color, wasted a lot of performance.

The CSS itself is not Turing complete, which has led to a variety of preprocessors: Sass, Less, Stylus…

They provide many features for CSS: loops, conditional statements, variables, functions…

One of the most useful features is variables! CSS also introduced the concept of variables, since the CSS variables, a lot of things are really convenient, through JS manipulation of CSS variables, and then use the CSS variables where needed, this method is much more efficient than before.

What is a CSS variable

In JS, variables usually have the following properties:

  • The statement
  • use
  • scope
  • The default value

The statement

To make it easier to understand, let’s use the analogy of JS:

var color = ‘red’;

Equivalent in CSS:

–color: red;

Of course, this is different from JS, but if you learn a language like PHP or Sass, it should be easy to understand. In PHP or Sass, you do not have a keyword to declare a variable. Instead, you add a dollar sign $to the first part of the variable name, which means that the variable is declared.

PHP:

$color = 'red';
Copy the code

Sass:

$color: color;
Copy the code

But the $sign is taken by Sass and the @ sign is taken by less, so CSS can only come up with other symbols. The CSS symbol is the two minus signs

use

Just declaring a variable doesn’t make much sense, it’s only valuable if it’s used:

JS:

console.log(color)
Copy the code

You can see that var is just a keyword to declare the variable, and color is the variable name.

PHP:

echo $color;
Copy the code

Scss:

h1 {
	color: $color;
}
Copy the code

But in PHP or Sass, you declare variables with $and use them with $.

This confuses many developers, so CSS uses a function called var() when using variables:

CSS:

h1 {
	color: var(--color);
}
Copy the code

Like PHP and Sass, it is called with a prefix (because that is part of the variable name), but the variable needs to be wrapped with a var().

scope

This makes sense. Not only does JAVASCRIPT have scopes, but CSS also has scopes. For example:

JS:

var color = 'red';

function h1 () {
  console.log(color);
}

function div () {
  var color = 'blue';
  console.log(color);
}

h1(); // red
div(); // blue
Copy the code

Similar to CSS:

body{-color: red;
}

h1 {
  color: var(--color); /** this is the global declaration of the variable, value red **/
}

div{-color: blue;
  color: var(--color); /** Here we get a locally declared variable with a value of blue **/
}
Copy the code

That is, the scope of a variable is the valid scope of the selector in which it is located.

The default value

Sometimes we need to declare a variable and then assign it a value at some point in time. We usually write:

let a

function xxx () {
    if (xxx) {
        a = xxx
    }
}
Copy the code

This variable a defaults to undefined, which is equivalent to this:

let a = undefined
Copy the code

CSS variables can also have default values, which are the second argument to the var() function:

div {
    width: var(--width, 100px)}Copy the code

If the –width variable is not defined, then the value of the second parameter is taken, which is suitable for wrapping components.

Chinese CSS variables

One time I saw two imaginative libraries, I realized that CSS variables could be played like this:

  • chinese-gradient
  • chinese-layout

As can be seen from their names, they both start with Chinese, so the probability is made in Chinese CSS variables, click in to see what is true.

That is to say, CSS variable tolerance is very strong, unlike the past programming time must be English naming, Chinese this time can also run perfectly, do not believe let’s try:

<! DOCTYPEhtml>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="Width = device - width, initial - scale = 1.0">
  <title>Document</title>
  <! Introduce Chinese layout with link tag -->
  <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/chinese-layout">

  <! -- Use link tag to introduce Chinese gradient -->
  <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/chinese-gradient">
  <style>
    /* Clear the default style */
    * { padding: 0; margin: 0 }
    ul { list-style: none }

    /* Full screen display */
    html.body.ul { height: 100% }

    /* Write the grid */ on the parent element
    ul {
      display: grid;
      grid: var(-- nine grid); gap:5px
    }

    /* Color the child elements */
    li {
      background: var(-- aurora green)}</style>
</head>
<body>
  <ul>
    <li></li>
    <li></li>
    <li></li>
    <li></li>
    <li></li>
    <li></li>
    <li></li>
    <li></li>
    <li></li>
  </ul>
</body>
</html>
Copy the code

Running result:

In other words, CSS variables can be defined like this:

body{-- turquoise: aquamarine; }Copy the code

Then when called:

h1 {
  color: var(-- blue-green); }Copy the code

Variables in vue

How can you use variables declared in

First let’s create a vite project (don’t use vue-cli) :

npm init vite-app vars

Then go to this folder to install the dependency:

cd vars

npm i

Then create a component that looks like this:

<template>
  <h1>{{ color }}</h1>
</template>

<script>
export default {
  data () {
    return {
      color: 'red'}}}</script>

<style vars="{ color }">
h1 {
  color: var(--color);
}
</style>
Copy the code

Remember what the fantasy components look like at the beginning of this article:

<style>
h1 {
  color: this.color;
}
</style>
Copy the code

It’s impossible to make a “this” in CSS unless you make a preprocessor, but this time you can use the CSS variable to get closer to your fantasy component:

<style vars="{ color }">
h1 {
  color: var(--color);
}
</style>
Copy the code

First write vars=”{}” in the

If there are multiple variables, separate them with commas:

<template>
  <h1>Vue</h1>
</template>

<script>
export default {
  data () {
    return {
      border: '1px solid black'.color: 'red'}}}</script>

<style vars="{ border, color }" scoped>
h1 {
  color: var(--color);
  border: var(--border);
}
</style>
Copy the code

Again, check whether the variable is responsive. Will dynamically changing the value of this. Opacity in the

<template>
  <h1>Vue</h1>
</template>

<script>
export default {
  data () {
    return {
      opacity: 0
    }
  },
  mounted () {
    setInterval(_= > {
      this.opacity >= 1 && (this.opacity = 0)
      this.opacity += 0.2
    }, 300)}}</script>

<style vars="{ opacity }">
h1 {
  color: rgb(65.184.131);
  opacity: var(--opacity);
}
</style>
Copy the code

Running result:

You can see that every 300 milliseconds we change the value of this. Opacity, which maps to the CSS variable, this. Opacity changes — the value of the opacity changes accordingly, and the view updates accordingly as the data is updated.

Imaginative

Since the two CSS libraries, Chinese-gradient and Chinese-layout, verify the feasibility of CSS Chinese variables, and I remember that the properties of objects can also be written in Chinese, let’s try to use this dark magic to write Chinese in Vue:

<template>
  <h1>Vue</h1>
</template>

<script>
export default {
  data () {
    return {
      'Transparency': 0
    }
  },
  mounted () {
    setInterval(_= > {
      this['Transparency'] > =1 && (this['Transparency'] = 0)
      this['Transparency'] + =0.2
    }, 300)}}</script>

<style vars="{transparency}">
h1 {
  color: rgb(65.184.131);
  opacity: var(-- transparency); }</style>
Copy the code

Running result:

R!!!! However! Into! The work! !

In the future, if you don’t name it, don’t use Chinese pinyin, write Chinese directly haha! It is easy to see the variable name during subsequent maintenance (but it is still recommended to use English).

The principle of

SetProperty (‘–opacity’, this.opacity); press f12 to open the console. Sure enough, it controls the style property of the component element:

< span style = “box-sizing: border-box; color: RGB (74, 74, 74); line-height: 22px; white-space: inherit;”

<style vars="{transparency}" scoped>
h1 {
  color: var(-- transparency); }</style>
Copy the code

Running result:

You can see that Vue also compiles the CSS variable to a string of random characters following data-v- :

Here’s the problem: if I define a –color property in the global style, I want to use the global CSS variable in the scoped component, but once I use the CSS variable in the scoped, it will compile to: – 62 a9ebed – color, but the global definition instead – 62 a9ebed – color – color, it will appear the situation of couldn’t find a global property, how to solve this problem? Just add global: to the end of –.

<style vars="{ color }" scoped>
h1 {
  color: var(--global:color);
}
</style>
Copy the code

Var (–color) = var(–color);

conclusion

Isn’t that fun? Vue is doing a great job with this update, but everyone is so focused on comification-API that they don’t pay attention to the small corners, which can greatly improve our development experience.

By the way, CSS variables are also compatible:

As you can see from the Caniuse website, it is not compatible with IE, so remember to check the scope of compatibility required by your project when using it.

update

At present, the syntax in this article has been modified by Yu Yuxi. For new syntax, see Vue 3.0.3: New CSS Variable Passing and the Latest Ref Proposal.

Previous excellent article

  • Create your own Visual Data Map without any libraries
  • “Product Manager: The opening animation of Hongmeng is very handsome. Please give us a whole page.”
  • Vue3 will not support IE11, but focus on Vue2.7
  • You Yuxi: Ref Grammar Sugar Proposal
  • “Double 11 small black box is cool? Let’s use CSS variables to improve!”
  • “Don’t underestimate the nine grid, one question can let a candidate reveal his true colors!”
  • “Mobile Layout Interview Questions to test your CSS Skills (Center)”
  • A series of confusing behaviors after setting prototype Objects as Proxies
  • Vue’s Super Fun New Feature: DOM Portal
  • “Use of React’s Super-popular CSS-in-JS Library in the Vue Project: Styled – Components”
  • Is It Finally Vue’s Turn to Inspire React?
  • A Small Pit in Vue3 on IOS
  • Upgrade your React project to Immer instead of Immutable by 2020
  • “Soul Interrogation from the Author of React Hooks and Immutable”
  • Hooks use of the New VUe-Router
  • React 17 is officially a transition version!
  • Yu Yuxi: The Design Process of Vue3
  • The Father of Node’s refactoring Deno is finally released. Will it Replace Node after all?
  • The Vue3 beta was released early this morning and openly supports scaffolding!