CSS 变量(也称为CSS自定义属性)可以容纳各种各样的东西。其中一些特征对我们来说并不常用,这就是为什么我决定写这篇文章的原因。
需要明确的是,本文着重介绍了您可以在 CSS 变量中添加的内容以及即将结束时的动画演示,因为我能力受限。如果您正在寻找有关使用 CSS 变量的更广泛的指导,那么可以阅读这篇很棒的文章。
单位和数值
让我们从简单开始。通常将带有单位的数值放入 CSS 变量中。正式名称为尺寸。
:root {
--nice-padding: 20px;
--decent-font-size: 1.25rem;
}
article {
padding: var(--nice-padding);
font-size: var(--decent-font-size);
}
变量可以通过calc()
来保存涉及其他变量的计算结果。
:root {
--image-width: 800px;
/* calculate height to preserve a 4:3 aspect ratio */
--image-height: calc(var(--image-width) / (4/3));
}
img {
width: var(--image-width);
height: var(--image-height);
}
同样,变量可与内置 CSS 函数一起使用。
:root {
--min: 1rem;
--max: 4rem;
--clamped-font-size: clamp(var(--min), 2.5vw, var(--max));
}
p {
font-size: var(--clamped-font-size);
}
无单位数值
变量也可以保存无单位的数值。一些 CSS 属性直接使用这些值。
:root {
--obnoxiously-big-number: 9001;
}
.important-modal {
z-index: var(--obnoxiously-big-number);
}
但有时,您可能希望将单位应用于这些值。这可以通过在calc()
表达式中进行乘法来完成。
:root {
--magic-number: 41;
}
.crazy-box {
width: calc(var(--magic-number) * 1%);
padding: calc(var(--magic-number) * 1px);
transform: rotate(calc(var(--magic-number) * 1deg));
}
非数值事物
CSS 变量不仅用于数字。它们可以包含属性可以识别的预定义关键字。
:root {
--bullets: circle;
--casing: uppercase;
}
ul {
list-style-type: var(--bullets);
text-transform: var(--casing);
}
还有一些自定义标识符,它们指向您已定义和命名的事物,如下面所示的animation-name
或grid-area
。
:root {
--layout-position: center-stage;
}
body {
grid-template-areas: 'left center-stage right';
}
main {
grid-area: var(--layout-position);
}
内容字符串
::before
和::after
的伪元素使用content
属性来显示内容。此内容可以是几处不同的内容,但通常是文本字符串。
下面的 CSS 显示了content
用字符串变量填充的代码。您还可以查看如何将字符串变量与其他字符串连接在一起,以及如何使用来从属性中提取字符串值attr()
。
:root {
--open: '(';
--close: ')';
--heading-hint: ' ' var(--open) 'this is a heading' var(--close);
--link-hint: ' ' var(--open) attr(href) var(--close);
}
h1::after {
content: var(--heading-hint);
}
a::after {
content: var(--link-hint);
}
这是一个演示,向您展示结果。
图片
CSS变量也可以保存图像。图像也可以显示在中content
,但是大家对background-image
可能更熟悉。
:root {
/* image from an external URL (PNG in this case) */
--image-from-somewhere: url(https://codersblock.com/assets/images/logo.png);
/* image from embedded data (SVG in this case) */
--image-embedded: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 512 512'%3E%3Cpath d='M8 256c0 136.966 111.033 248 248 248s248-111.034 248-248S392.966 8 256 8 8 119.033 8 256zm248 184V72c101.705 0 184 82.311 184 184 0 101.705-82.311 184-184 184z'%3E%3C/path%3E%3C/svg%3E");
}
.a {
background-image: var(--image-from-somewhere);
}
.b::after {
content: var(--image-embedded);
}
这使您可以隐藏冗长且笨拙的图像 URL,并仅在需要时使用较短的变量名称。
速记
CSS 变量可以用作速记中的单个值,也可以用作整个速记本身。下面的两个容器元素将具有相同的padding
。
:root {
--top-padding: 60px;
--all-padding: 60px 20px 40px 10px;
}
.container {
padding: var(--top-padding) 20px 40px 10px;
}
.another-container {
padding: var(--all-padding);
}
我发现有趣的是 CSS 变量还可以包含多个速记值的部分片段。
:root {
--weight-and-size: bold 3rem;
}
body {
font: var(--weight-and-size)/1.25 sans-serif;
}
清单
一些属性(例如 background 和 box-shadow)可以列出内容。您可以将 CSS 变量用作列表中的单个项目,列表的子列表或整个列表。
以下是将box-shadow
列表和 CSS 变量混合在一起的一些示例。我还偷看了一个将颜色列表放入 CSS 变量以在linear-gradient()
中使用的示例,因为您也可以完全做到这一点!
/*
quick reminder of the anatomy of a box-shadow!
box-shadow: <x-offset> <y-offset> <blur> <spread> <color>;
*/
:root {
--single-shadow:
0 0 0 40px #355c7d;
--multi-shadow:
0 0 0 60px #f67280,
0 0 0 80px #6c5b7b;
--gradient-colors: #f1bbba, #ece5ce, #c5e0dc;
}
.a {
box-shadow:
0 0 0 20px #60b99a,
var(--single-shadow);
}
.b {
box-shadow:
var(--multi-shadow);
}
.c {
box-shadow:
0 0 0 20px #60b99a,
var(--single-shadow),
var(--multi-shadow);
}
body {
background-image: linear-gradient(45deg, var(--gradient-colors));
}
这里是一个演示,以了解事物的外观。
颜色
不能忘记颜色!CSS 变量适用于颜色,通常会看到它们用于定义易于在整个站点中使用的颜色主题。
@media (prefers-color-scheme: light) {
:root {
--color-text: #233742;
--color-links: #d80b77;
--color-bg: white;
}
}
@media (prefers-color-scheme: dark) {
:root {
--color-text: white;
--color-links: #b4cddd;
--color-bg: #233742;
}
}
body {
color: var(--color-text);
background-color: var(--color-bg);
}
a {
color: var(--color-links);
}
您还可以将单独的颜色参数值放入 CSS 变量中,然后使用rgb()/rgba()
和hsl()/hsla()
将它们组合成一种颜色。这是使用的rgb()
示例。
:root {
--red: 216;
--green: 11;
--blue: 119;
}
a {
color: rgb(var(--red), var(--green), var(--blue));
}
与动画结合
某些浏览器将显示从起始值到结束值的单个离散跳转。某些浏览器将不执行任何操作。无论哪种方式,您都不会获得任何平滑,插值的动画。
问题是,您的浏览器不知道如何为您制作的变量设置动画。但是好消息!您可以借助 Properties and Values API 来解决此问题。它是 Houdini 的一部分,目前可在 Chrome,Edge 和 Opera 中运行,并且有望加入更多浏览器。
这是它的工作方式。首先,声明您的自定义属性。
@property --red {
syntax: '<integer>';
inherits: true;
initial-value: 0;
}
@property --green {
syntax: '<integer>';
inherits: true;
initial-value: 0;
}
@property --blue {
syntax: '<integer>';
inherits: true;
initial-value: 0;
}
这是告诉浏览器“嘿,这是一些变量,它们是默认为的整数 0”。然后,您的浏览器会说“哦,整数,天哪,我知道如何为它们设置动画”。现在我们可以进行动画了。
@keyframes red-fade {
50% { --red: 255; }
}
@keyframes green-fade {
50% { --green: 255; }
}
@keyframes blue-fade {
50% { --blue: 255; }
}
:root {
animation: red-fade 16s, green-fade 14s, blue-fade 12s;
animation-iteration-count: infinite;
}
在上面的 CSS 中,每个变量都有一个关键帧动画,该变量从 0(initial-value 声明的)255 来回移动。这些值在:root
元素上具有动画效果,并且所有子元素都可以使用它们,因为我们使用声明了变量inherits: true
。
.swatch {
background-color: rgb(var(--red), var(--green), var(--blue));
}
这样,我们就有了 3 个独立动画的 CSS 变量,这些变量通过组合在一起rgb()
以创建一个不断变化的background-color
。没有 JavaScript ,相当的整洁!
该演示实际上有很多事情要做。多个动画正在由 CSS 变量渲染(–red,–green,–blue)。
让我们分解一下:
-
首先,是大型 RGB 色板。我们已经讨论了这一点。
-
其次,指示器在颜色条上下移动。通过将 CSS 变量转换为负值px
来定位它们。例如,这是红色的。
.red .indicator {
transform: translateY(calc(var(--red) * -1px));
}
- 然后,在彩条下方显示数字。这个很有趣。如前所述,您可以使用
content
显示字符串,但是这不适用于我们的整数变量。然而,CSS 计数器整数工作,并可以用content
显示就像一个字符串。
.red .value::before {
/* in goes an integer variable */
counter-reset: color-value var(--red);
/* out comes a string-like counter value */
content: counter(color-value);
}
基本上,我们在滥用 CSS 计数器将整数转换为字符串用于娱乐。
CSS 范围
在进行级联和继承时,自定义属性遵循与内置属性相同的规则。
这样,您可以在 CSS 变量上使用相同的 CSS 范围内特殊值initial
,Inherit
,unset
和revert
来控制最终放入它们的内容。
结束语
从语法角度来看,CSS 变量是“极其宽松的”。可以放很多种类的东西,但是希望我已经展示了足够多的东西,可以使您对这些可能性有一些了解。