CSS 通常都被认为很简单,用它来描述网页样式,甚至很多时候都不被认为是一门编程语言。如今,它开始变得更加复杂了。
你可能觉得难以置信,但现在 CSS 不仅可以定义属性,还能进行数学运算,甚至可以直接获取窗口尺寸!下面将展示如何实现这一点。
@property
规则是 CSS 中的一个新特性,允许开发者创建自定义属性并设置其类型、继承性和初始值。通过这个特性,我们可以读取特定值并将其传递给自定义属性。
在下面的示例中,我们定义了两个自定义属性 --w_raw
和 --h_raw
,分别表示窗口的宽度和高度:
@property --w_raw {
syntax: '<length>';
inherits: true;
initial-value: 100vw;
}
@property --h_raw {
syntax: '<length>';
inherits: true;
initial-value: 100vh;
}
syntax: '<length>'
指定属性的类型为长度。inherits: true
表示该属性可以被继承。initial-value
将属性的初始值设置为 100vw
和 100vh
,即可视区域(viewport)的宽度和高度。现在,我们已经获取了窗口的宽度和高度值,但结果中包含了单位。如何删掉单位获得其中的数值呢?可以使用 CSS 中的数学工具:atan2(y, x)
和 tan()
。
atan2(y, x)
函数返回从 x 轴到点 (x, y) 的角度(以弧度为单位)。tan()
函数计算给定角度的正切值。使用这些函数,我们可以获得纯数值。在这里,我们将 var(--w_raw)
和 1px
作为参数传递,计算宽度的角度,然后将其转换为数值。通过这种方式,我们将宽度和高度转换为无单位的值,并存储在 :root
的变量中。
:root {
--w: tan(atan2(var(--w_raw), 1px));
--h: tan(atan2(var(--h_raw), 1px));
}
现在,数值已经存储在 CSS 中,如何显示它们呢?这需要用到计数器!
body::before {
content: counter(w) 'x' counter(h);
counter-reset: h var(--h) w var(--w);
}
body
上创建一个 ::before
伪元素来显示 CSS 内容。counter-reset
初始化计数器 h
和 w
,并将它们的值设置为 var(--h)
和 var(--w)
。content: counter(w) "x" counter(h);
以 “宽度 x 高度” 的格式显示宽度和高度计数器。现在,我们已经实现了一个纯 CSS 的窗口尺寸指示器。
浏览器会实时更新 --w
和 --h
,并在页面上显示它们。整个过程完全不依赖 JavaScript。
你可以点击这里尝试在线演示。
通过 @property
规则定义自定义属性,利用 CSS 的数学函数删除单位,并使用计数器显示数值,我们成功实现了一个纯 CSS 的窗口尺寸指示器。
这个过程展示了 CSS 的强大功能,可以在不依赖 JavaScript 的情况下实现相对复杂的功能。