[译]你能在CSS变量中放什么?

191 阅读7分钟

原文链接:codersblock.com/blog/what-c… 作者:Will

CSS变量(也称为CSS自定义属性)可以保存各种东西。有些事情对我来说并不明显,这就是为什么我决定写这篇文章。

明确地说,这篇文章的重点是你可以在CSS变量中放什么——以及接近尾声的动画演示,因为我忍不住。如果您正在寻找使用CSS变量的更广泛的指导,还有其他很棒的文章。

img

单位值和数学知识

让我们从简单的开始。将带有单位的数值放入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);}

还有一些自定义标识符指向你定义和命名的东西,比如动画名称或网格区域,如下所示。

:root {  --layout-position: center-stage;}body {  grid-template-areas: 'left center-stage right';}main {  grid-area: var(--layout-position);}

Strings

伪元素使用内容属性来显示内容。这些内容可以是几种不同的东西,但通常是文本字符串。

以下CSS显示使用字符串变量填充的内容。您还可以看到如何将字符串变量与其他字符串连接起来,以及如何使用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变量也可以保存图像。图像也可以在内容中显示,但是在背景图像中看到它们可能更熟悉。

: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变量可以用作速记中的单个值,也可以用作整个速记本身。下面的两个容器元素将具有相同的填充。

: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;}

一些属性,如背景和框阴影,可以列出一些东西。您可以将CSS变量用作列表中的单个项目、列表的子列表或整个列表。

这里有几个混合框影子列表和CSS变量的例子。我还偷偷加入了一个例子,将颜色列表放入CSS变量中,用于线性渐变(),因为你也完全可以这样做!

/*  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));}

动画带来一切

您可以将动画值放入CSS变量中吗?答案是:这很复杂!

默认情况下,大多是没有。一些浏览器将显示从开始值到结束值的单个离散跳跃。有些浏览器什么都不会做。不管怎样,你都不会得到任何平滑的插值动画。

问题是,你的浏览器不知道如何动画你的虚构变量。但是好消息!您可以通过属性和值API解决这个问题。它是胡迪尼的一部分,目前在铬、边缘和歌剧中工作,预计会有更多的浏览器加入。

下面是它的工作原理。首先,声明自定义属性。

@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(我们声明的初始值)到255,然后再回来。这些值在: root元素上是动态的,所有子元素都可以使用它们,因为我们用继承: true声明了变量。

.swatch {  background-color: rgb(var(--red), var(--green), var(--blue));}

因此,我们有3个独立的动画CSS变量,它们通过rgb()组合在一起,创建一个不断变化的背景颜色。没有JavaScript。整洁!

这个演示实际上有很多内容。这三个动画CSS变量(--red,--green,--blue)为多个动画提供了动力。让我们把它分解一下。

首先,大RGB色板。我们已经谈过这个了。

第二,指标在彩条上上下移动。这些是通过将CSS变量转换为负px值来定位的。例如,这是红色的。

.red .indicator {  transform: translateY(calc(var(--red) * -1px));}

第三,彩条下显示的数字。这个很有趣。如前所述,您可以使用内容来显示字符串,但这不适用于我们的整数变量。然而,CSS计数器使用整数值,可以带内容的字符串一样显示。

.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-Wide值

在级联和继承方面,自定义属性遵循与内置属性相同的规则。因此,您可以在CSS变量上使用相同的特殊CSS范围的初始值、继承值、设置值和还原值来控制最终放入其中的内容。

再见

从语法的角度来看,CSS变量是非常允许的”。你肯定有更多类型的东西可以放在里面,我还没有具体介绍过,但希望我已经展示了足够多的东西,让你对可能性有一些看法。另外,我们还可以玩动画颜色,所以很有趣。