如何像专业人士一样使用 CSS 变量

2025-05-25

如何像专业人士一样使用 CSS 变量

作者:Idorenyin Obong ✏️

与大多数编程语言一样,原生 CSS 现在支持变量,并且将继续支持变量。

如果您对 CSS 有所了解,那么您很可能听说过Sass和 Less 之类的 CSS 预处理器。无论您选择哪种前端框架,您都可能在项目中使用过它们。或者,您可能没有,只是使用普通的 CSS

无论如何,这些预处理器的主要卖点在于你可以像在编程语言中一样使用变量。你可以声明一个变量,赋值,然后在整个文档中使用它,从而简化了维护工作。

在本教程中,我们将通过首先揭秘 CSS 变量,然后构建两个利用变量的简单项目,来简要介绍这个概念。如果你渴望尽快开始行动,可以在 CodePen 上找到这两个项目的代码(这里这里)。

学习本教程需要一些基本的 CSS 知识。事不宜迟,让我们开始吧!

我们将构建什么

为了巩固我们对 CSS 变量的理解,我们将构建两个非常简单的项目。第一个项目将演示如何创建按钮变体。这个概念在 Bootstrap 中很流行,其中某些元素共享 CSS 规则,这些规则赋予它们默认设计,但通过颜色或其他属性进行区分。第二个项目将是一个基于主题的设计——具体来说,是一个由 JavaScript 操作的明暗主题。

LogRocket 免费试用横幅

如何使用 CSS 变量

CSS 变量也称为自定义属性或级联变量,具有多种用例。最常见的用例之一是管理网站,其中许多值与文档中的值相似。这有助于减少重构或更新代码带来的麻烦。

基础知识

要在 CSS 中声明变量,请为变量想出一个名称,然后附加两个连字符 (-) 作为前缀。

element {
  --bg-color: #405580;
}
Enter fullscreen mode Exit fullscreen mode

这里element指的是任何可以访问此 CSS 文件的有效 HTML 元素。

变量名称为bg-color,后跟两个连字符。要访问变量,请使用var()表示法并传入变量名称。

body {
  background-color: var(--bg-color);
}
Enter fullscreen mode Exit fullscreen mode

background-color采用我们之前声明的值bg-color。开发人员通常会在:root文档的元素中声明所有变量。

:root {
  --primary-color: #0076c6;
  --blur: 10px;
}
Enter fullscreen mode Exit fullscreen mode

在这里声明变量将使它们具有全局范围并可供整个文件使用。

CSS 变量继承

与传统 CSS 类似,CSS 变量本质上是级联的,也就是说,它们可以继承。如果没有定义自定义属性,则元素的值将从其父元素继承。

HTML:

<div class="container">
  <span class="container-inner"></span>
  <article class="post">
    <h1 class="post-title">Heading text</h1>
    <p class="post-content">Paragraph text</p>
  </article>
</div>
Enter fullscreen mode Exit fullscreen mode

CSS:

.container {
  --padding: 1rem;
}
.container-inner {
  padding: var(--padding);
}
.post {
  --padding: 1.5rem;
}
.post-content {
  padding: var(--padding);
}
Enter fullscreen mode Exit fullscreen mode

.container-inner和类的填充.post-content会有所不同,因为默认情况下,目标选择器会从其最近的父级继承。在本例中,.post-content选择器从其直接父级 继承填充值.post,其值为 ,1.5rem而不是1rem

后备值和无效值

使用自定义属性时,您可能会引用文档中未定义的自定义属性。您可以指定一个后备值来代替该值。提供后备值的语法仍然是var()符号表示法。在第一个值后添加一个以逗号分隔的值列表。第一个逗号之后的任何内容都将被视为后备值。

:root {
  --light-gray: #ccc;
}

p {
  color: var(--light-grey, #f0f0f0, #f9f9f9) /* No --light-grey, so #f0f0f0 is 
  used as a fallback value */
}
Enter fullscreen mode Exit fullscreen mode

你注意到我拼错了值了--light-gray吗?这会导致值未定义,在这种情况下,浏览器会使用第一个后​​备值。如果由于某种原因找不到后备值,则会使用下一个值,依此类推。如果浏览器找不到任何提供的值,它将使用初始默认颜色。

后备值的另一个用例是当所提供的属性的值无效时。

:root { 
  --text-danger: 16px; 
} 

body { 
  color: var(--text-color); 
} 
Enter fullscreen mode Exit fullscreen mode

在此代码片段中,--text-danger自定义属性的值定义为,这在技术上并没有错。但是,当浏览器用16px的值替换 时,它会尝试使用 的值,而这在 CSS 中并不是有效的 color 属性值。--text-colorvar(--text-color)16px

浏览器会将其视为无效值,并检查颜色属性是否可以被父元素继承。如果可以,则使用该颜色。否则,则使用默认颜色(大多数浏览器中为黑色)。

现在让我们深入研究我们的第一个项目。

项目 1:构建按钮变体

在 Bootstrap 等 CSS 框架中,变量使得跨元素共享基础设计变得更加容易。例如.bg-danger,一个类可以将元素的背景颜色变为红色,并将其自身颜色变为白色。在这个第一个项目中,你将构建类似的内容。

首先创建一个项目文件夹。在终端中,你可以依次运行这些命令。

# create a base project folder
mkdir css-variables-pro 

# change directory to the created folder 
cd css-variables-pro

# create a new folder for the first project
mkdir button-variations

# change directory to the new folder
cd button-variations

# create two files
touch variations.html variations.css
Enter fullscreen mode Exit fullscreen mode

这将创建一个名为 的项目文件夹css-variables-pro。此文件夹将存放您将要构建的两个项目。接下来,创建一个名为 的子文件夹button-variations,其中包含第一个项目的两个文件。

将以下代码片段粘贴到variations.html您创建的文件中。

<!-- css-variables-pro/button-variations/variations.html -->
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <meta http-equiv="X-UA-Compatible" content="ie=edge" />
    <title>CSS Variables - Button Variations</title>
    <link rel="stylesheet" href="variations.css" />
  </head>
  <body>
    <section>
      <div class="container">
        <h1 class="title">CSS Color Variations</h1>
        <div class="btn-group">
          <button class="btn primary">Primary</button>
          <button class="btn secondary">Secondary</button>
          <button class="btn link">Link</button>
          <button class="btn success">Success</button>
          <button class="btn error">Error</button>
        </div>
      </div>
    </section>
  </body>
</html>
Enter fullscreen mode Exit fullscreen mode

这个标记的结构非常标准。注意每个按钮元素都有两个类:第一个btn类和第二个类。btn在本例中,我们将第一个类称为基类,将第二个类称为修饰类。

将此代码片段粘贴到您的variations.css文件中:

/* css-variables-pro/button-variations/variations.css */

* {
 border: 0;
}
:root {
 --primary: #0076c6;
 --secondary: #333333;
 --error: #ce0606;
 --success: #009070;
 --white: #ffffff;
}
/* base style for all buttons */
.btn {
 padding: 1rem 1.5rem;
 background: transparent;
 font-weight: 700;
 border-radius: 0.5rem;
 cursor: pointer;
 outline: none;
}
/* variations */
.primary {
 background: var(--primary);
 color: var(--white);
}
.secondary {
 background: var(--secondary);
 color: var(--white);
}
.success {
 background: var(--success);
 color: var(--white);
}
.error {
 background: var(--error);
 color: var(--white);
}
.link {
 color: var(--primary);
}
Enter fullscreen mode Exit fullscreen mode

该类btn包含所有按钮的基本样式,而各个修饰符类可以访问其颜色,这些颜色是在:root文档级别定义的。这不仅对按钮非常有用,而且对 HTML 中其他可以继承自定义属性的元素也非常有用。

例如,如果您明天觉得自定义属性的值--error太暗,不适合用红色,您可以轻松将其切换为#f00000,然后瞧:所有使用此自定义属性的元素都会通过一次更改更新。我不知道您怎么想,但这对我来说听起来像是减轻压力的方法。

您的第一个项目应该是这样的:

已完成按钮变体项目的屏幕截图

项目 2:构建站点主题

在第二个项目中,我们将构建一个明暗主题。除非用户已将系统设置为暗色主题,否则默认使用明色主题。我们将在页面上创建一个切换按钮,允许用户在主题之间切换。

打开css-variables-pro之前创建的文件夹。在该文件夹中,为第二个项目创建另一个文件夹,并将其命名为theming。或者,您可以使用以下命令:

# create a new folder called theming
mkdir theming
Enter fullscreen mode Exit fullscreen mode

接下来,进入主题文件夹。

cd theming
Enter fullscreen mode Exit fullscreen mode

创建三个新文件。

# create three files namely theme.html, theme.css, and theme.js
touch theme.html theme.css theme.js
Enter fullscreen mode Exit fullscreen mode

这部分涉及一些 JavaScript。首先,打开theme.html并粘贴以下标记。

<!-- theme.html -->
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <meta http-equiv="X-UA-Compatible" content="ie=edge" />
    <title>CSS Variables - Theming</title>
    <link rel="stylesheet" href="theme.css" />
  </head>
  <body>
    <header>
      <div class="container">
        <div class="container-inner">
          <a href="#" class="logo">My Blog</a>
          <div class="toggle-button-container">
            <label class="toggle-button-label" for="checkbox">
              <input type="checkbox" class="toggle-button" id="checkbox" />
              <div class="toggle-rounded"></div>
            </label>
          </div>
        </div>
      </div>
    </header>
    <article>
      <div class="container">
        <h1 class="title">Title of article</h1>
        <div class="info">
          <div class="tags">
            <span>#html</span>
            <span>#css</span>
            <span>#js</span>
          </div>
          <span>1st March, 2020</span>
        </div>
        <div class="content">
          <p>
            Lorem ipsum dolor sit amet consectetur adipisicing elit.
            <a href="#">Link to another url</a> Eius, saepe optio! Quas
            repellendus consequuntur fuga at. Consequatur sit deleniti, ullam
            qui facere iure, earum corrupti vitae laboriosam iusto eius magni,
            adipisci culpa recusandae quis tenetur accusantium eum quae harum
            autem inventore architecto perspiciatis maiores? Culpa, officiis
            totam! Rerum alias corporis cupiditate praesentium magni illo, optio
            nobis fugit.
          </p>
          <p>
            Eveniet veniam ipsa similique atque placeat dignissimos
            quos reiciendis. Odit, eveniet provident fugiat voluptatibus esse
            culpa ullam beatae hic maxime suscipit, eum reprehenderit ipsam.
            Illo facilis doloremque ducimus reprehenderit consequuntur
            cupiditate atque harum quaerat autem amet, et rerum sequi eum cumque
            maiores dolores.
          </p>
        </div>
      </div>
    </article>
    <script src="theme.js"></script>
  </body>
</html>
Enter fullscreen mode Exit fullscreen mode

此代码片段代表一个简单的博客页面,其中包含标题、主题切换按钮、虚拟文章以及指向相应 CSS 和 JavaScript 文件的链接。

现在,打开theme.css文件并粘贴以下内容。

:root {
 --primary-color: #0d0b52;
 --secondary-color: #3458b9;
 --font-color: #424242;
 --bg-color: #ffffff;
 --heading-color: #292922;
 --white-color: #ffffff;
}
/* Layout */
* {
 padding: 0;
 border: 0;
 margin: 0;
 box-sizing: border-box;
}
html {
 font-size: 14px;
 font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen,
  Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif;
}
body {
 background: var(--bg-color);
 color: var(--font-color);
}
.container {
 width: 100%;
 max-width: 768px;
 margin: auto;
 padding: 0 1rem;
}
.container-inner {
 display: flex;
 justify-content: space-between;
 align-items: center;
}

/* Using custom properties */
a {
 text-decoration: none;
 color: var(--primary-color);
}
p {
 font-size: 1.2rem;
 margin: 1rem 0;
 line-height: 1.5;
}
header {
 padding: 1rem 0;
 border-bottom: 0.5px solid var(--primary-color);
}
.logo {
 color: var(--font-color);
 font-size: 2rem;
 font-weight: 800;
}
.toggle-button-container {
 display: flex;
 align-items: center;
}
.toggle-button-container em {
 margin-left: 10px;
 font-size: 1rem;
}
.toggle-button-label {
 display: inline-block;
 height: 34px;
 position: relative;
 width: 60px;
}
.toggle-button-label .toggle-button {
 display: none;
}
.toggle-rounded {
 background-color: #ccc;
 bottom: 0;
 cursor: pointer;
 left: 0;
 position: absolute;
 right: 0;
 top: 0;
 transition: 0.4s;
}
.toggle-rounded:before {
 background-color: #fff;
 bottom: 4px;
 content: '';
 height: 26px;
 left: 4px;
 position: absolute;
 transition: 0.4s;
 width: 26px;
}
input:checked + .toggle-rounded {
 background-color: #9cafeb;
}
input:checked + .toggle-rounded:before {
 transform: translateX(26px);
}
article {
 margin-top: 2rem;
}
.title {
 font-size: 3rem;
 color: var(--font-color);
}
.info {
 display: flex;
 align-items: center;
 margin: 1rem 0;
}
.tags {
 margin-right: 1rem;
}
.tags span {
 background: var(--primary-color);
 color: var(--white-color);
 padding: 0.2rem 0.5rem;
 border-radius: 0.2rem;
} 
Enter fullscreen mode Exit fullscreen mode

此代码片段可分为两个主要部分:布局部分和自定义属性部分。您应该重点关注后者。如您所见,变量已应用于上方的链接、段落、标题和文章元素中。

这种方法背后的想法是,默认情况下,网站使用浅色主题,当选中该框时,浅色主题的值会反转为深色变体。

由于您无法通过 CSS 触发这些站点范围的更改,因此 JavaScript 至关重要。在下一节中,我们将连接在明暗主题之间切换所需的 JavaScript 代码。

或者,您可以使用媒体查询通过 CSS 自动触发更改,prefers-color-scheme以检测用户请求的是浅色主题还是深色主题。换句话说,您可以直接更新网站以使用浅色主题的深色变体。

将以下代码片段添加到您刚刚编写的所有 CSS 代码中。

/* theme.css */
@media (prefers-color-scheme: dark) {
 :root {
  --primary-color: #325b97;
  --secondary-color: #9cafeb;
  --font-color: #e1e1ff;
  --bg-color: #000013;
  --heading-color: #818cab;
 }
}
Enter fullscreen mode Exit fullscreen mode

我们正在监听用户的设备设置,如果他们已经在使用深色主题,则将主题调整为深色。

theme.js通过添加此代码片段来更新文件:

// theme.js
const toggleButton = document.querySelector('.toggle-button');
toggleButton.addEventListener('change', toggleTheme, false);

const theme = {
 dark: {
  '--primary-color': '#325b97',
  '--secondary-color': '#9cafeb',
  '--font-color': '#e1e1ff',
  '--bg-color': '#000013',
  '--heading-color': '#818cab'
 },
 light: {
  '--primary-color': '#0d0b52',
  '--secondary-color': '#3458b9',
  '--font-color': '#424242',
  '--bg-color': '#ffffff',
  '--heading-color': '#292922'
 }
};

function toggleTheme(e) {
 if (e.target.checked) {
  useTheme('dark');
  localStorage.setItem('theme', 'dark');
 } else {
  useTheme('light');
  localStorage.setItem('theme', 'light');
 }
}

function useTheme(themeChoice) {
 document.documentElement.style.setProperty(
  '--primary-color',
  theme\[themeChoice\]['--primary-color']
 );
 document.documentElement.style.setProperty(
  '--secondary-color',
  theme\[themeChoice\]['--secondary-color']
 );
 document.documentElement.style.setProperty(
  '--font-color',
  theme\[themeChoice\]['--font-color']
 );
 document.documentElement.style.setProperty(
  '--bg-color',
  theme\[themeChoice\]['--bg-color']
 );
 document.documentElement.style.setProperty(
  '--heading-color',
  theme\[themeChoice\]['--heading-color']
 );
}

const preferredTheme = localStorage.getItem('theme');
if (preferredTheme === 'dark') {
 useTheme('dark');
 toggleButton.checked = true;
} else {
 useTheme('light');
 toggleButton.checked = false;
}
Enter fullscreen mode Exit fullscreen mode

现在让我们来分析一下网站的当前状态。

用户访问页面。媒体查询prefers-color-scheme会判断用户使用的是浅色主题还是深色主题。如果是深色主题,网站会更新以使用自定义属性的深色变体。假设用户未使用深色主题,或者其操作系统不支持深色主题,浏览器会默认使用浅色主题,用户可以通过勾选或取消勾选来控制该行为。

根据复选框是否选中,useTheme()系统会调用该函数来传入主题变体,并将用户当前的选择保存到本地存储。稍后您将了解为什么要保存它。

函数useTheme()是所有魔法发生的地方。根据传递的主题变量,对theme常量进行查找,并用于在明暗模式之间切换。

难题的最后一部分是保留当前主题,这是通过从本地存储读取上次首选的主题并在用户重新访问网站时自动设置来实现的。

你可能正在想出无数种方法来实现这一点。请随意浏览代码,并根据需要进行尽可能多的更改。

您的第二个项目应该是这样的:

结论

通过构建这些简单的项目,您可以学习如何像专业人士一样使用 CSS 变量。它们的具体内容远不止我解释的,所以您可以随意尝试代码来进一步探索。

CSS 变量有助于简化您构建网站和复杂动画的方式,同时仍允许您编写可重用且优雅的代码。要了解更多信息,请参阅MDN上的文档。


您的前端是否占用了用户的 CPU?

随着 Web 前端日益复杂,资源占用大的功能对浏览器的要求也越来越高。如果您有兴趣监控和跟踪生产环境中所有用户的客户端 CPU 使用率、内存使用率等数据,不妨尝试 LogRocket。

替代文本

LogRocket就像 Web 应用的 DVR,记录 Web 应用或网站中发生的一切。您无需猜测问题发生的原因,而是可以汇总和报告关键的前端性能指标、重放用户会话以及应用程序状态、记录网络请求并自动显示所有错误。

实现 Web 应用程序调试方式的现代化 —开始免费监控。


如何像专业人士一样使用 CSS 变量一文首先出现在LogRocket 博客上。

文章来源:https://dev.to/bnevilleoneill/how-to-use-css-variables-like-a-pro-4c78
PREV
使用 Hooks + Context,而不是 React + Redux
NEXT
如何使用 React 构建管理面板