CSS 变量初学者指南(又名 CSS 自定义属性)

已发表: 2022-04-10

在成为标准之前很久就在 CSS 愿望清单上的一个特性是 CSS 变量,在规范中正式称为 CSS 自定义属性。 CSS 变量已经成为标准近十年了,所有现代浏览器都支持它们已有一段时间了。

所有开发人员都应该使用此功能,因为它可以节省大量编码和维护时间。 在本教程中,我将介绍 CSS 变量语法的基础知识,然后我将介绍使用 CSS 变量(或自定义属性)的一些细节以及一些实际用例。

CSS 变量指南

目录:

  • 预处理器中的 CSS 变量
  • 原生 CSS 中的变量(自定义属性)#
  • 为什么是“自定义属性”? #
  • CSS 变量在哪里定义? #
  • 关于 CSS 变量的技术说明 #
  • 理解var()函数
  • 使用带有calc()的 CSS 变量 #
  • CSS 变量的技巧 #
#CSS 变量初学者指南(附实际示例)️
点击推文

预处理器中的 CSS 变量

CSS 预处理器使用 CSS 变量已有 10 多年了。 我不会在这里详细介绍这些选项,但我认为了解每个流行的预处理器库如何使用变量会很有帮助。

在 Sass(或 SCSS)中,你声明变量如下:

$theme-color: #cccccc; .element1 { border: 1 px solid $theme-color; } .element2 { background-color: $theme-color; }
代码语言: PHP ( php )

注意美元符号 ($)。 第一行是变量及其值的声明。 下面的两个块是稍后在样式表中使用的变量示例。

Less.js 中的变量使用@符号:

@linkcolor: firebrick; a,.link { color: @linkcolor; }

在 Stylus 中,变量如下所示:

font- default = 14 px body font-size font- default
代码语言: JavaScript javascript

如果您想进一步研究使用这些第三方技术的变量,您可以查阅上面显示的每个预处理器的各个文档部分。

本机 CSS 中的变量(自定义属性)

这将我们带到 CSS 变量或自定义属性,因为它们在 CSS 规范中定义。 要在纯 CSS 中声明变量,请在您为变量或属性选择的自定义名称前放置两个连字符,然后使用var()函数将该值放置在您想要的任何位置:

:root { --main : #030303 ; --accent : #5a5a5a ; } .container { color : var (--main); } .footer { border-color : var (--main); } .sidebar { color : var (--accent); } .module { border-color : var (--accent); }
代码语言: CSS css

在这个例子中,我定义了两个 CSS 变量: --main--accent 。 然后我在两个不同的元素上使用了每个 CSS 变量,展示了它们带来的灵活性。

与任何编程语言中的变量一样,这允许您在一个地方声明一个变量。 如果您以后想在样式表中的任何地方更改该值,只需更改原始声明即可,它将应用于您使用该变量的所有位置。

为什么是“自定义属性”?

在日常对话中,开发人员经常将此功能称为“CSS 变量”,这与预处理器和编程语言对同一功能的引用方式一致。 但从严格的技术角度来看,这些并不是真正的“变量”,而是自定义属性

它们与 CSS 中的任何预定义属性具有相同的语法,除了出现在属性名称前面的两个破折号。 这两个破折号允许 CSS 作者使用任何有效的破折号标识符,而不必担心与常规 CSS 属性冲突。

该规范解释说,单独的两个破折号是无效的(显然保留供将来使用)并且 CSS 永远不会赋予任何有效的破折号标识符以用作作者定义的自定义属性之外的意义。

与常规 CSS 属性不同,自定义属性区分大小写。 这意味着 --main- --main-color--Main-Color不同。 要包含在自定义属性名称中的有效字符是字母、数字、下划线和连字符。

CSS 变量在哪里定义?

正如您在我上面提供的示例中所看到的,您经常会看到直接在 HTML 文档或影子 DOM 的根元素上定义的 CSS 自定义属性。 :root伪类选择器完成了这一点。

:root { --main : #030303 ; --accent : #5a5a5a ; }
代码语言: CSS css

但是 CSS 变量并不仅限于在根元素上定义,在其他地方定义它们通常是有益的。 通常选择:root选择器,因为它总是针对 DOM 树中最上面的元素(无论是完整文档还是影子 DOM)。

在大多数情况下,您可以通过在html元素(它是 HTML 文档中的根元素)甚至是body元素上定义自定义属性来获得相同的结果。 使用:root可以让代码更加面向未来(例如,如果规范有一天添加一个新元素作为根,CSS 将保持不变),我想还允许样式表应用于不同类型的文档有不同的根元素。

例如,以下代码将限制您的自定义属性仅在.sidebar元素中使用:

.sidebar { --main : #030303 ; --accent : #5a5a5a ; }
代码语言: CSS css

出于演示目的,您经常会看到在:root上定义的变量,但您可以在任何实际可行的地方使用它们。 事实上,许多开发人员建议在初始开发期间将它们设置在 DOM 树中较低的位置以用于较小的模块,然后在您创建范围更大的值时逐步向:root方向努力。

关于 CSS 变量的技术说明

除了能够应用于任何元素之外,CSS 变量还相当灵活且易于处理。

以下是一些值得注意的事情:

  • 它们通过常规的 CSS 继承和级联规则解决
  • 您可以在媒体查询和其他条件规则中使用它们
  • 您可以在元素的style属性中定义它们
  • 可以使用 CSS 对象模型的功能读取或设置它们。

同样值得注意的是,您实际上可以嵌套 CSS 变量。 请注意以下示例:

:root { --main-color : lightblue; --new-color : var (--main-color); } body { background : var (--new-color); }
代码语言: CSS css

请注意,我已经定义了一个--main-color变量,然后我使用相同的变量名称作为以下 CSS 变量的值。

您也可以在 CSS 变量值中使用!important关键字,但这只会将“重要性”应用于与其他变量定义相关的变量本身,而不是应用于文档中一个或多个元素的值。 如果这令人困惑,这里有一个例子:

:root { --main-color : lightblue !important ; --main-color : orange; } body { background : var (--main-color); }
代码语言: CSS css

在上面的示例中,背景颜色将是“浅蓝色”,尽管橙色稍后出现在变量定义中。 但是body元素上的背景值本身并不重要。

CSS 变量还可以包含 CSS 范围的关键字值,例如initialinheritunset ,但all属性不会影响 CSS 变量(即它们不会被重置)。

理解var()函数

您已经在本 CSS 变量教程的一些典型示例中看到了var()函数。 但是var()的内容比我目前所介绍的要多。

首先, var()函数只在一个值中有效; 属性名称或选择器不能使用 CSS 变量。 此外,媒体查询值不能使用 CSS 变量(例如,@media @media (max-width: var(--my-var))无效)。

var()函数有两个参数:

  • 要包含的自定义属性的名称
  • 自定义属性无效时的后备值

这是第二个参数生效的示例:

:root { --main-colour : lightgreen; } body { background : var (--main-color, #ccc); }
代码语言: CSS css

请注意,在上面的代码中,我使用英国或加拿大单词“color”拼写了初始变量名称,但是当我使用该变量时,我合并了美国拼写“color”。 这使得变量在技术上无效,因此纯灰色 ( #ccc ) 背景改为生效。

另请注意,备用值可以包含自己的逗号。 因此,例如,如果您的后备是字体堆栈,这将是定义它的有效方法:

:root { --main-font : Helvetica, Arial, sans-serif; } body { font-family : var (--main-type, "Courier New" , Consolas, monospace); }
代码语言: CSS css

再次注意我的变量有一个缺陷,声明了一个未知的--main-type而不是--main-font 。 这会触发备用值,它是备用字体堆栈。 因此,第一个逗号之后的所有内容(甚至包括任何其他逗号)都是备用值。

将 CSS 变量用于局部变量

当定义一个 CSS 变量时,它持有的值本身不必是一个有效的 CSS 值; 它可以是可用作完整值的一部分的部分值。

例如,您可以分解字体堆栈:

:root { --main-font : "Franklin Gothic" ; --fallback-font : Gill Sans; --generic-font : sans-serif; } body { font-family : var (--main-font), var (--fallback-font), var (--generic-font); }
代码语言: CSS css

在这种情况下,每个变量值都独立工作,但它证明了这一点。 让我们尝试一个使用rgba()颜色符号的更人为的示例:

:root { --rgba-red : 25 ; --rgba-green : 50 ; --rgba-blue : 105 ; --rgba-opacity : 0.4 ; } body { background : rgba (var(--rgba-red), var (--rgba-green), var (--rgba-blue), var (--rgba-opacity)); }
代码语言: CSS css

您可以看到这可能有多么有用,允许您从本质上动态地“构建”值。

通过calc()使用 CSS 变量

将 CSS 变量合并到项目中的一种有用方法是与calc()函数结合使用。 您可能知道, calc()允许您在值内执行计算。 所以你可以做这样的事情:

.element { width : calc ( 100% - 100px ); }
代码语言: CSS css

CSS 自定义属性允许您将calc()提升到一个新的水平,例如使用预定义的大小。 Ahmad Shadeed 描述了类似的东西,这里有一个例子:

:root { --size : 240 ; } .module { width : calc (var(--size) * 1px ); } .module-small { --size : 360 ; } .module-medium { --size : 720 ; } .module-large { --size : 1080 ; }
代码语言: CSS css

有了这个,我可以在媒体查询中使用.module.module-*规则集,允许我有条件地针对特定视口大小或其他媒体功能显示这些样式。 小/中/大模块将具有与主模块相同的类,但仅根据需要覆盖模块大小。 在上面的示例中,大小的初始240值作为一种默认值,但我也可以将240px作为var()中的第二个参数传递以作为后备。

CSS 变量的技巧

多年来,一些开发人员分享了使用 CSS 变量的技巧和窍门。 由于这主要是初学者教程,因此我不会在这里详细展开这些内容,但这里有一些简要说明:

  • 正如我之前提到的,您可以在内联样式中使用 CSS 变量,例如纵横比框。
  • 空格字符是 CSS 变量的有效值,它允许您执行开/关技巧(例如,对于暗模式之类的东西),您可以在 Lea 的帖子中阅读。
  • 您不能在内联样式中编写悬停样式,但您可以使用 CSS 变量来解决这个问题。
  • CSS 变量有助于更轻松地创建多色 SVG,如此处所述。
  • 您可以使用 CSS 变量构建实用且可维护的设计系统和主题,本文将详细介绍
  • 如 Michelle Barker 所述,您可以使用 CSS 变量通过网格布局功能构建更高效且可维护的网格。
转到顶部

结论

CSS 变量,或 CSS 自定义属性,现在已经可以使用了,超过 90% 的全球使用中的浏览器都支持这个方便的功能。 我希望对基础知识和语法的讨论能鼓励您在最新项目中考虑 CSS 变量(如果您还没有这样做的话)。

如果您对 CSS 变量的使用仅限于某些全局主题颜色,那么本教程可能会启发您更多地使用它们,并且可能会想出一些您自己的技巧。

现在您已经完成了 CSS 变量,请查看我们的其他一些指南:

  • CSS 网格布局
  • Parcel.js 简介
  • CSS flexbox 教程
  • 适合初学者的 Webpack
  • 面向初学者的微交互教程

如果您对此 CSS 变量教程有任何疑问,请随时在下面的评论中提交。

您需要了解的有关#CSS 变量的所有信息(附实际示例)️
点击推文

不要忘记加入我们关于加快 WordPress 网站速度的速成课程。 通过一些简单的修复,您甚至可以将加载时间减少 50-80%:

现在订阅图片

Chris Fitzgerald 和 Karol K. 的布局和演示。