45
头图

This article mainly talks about a very new feature of CSS, CSS @property. Its appearance has greatly enhanced the capabilities of CSS!

According to MDN-CSS Property , @property CSS at-rule is part of the CSS Houdini API, which allows developers to explicitly define their CSS custom properties, allowing property type checking, setting default values, and defining the Whether custom attributes can be inherited.

What is CSS Houdini CSS Houdini opens the underlying CSS API to developers, allowing developers to extend CSS through this set of interfaces, and provides corresponding tools to allow developers to intervene in the style and layout process of the browser rendering engine to enable development People can write CSS code that the browser can parse to create new CSS features. Of course, it is not the focus of this article, but it is too much to describe.

How to use CSS Property We will quickly get started through some simple examples, and focus on the key role it plays in CSS animation and the huge improvement it brings to CSS animation.

Example

Normally, the way we define and use a CSS custom property is this:

:root {
    --whiteColor: #fff;
}

p {
    color: (--whiteColor);
}

With the @property rule, we can also define a CSS custom property like the following code:

<style>
@property --property-name {
  syntax: '<color>';
  inherits: false;
  initial-value: #fff;
}

p {
    color: var(--property-name);
}
</style>

A brief interpretation:

  • @property --property-name in --property-name is the name of the custom attribute, which can be referenced var(--property-name)
  • syntax: The grammatical rules of the custom attribute can also be understood as the type of the defined custom attribute
  • inherits: whether to allow inheritance
  • initial-value: initial value

Among them, the syntax and inherits descriptors in the @property

Of course, the writing method defined in JavaScript is also very simple, by the way:

<script>
CSS.registerProperty({
  name: "--property-name",
  syntax: "<color>",
  inherits: false,
  initialValue: "#c0ffee"
});
</script>

Supported syntax types

syntax are very rich, basically covering all the types you can think of.

  • length
  • number
  • percentage
  • length-percentage
  • color
  • image
  • url
  • integer
  • angle
  • time
  • resolution
  • transform-list
  • transform-function
  • custom-ident (a custom identifier string)

+ , # , | symbols in syntax

The syntax syntax of the defined CSS @property variable accepts some special type definitions.

  • syntax: '<color#>' : Accepts a comma-separated list of color values
  • syntax: '<length+>' : Accepts a space-separated list of length values
  • syntax: '<length | length+>' : Accepts a single length or a list of length values separated by spaces

OK, so much foreshadowing, then why use such troublesome syntax to define CSS custom properties? What are the advantages of the custom variables defined by CSS Houdini? Let's talk about them one by one below.

Use color syntax syntax type to act on gradients

Let's look at such an example, we have such a gradual pattern:

<div></div>
div {
    background: linear-gradient(45deg, #fff, #000);
}

Let's modify the above code and use CSS custom attributes instead:

:root {
    --colorA: #fff;
    --colorB: #000;
}
div {
    background: linear-gradient(45deg, var(--colorA), var(--colorB));
}

The result is the same gradient map:

We add another transition effect:

:root {
    --colorA: #fff;
    --colorB: #000;
}
div {
    background: linear-gradient(45deg, var(--colorA), var(--colorB));
    transition: 1s background;
    
    &:hover {
        --colorA: yellowgreen;
        --colorB: deeppink;
    }
}

Take a look at what happens when the mouse is hovered:

Although we set a 1s transition animation transition: 1s background , it is a pity that CSS does not support the direct transition of the background gradient, and what we get is only the change between two frames.

Use CSS @property for transformation

OK, next we have the protagonist of this article, using the CSS custom properties in the Houdini API to replace the original CSS custom properties.

To make a simple transformation, use color syntax syntax type:

@property --houdini-colorA {
  syntax: '<color>';
  inherits: false;
  initial-value: #fff;
}
@property --houdini-colorB {
  syntax: '<color>';
  inherits: false;
  initial-value: #000;
}
.property {
    background: linear-gradient(45deg, var(--houdini-colorA), var(--houdini-colorB));
    transition: 1s --houdini-colorA, 1s --houdini-colorB;
    
    &:hover {
        --houdini-colorA: yellowgreen;
        --houdini-colorB: deeppink;
    }
}

We used the @property syntax and defined two CSS Houdini custom variables --houdini-colorA and --houdini-colorB . When the hover changes, we change these two colors.

Concern that the transition statement we set transition: 1s --houdini-colorA, 1s --houdini-colorB , here, we are against CSS Houdini custom variable set of transition, rather than background set transition animation , and then look at the results:

Wow, I succeeded. The change of the gradient color has changed from a two-frame frame-by-frame animation to a tween animation, achieving the effect of transitioning from one gradient color to another gradient color! And this, thanks to the powerful ability of CSS Houdini custom variables!

CodePen Demo - CSS Houdini custom variable to achieve gradient color transition animation

Use CSS @property to achieve gradient background color transition animation

In the above DEMO, we used CSS Houdini custom variables to background the transition effect color , and CSS supports the transformation of one color to another. In this way, we cleverly implemented the gradient The transition animation of the background color.

Before, we have discussed how many ways to achieve gradient background color transition animation in CSS - cleverly make background color gradient animation! , to this day, we have one more way to achieve it!


@property --colorA {
  syntax: '<color>';
  inherits: false;
  initial-value: fuchsia;
}
@property --colorC {
  syntax: '<color>';
  inherits: false;
  initial-value: #f79188;
}
@property --colorF {
  syntax: '<color>';
  inherits: false;
  initial-value: red;
}
div {
    background: linear-gradient(45deg,
        var(--colorA),
        var(--colorC),
        var(--colorF));
    animation: change 10s infinite linear;
}

@keyframes change {
    20% {
        --colorA: red;
        --colorC: #a93ee0;
        --colorF: fuchsia;
    }
    40% {
        --colorA: #ff3c41;
        --colorC: #e228a0;
        --colorF: #2e4c96;
    }
    60% {
        --colorA: orange;
        --colorC: green;
        --colorF: teal;
    }
    80% {
        --colorA: #ae63e4;
        --colorC: #0ebeff;
        --colorF: #efc371;
    }
}

The complete code can be stamped here:

CodePen Demo - CSS Houdini custom variable to achieve gradient color transition animation 2

Conic-gradient cooperates with CSS @property to achieve pie chart animation

OK, above we demonstrated that syntax is color syntax type. At the beginning of the article, we also listed a lot of syntax types.

Let's try other types, using percentage percentage type or angle angle type to realize a hover animation of a pie chart.

If we still use the traditional way of writing, use angular gradients to achieve pie charts with different angles:

<div></div>
.normal {
    width: 200px;
    height: 200px;
    border-radius: 50%;
    background: conic-gradient(yellowgreen, yellowgreen 25%, transparent 25%, transparent 100%); 
    transition: background 300ms;
    
    &:hover {
        background: conic-gradient(yellowgreen, yellowgreen 60%, transparent 60.1%, transparent 100%); 
    }
}

Will get such an effect, because conic-gradient also does not support transition animation, the result is a direct change from one frame to another:

Ok, use CSS Houdini custom variables to transform it:

@property --per {
  syntax: '<percentage>';
  inherits: false;
  initial-value: 25%;
}

div {
    background: conic-gradient(yellowgreen, yellowgreen var(--per), transparent var(--per), transparent 100%); 
    transition: --per 300ms linear;
    
    &:hover {
        --per: 60%;
    }
}

Take a look at the effect after the transformation:

CodePode Demo - conic-gradient with CSS @property to achieve pie chart animation

In the past, using pure CSS to achieve very complicated effects, if it can be easily achieved, I have to sigh CSS @property powerful capabilities of 060794b62e31f0!

syntax of | symbols

By the way, I will demonstrate some slightly more complicated usages of syntax when defining Houdini custom variables.

In conic-gradient , we can use percentages or angles as keywords. The DEMO mentioned above can also be transformed into this:

@property --per {
  syntax: '<percentage> | <angle>';
  inherits: false;
  initial-value: 25%;
}
...

Indicates that our custom attribute can be either a percentage value or an angle value.

In addition to the | symbol, there are also + and # numbers indicating that the attributes separated by spaces and separated by commas are accepted, and those who are interested can try it by themselves.

Use length type to act on some length changes

Having mastered the above techniques, we can use the ability of Houdini's custom variables to fill in and repair some effects that could not be directly transitioned in the animation before.

In the past, we wanted to achieve the Hover effect of such a text underline:

p {
    text-underline-offset: 1px;
    text-decoration-line: underline;
    text-decoration-color: #000;
    transition: all .3s;
    
    &:hover {
        text-decoration-color: orange;
        text-underline-offset: 10px;
        color: orange;
    }
}

Because text-underline-offset does not support transition animation, the results obtained are as follows:

Use Houdini custom variable transformation to turn decay into magic:

@property --offset {
  syntax: '<length>';
  inherits: false;
  initial-value: 0;
}
div {
    text-underline-offset: var(--offset, 1px);
    text-decoration: underline;
    transition: --offset 400ms, text-decoration-color 400ms;
    
    &:hover {
        --offset: 10px;
        color: orange;
    text-decoration-color: orange;
    }
}

You can get a silky transition effect:

CodePen Demo - Underlines hover transition(Chrome solution with Houdini)

Actually, use CSS @property to cooperate with background to achieve screensaver animation

Well, because of the existence of CSS @property, the work that used to require a lot of CSS code has suddenly become simpler.

We try to use CSS @property with the background to simply implement a screensaver animation.

We can easily get such a graph by using background , the code is as follows:

html, body {
    width: 100%;
    height: 100%;
}
body {
    background-image:
        radial-gradient(
            circle at 86% 7%,
            rgba(40, 40, 40, 0.04) 0%,
            rgba(40, 40, 40, 0.04) 50%,
            rgba(200, 200, 200, 0.04) 50%,
            rgba(200, 200, 200, 0.04) 100%
        ),
        radial-gradient(
            circle at 15% 16%,
            rgba(99, 99, 99, 0.04) 0%,
            rgba(99, 99, 99, 0.04) 50%,
            rgba(45, 45, 45, 0.04) 50%,
            rgba(45, 45, 45, 0.04) 100%
        ),
        radial-gradient(
            circle at 75% 99%,
            rgba(243, 243, 243, 0.04) 0%,
            rgba(243, 243, 243, 0.04) 50%,
            rgba(37, 37, 37, 0.04) 50%,
            rgba(37, 37, 37, 0.04) 100%
        ),
        linear-gradient(rgb(34, 222, 237), rgb(135, 89, 215));
}

The effect is as follows, a fairly good static background image:

image

, we want to make it 160794b62e3429 move , in fact, it takes a certain amount of effort, but now, through CSS @property , we want to modify some of the details of the animation, we can get very good animation effects:

body,
html {
    width: 100%;
    height: 100%;
}

@property --perA {
  syntax: '<percentage>';
  inherits: false;
  initial-value: 75%;
}

@property --perB {
  syntax: '<percentage>';
  inherits: false;
  initial-value: 99%;
}

@property --perC {
  syntax: '<percentage>';
  inherits: false;
  initial-value: 15%;
}

@property --perD {
  syntax: '<percentage>';
  inherits: false;
  initial-value: 16%;
}

@property --perE {
  syntax: '<percentage>';
  inherits: false;
  initial-value: 86%;
}

@property --angle {
  syntax: '<angle>';
  inherits: false;
  initial-value: 0deg;
}

body {
    background-image: 
        radial-gradient(
            circle at var(--perE) 7%,
            rgba(40, 40, 40, 0.04) 0%,
            rgba(40, 40, 40, 0.04) 50%,
            rgba(200, 200, 200, 0.04) 50%,
            rgba(200, 200, 200, 0.04) 100%
        ),
        radial-gradient(
            circle at var(--perC) var(--perD),
            rgba(99, 99, 99, 0.04) 0%,
            rgba(99, 99, 99, 0.04) 50%,
            rgba(45, 45, 45, 0.04) 50%,
            rgba(45, 45, 45, 0.04) 100%
        ),
        radial-gradient(
            circle at var(--perA) var(--perB),
            rgba(243, 243, 243, 0.04) 0%,
            rgba(243, 243, 243, 0.04) 50%,
            rgba(37, 37, 37, 0.04) 50%,
            rgba(37, 37, 37, 0.04) 100%
        ),
        linear-gradient(var(--angle), rgb(34, 222, 237), rgb(135, 89, 215));
    animation: move 30s infinite alternate linear;
}

@keyframes move {
    100% {
        --perA: 85%;
        --perB: 49%;
        --perC: 45%;
        --perD: 39%;
        --perE: 70%;
        --angle: 360deg;
    }
}

The effect is as follows (because of the Gif upload size limit, the speed is accelerated, and some of them are intercepted, just as a simple indication):

property1

The overall effect is quite good, you can click here for the complete Demo:

CodePen Demo -- CSS @property PureCSS Wrapper

references:

At last

Well, this concludes this article. I introduced the CSS @property part of the CSS Houdini API, and used it to achieve some animation effects that could not be easily achieved in the past. I hope it will be helpful to you :)

Want to get the most interesting CSS information, don’t miss my public - 160794b62e3543 iCSS front-end facts 160794b62e3544 😄

More wonderful CSS technical articles are summarized in my Github - iCSS , which will be updated continuously. Welcome to click a star to subscribe to the collection.

If you have any questions or suggestions, you can exchange more, original articles, limited writing style, and lack of knowledge. If there are any irregularities in the article, please let me know.


chokcoco
12.3k 声望18.5k 粉丝