@property
是CSS的新特性,用于定义自定义CSS属性,并使这些属性可以在CSS中使用,当然也可以在JavaScript中使用。
@property 简介
@property
允许开发者显示的定义CSS
属性,这些属性允许进行类型检查,以及设置默认值,定义之后的属性,可以直接在css
中使用,也可以在JavaScript
中使用。
@property 语法
@property --name {
syntax: <type> | <type> [ <type> ]*;
inherits: true | false;
initial-value: <value>;
}
@property
的语法如上所示,其中:
--name
:自定义属性的名称,必须以--
开头;syntax
:自定义属性的类型;inherits
:是否继承父元素的属性值;initial-value
:自定义属性的默认值;
需要注意的点有:
@property
定义的属性,必须以--
开头;syntax
和inherits
是必须的;initial-value
只有在syntax
为通用类型时,才是可选的,否则必须指定默认值;syntax
的类型有:<length>
:长度类型,如px
、em
等;<number>
:数字类型;<percentage>
:百分比类型;<length-percentage>
:长度或百分比类型;<color>
:颜色类型;<image>
:图片类型;<url>
:URL类型;<integer>
:整数类型;<angle>
:角度类型;<time>
:时间类型;<resolution>
:分辨率类型;<transform-function>
:变换函数类型;<custom-ident>
:自定义标识符类型;<transform-list>
:变换列表类型;
syntax
可以有多个类型,用|
分隔,表示可以接受多种类型的值,如<length-percentage> | <color>
表示可以接受长度或百分比类型,或者颜色类型的值;syntax
可以接受自定义值,例如css
有很多关键字,如auto
、inherit
等,这些关键字可以作为<custom-ident>
的值,如<custom-ident> | auto | inherit
;
如果上面的注意事项有一个没有满足,那么整条规则都会被忽略,但不会造成整条规则失效。
@property 示例
使用@property
定义一个自定义属性:
@property --my-color {
syntax: <color>;
inherits: false;
initial-value: red;
}
不知道为什么都喜欢用颜色作为示例,我看到的大多数都是这样的,所以我也跟着用颜色作为示例。
这样定义之后,就可以在css
中使用了:
div {
color: var(--my-color);
}
看起来和使用css
变量没什么区别,但是css
变量如果想要修改,只有两种方式:
- 直接修改
css
变量的值; - 使用
js
修改css
变量的值;
对比 css 变量
现在使用两个案例来对比@property
和css
变量:
1. 修改 css 变量
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
:root {
--my-color: red;
}
html, body {
margin: 0;
padding: 0;
}
body {
--my-color: blue;
display: flex;
justify-content: center;
align-items: center;
width: 100%;
height: 100vh;
color: var(--my-color);
}
</style>
</head>
<body>
<div>CSS变量</div>
</body>
</html>
可以看到css
变量在css
中直接修改是采用的就近原则,所以body
中的--my-color
会覆盖html
中的--my-color
。
如果使用JS
修改css
变量又是什么样子呢?
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
:root {
--my-color: red;
}
html, body {
margin: 0;
padding: 0;
}
body {
display: flex;
justify-content: center;
align-items: center;
width: 100%;
height: 100vh;
color: var(--my-color);
}
</style>
</head>
<body>
<div>CSS变量</div>
</body>
<script>
document.body.style.setProperty('--my-color', 'green');
</script>
</html>
可以看到使用JS
修改css
变量,也是采用就近原则,是直接在行内样式中添加--my-color
,然后覆盖html
中的--my-color
。
2. 修改 @property
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
@property --my-color {
syntax: '<color>';
inherits: false;
initial-value: red;
}
html, body {
margin: 0;
padding: 0;
}
body {
--my-color: blue;
display: flex;
justify-content: center;
align-items: center;
width: 100%;
height: 100vh;
color: var(--my-color);
}
</style>
</head>
<body>
<div>@property</div>
</body>
</html>
可以看到@property
在css
中修改是直接修改的,和css
变量不一样,@property
是直接修改的。
效果对比
上面的案例分析了css
变量和@property
的区别,那么我们知道区别了有什么用?他们都可以达到修改样式的目的,那么我们为什么要使用@property
呢?
其实主要是它们的侧重点不一样,css
变量的侧重点是样式的统一,而@property
的侧重点是样式的可控。
现在css
变量已经在大放异彩了,很多站点皮肤切换使用的就是css
变量,所以css
变量的案例就不用列举了。
现在我们直接看@property
能做到的而css
变量做不到的,就是动画:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
:root {
--my-color: red;
}
html, body {
margin: 0;
padding: 0;
}
body {
display: flex;
justify-content: center;
align-items: center;
width: 100%;
height: 100vh;
color: var(--my-color);
animation: changeColor 1s infinite;
}
@keyframes changeColor {
from {
--my-color: red;
}
to {
--my-color: blue;
}
}
</style>
</head>
<body>
<div>@property</div>
</body>
</html>
可以看到使用css
变量是无法实现动画的过渡的,这个时候如果替换成@property
就可以实现了:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
@property --my-color {
syntax: '<color>';
inherits: false;
initial-value: red;
}
html, body {
margin: 0;
padding: 0;
}
body {
display: flex;
justify-content: center;
align-items: center;
width: 100%;
height: 100vh;
color: var(--my-color);
animation: changeColor 1s infinite;
}
@keyframes changeColor {
from {
--my-color: red;
}
to {
--my-color: blue;
}
}
</style>
</head>
<body>
<div>@property</div>
</body>
</html>
可以看到使用@property
就可以实现动画的过渡了。
实践
通过上面的案例我们知道@property
的修改可以实现动画的过渡,那么我们可以使用@property
来实现一些动画效果;
我们常见的有一个问题就是定义的背景是不能旋转的,但是使用@property
就可以实现了:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
@property --rotate {
syntax: '<angle>';
inherits: false;
initial-value: 0deg;
}
html, body {
margin: 0;
padding: 0;
}
body {
display: flex;
justify-content: center;
align-items: center;
width: 100%;
height: 100vh;
}
.card {
width: 200px;
height: 200px;
background-image: linear-gradient(var(--rotate), #1abc9c, #3498db);
background-size: cover;
animation: rotate 5s infinite;
}
@keyframes rotate {
from {
--rotate: 0deg;
}
to {
--rotate: 360deg;
}
}
</style>
</head>
<body>
<div class="card"></div>
</body>
</html>
这里通过使用线性渐变可以修改背景的旋转角度,从而实现背景的旋转。
感兴趣的可以直接将rotate
动画里面的修改--rotate
的值改为直接修改background-image
的值,它是无法实现动画的过渡的。
案例
都掌握了一个这么有趣的新特性,那么不是实现点有趣的东西都有点对不起观众了,下面我们就来实现一个有趣的东西。
直接上代码,个人感兴趣自己可以去看看具体实现,这次就不讲解代码实现了:
总结
@property
是一个非常有趣的新特性,它可以实现以前无法实现的动画过渡效果,它的使用也非常简单,只需要定义一个@property
,然后在需要使用的地方使用var(--my-color)
就可以了。
当然还有JS
操控@property
的方法,咱们先将这篇消化完成,后面再来看看JS
操控@property
的方法。