Coding With Fun
Home Docker Django Node.js Articles Python pip guide FAQ Policy

Vue new feature: JS variables can be used in CSS


Jun 01, 2021 Article blog


Table of contents


preface

While watching Vue 3: Mid-2020 Status Update, I remember that Yuyuxi wanted to release the RC version (candidate version) in mid-July, followed by the 3.0 official version in early August.

But now it's early August, why hasn't it been released? W hat's the beginning of this month? S o I hurried to github上 to see if there is any wind and grass movement, watching and suddenly found a very interesting feature, this feature I used to think: if I define variables in data can also be used in CSS that would be good ah! (Have you ever thought of it that way)

fantasy

I used to think this way when I was working on a project:

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


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


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

Of course, think about knowing that it's impossible, JS and CSS belong to different contexts, where does CSS this from?

So how do I use CSS variables in JS Then you can only manipulate DOM with JS and stuff the variables into style for example, by getting the DOM element with ref and then dom.style.color = this.color

Or in the template:

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


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

However, this approach is still flawed, such as the original does not recommend writing styles in style property, and variable reuse can be very troublesome, such as a set of DOM elements want to use this variable, then have to give this group a class name, and then in mounted document.getElementsByClassName() get to DOM collection and then loop through each element, adding dom.style.color = this.color waste a lot of performance.

In fact, CSS itself has many defects, not complete, so it led to the emergence of a variety of preprocessors: Sass Less Stylus etc. ...

They provide many features for CSS loops, conditional statements, variables, functions, and so on...

One of the features that is very useful is the variable! So CSS also introduced the concept of variables, and since CSS many things have really been much easier, operating CSS through JS and then using CSS where they are needed is much more efficient than before.

What is a CSS variable

In JS (more than JS, all languages are similar), variables have several characteristics:

  • statement
  • use
  • scope

statement

For ease of understanding, let's use JS as an analogy:

var color = 'red';

In CSS, it is equivalent to:

--color: red;

Of course this is not the same as JS but if you learn a language like PHP or Sass it should be easy to understand that in PHP or Sass there is no keyword when declaring a variable, but a dollar sign $ in the first digit of the variable name, which means declaring a variable.

PHP:

$color = 'red';

Sass:

$color: color;

But $ symbol is occupied by Sass and the @ is occupied by less so CSS can only come up with other symbols, and the symbol of CSS is two minus signs --

use

It doesn't make much sense for light to declare a variable, and it's only when you use it that it's valuable:

JS:

console.log(color)

You can see var is just a keyword that declares a variable, color is the name of the variable.

PHP:

echo $color;

Scss:

h1 {
    color: $color;
}

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

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

CSS:

h1 {
    color: var(--color);
}

Although, like PHP Sass calls with a prefix (because that's part of the variable name), it's not the same as wrapping the variable around a var().

scope

This is well understood, not only in JS but also in CSS such as:

JS:

var color = 'red';


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


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


h1(); // red
div(); // blue

Similar to what's in CSS:

body {
    --color: red;
}


h1 {
    color: var(--color); /** 这里获取到的是全局声明的变量,值为red **/
}


div {
    --color: blue;
    color: var(--color); /** 这里获取到的是局部声明的变量,值为blue **/
}

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

Chinese CSS variable

Once I saw two brain holes open the library, only to find that the CSS variable can still play like this:

  • chinese-gradient
  • chinese-layout

As can be seen from their names, both start with chinese so the approximate rate is a CSS variable made with Chinese, and the point goes in and sees it.

That is to say, CSS变 is very inclusive, unlike in the past programming must be named in English, Chinese this time can also run perfectly, do not believe that we try:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <!-- 在这里用link标签引入中文布局 -->
  <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/chinese-layout">


  <!-- 在这里用link标签引入中文渐变色 -->
  <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/chinese-gradient">
  <style>
    /* 清除默认样式 */
    * { padding: 0; margin: 0 }
    ul { list-style: none }


    /* 全屏显示 */
    html, body, ul { height: 100% }


    /* 在父元素上写入九宫格 */
    ul {
      display: grid;
      grid: var(--九宫格);
      gap: 5px
    }


    /* 给子元素上色 */
    li {
      background: var(--极光绿)
    }
  </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>

Results:

 Vue new feature: JS variables can be used in CSS1

That is, the CSS variable can be defined as this:

body {
    --蓝绿色: aquamarine;
}

Then when called:

h1 {
    color: var(--蓝绿色);
}

The variable in vue

So how do you use the variables declared in the <script > in vue3's <style **<script>**

First, let's create a vite project that supports vue3

npm init vite-app vars

Then go to the folder to install the dependency:

cd vars

npm i

Then create a component that is as long as this:

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


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


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

Remember what the fantasy components were like at the beginning of the article:

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

But even vue can't give CSS a this unless you do another preprocessor, but this time using CSS can be very close to our fantasy components:

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

First, write vars in the <style > label, and then write in braces the values you declared in data

Try again if this variable is responsive, does dynamically changing the this.color value in the <script > label cause a change in the view? Let's try:

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

Results:

 Vue new feature: JS variables can be used in CSS2

You can see that every 300 milliseconds we change the value of this.opacity it maps to CSS variable, this.opacity changes, -- the value of --opacity changes, and the view updates as the data updates, which is fantastic!

Multiple variables are separated by 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>

The brain hole is wide open

Now that the CSS libraries, chinese-gradient and chinese-layout have verified the feasibility of CSS Chinese variables, and I remember that the properties of objects can also be written Chinese, let's try to see if we can write Chinese with this black magic in vue

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


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


<style vars="{ 透明度 }">
h1 {
  color: rgb(65, 184, 131);
  opacity: var(--透明度);
}
</style>

Results:

 Vue new feature: JS variables can be used in CSS3

reside! c orrect! t ube! u se! finish!

Later we will not name the words also don't use Chinese Pinyin, write directly Chinese haha! The variable name can be seen at a glance at subsequent maintenance (although english is still recommended).

principle

Guess what, too, that the approximate rate uses methods like dom.style.setProperty ('--opacity', this.opacity), press f12 to open the console and, sure enough, it controls the style property of the component element:

 Vue new feature: JS variables can be used in CSS4

But we just used var in <style> tag, scoped is actually very common, so what would they compile if they two came across each other?

<style vars="{ 透明度 }" scoped>
h1 {
  color: var(--透明度);
}
</style>

Results:

 Vue new feature: JS variables can be used in CSS5

You can see that Vue compiles the CSS variable in the same way as the random string of characters behind data-v-:

 Vue new feature: JS variables can be used in CSS6

So here's the problem, if I define a --color property in a global style, I want to use this global CSS variable in a component with the scoped property, but once I use the CSS variable in scoped it will be compiled into: --62a9ebed-color, but the global definition is not --62a9ebed-color but --color, so there will be a situation where the global property cannot be found. It's actually as simple as adding a global to the back of -- on it:

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

In this way, the compiled CSS will become: var (--color)!

epilogue

Isn't that fun? Vue update is full of sincerity, but everyone is focusing on Composition-API not noticing these humble corners, but these corners can greatly improve our development experience.

By the right point, CSS variables are also compatible:

 Vue new feature: JS variables can be used in CSS7

As you can see from the www.caniuse.com/#search=CSS Variables website, it is incompatible with IE and remember to confirm the scope of your project that needs to be compatible when using it.

Original link: segmentfault.com/a/1190000023479851

Author: Hand tore red and black trees

That's what W3Cschool编程狮 has to say about Vue's new features: you can use JS variables in CSS, and I hope it's helpful.