用CSS变量动态更新React和JavaScript
虽然人们可能很熟悉用SASS之类的东西来使用CSS变量,但自定义属性是在浏览器中使用变量的本地CSS实现。
有三种主要的方法可以用来使用这些自定义变量。其中包括定义双连字符(--)的前缀,说明变量的名称,以及用var关键字作为前缀。在一个元素或选择器上表示它(这将使它只在范围内级联)。
自定义CSS变量在JavaScript和JavaScript框架中使用。
在这篇文章中,我们将学习如何使用基于状态变化而动态更新的CSS自定义属性。这些知识可以帮助人们在变量状态变化时修改JavaScript UI组件属性。
主要收获
- 在React.js这样的JavaScript框架中设置自定义变量。
- 获取所使用变量的属性。
- 看看如何在状态变化和事件中使用自定义变量。
- 使用变量来动态更新组件属性。
- 配置变量,使其随应用程序的状态动态变化。
前提条件
读者需要具备以下条件才能跟上进度。
- 先前的React.js实践经验。
- 有过网页设计的经验。
- 在使用的机器上已经设置了React.js环境。
- 一个好的JavaScript IDE或编辑器。
- 一个稳定的网络连接。
- CSS知识。
如果一切就绪,让我们开始吧。
这些是我们在这个过程中要遵循的步骤。
- 创建一个新的React.js应用程序。
- 添加一个自定义变量来改变React.js的标志颜色。
- 用JavaScript获取一个CSS自定义属性的属性。
- 用JavaScript设置一个CSS自定义属性的值。
- 用自定义CSS属性动态地调整logo的大小。
- 通过更新CSS自定义属性来加快CSS动画的速度。
创建一个新的React应用程序
- 前往项目所在的文件夹位置。
通过在终端上运行下面的命令来创建应用程序。
npx create-react-app my-custom-properties
这将创建一个名为my-custom-properties 的应用程序。
- 打开它并使用下面的命令进行测试运行。
cd my-custom-properties
npm start
- 通过
http://localhost:3000/访问它。 - 如果你使用的是VS Code,请使用
code .命令将其打开。
文件夹结构
该应用程序应该有以下的文件夹结构。
.
├── node_modules
├── public
├── src
│ ├── App.css
│ ├── App.js
│ ├── App.test.js
│ ├── index.css
│ ├── index.js
│ ├── logo.svg
│ ├── reportWebVitals.js
│ └── setupTests.js
├── .gitignore
├── package.json
├── package-lock.json
└── README.md
添加一个自定义变量来改变React标识的颜色
要做到这一点,请遵循下面的步骤。
- 要瞄准用作居中标识图像的SVG文件,将其从
logo.svg文件复制粘贴到App.js文件。在新的p标签中的标题标签下做这件事。将其className设置为App-logo。 - 删除导入图像源的最后一行。这样做使SVG成为一个内联SVG文件。
这两个步骤的结果显示在下面的页眉标签里面。
<header className="App-header">
<p>
{/*Insert the SVG here*/}
<svg className="App-logo" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 841.9 595.3"><g fill="#61DAFB"><path ... ><path d="M520.5 78.1z"/></g></svg>
</p>
<p>
...
</p>
<a>
...
</a>
</header>
- 为了验证它是否使用了内联图像,请删除
logo.svg文件并刷新应用程序。 - 使用浏览器中的检查模式打开网页,首先在页面的任何地方点击右键,然后选择
Inspect选项。
注意到SVG是在下面的标签里面,<g></g> 。

与文本不同,SVG的颜色属性不能用color 属性来访问。相反,它是通过使用fill 属性来引用的,如下图所示。

- 在
App.css文件中,创建一个新的样式,在App-logo类下对SVG应用红色填充,如下图所示。
.App-logo g {
fill: red;
}
这段代码将填充效果应用到应用程序中。
- 打开
index.css文件。在这里定义CSS变量。
使用root 元素,这样变量就可以在整个应用程序中可见。例如,一个变量用来保存颜色属性。
:root{
--logo-color: red;
}
变量的好处是它们使用易于理解的名称,因此可以多次重复使用而不会出错。
要改变变量的范围,请参考它所绑定的元素。组件将取代根的位置。
- 将应用程序的标识设置为依赖颜色属性的设置变量。
在App.css 文件中这样做。
.App-logo g {
fill: var(--logo-color);
}
- 刷新浏览器。徽标没有变化。这一步证明了一切都很好。
- 在回退的情况下,当变量还没有设置或找不到时,可能会出现这种情况,使用以下代码语法来指定另一个选项。
.App-logo g {
fill: var(--logo-color, aqua);
}
通过从应用程序中删除该变量并刷新网页来尝试。一旦重新运行,将应用程序的变量返回到初始状态。
用JavaScript获取CSS自定义属性的属性
要动态地获取变量内部的值,请执行以下操作。
- 在App.js文件中,从React导入
useEffect,如下图所示。
import { useEffect } from "react";
这允许应用程序在React渲染组件的范围之外运行客户端代码。
在App() 函数里面,添加useEffect钩子,抓取变量,并通过[] 第一次运行它。
- 由于在块引号中没有添加任何行为,它可以防止在每次渲染中重新启动应用程序。
这是由于缺乏传递给它的值。
useEffect(() => {
}, []);
- 在其中,创建一个常量,使用
getComputedStyle()函数来获取其样式的值。 - 传递根元素(
document.documentElement)作为参数,以及--logo-color变量。
获取变量的属性值,如下图所示。
const color = getComputedStyle(document.documentElement).getPropertyValue('--logo-color');
console.log(color);
当页面被刷新时,应用程序将在控制台中记录出根元素内的变量值。

试着将颜色从红色改为橙色并刷新页面。
注意,当颜色被改变时,例如黄色,它并没有立即注销,尽管结果已经应用到SVG上。
这是因为useEffect 钩子只在第一个实例上运行。这需要再次刷新页面才能反映出来。
用JavaScript设置CSS自定义属性的值
- 在App.js文件中,在useEffect函数下,创建一个函数,将一个元素的颜色设置为作为参数传递的颜色。
- 它将用作为参数传递的新属性来设置
--logo-color变量中传递的样式属性。
这两个步骤显示在下面的代码中。
function setColor (newColor){
document.documentElement.style.setProperty('--logo-color', newColor);
}
- 删除App.js文件中的以下代码。

用下面的代码代替,该代码创建了三个按钮,可以立即将应用标志的颜色设置为每个按钮中定义的颜色。
<p>
<button onClick={() => setColor('orange')}>orange</button>
<button onClick={() => setColor('blueviolet')}>blueviolet</button>
<button onClick={() => setColor('red')}>red</button>
</p>
这只是一个改变变量值的简单方法。
用一个自定义的CSS属性动态地调整标志的大小
现在,根据实际的输入值动态地改变变量的值呢?
具体做法如下。
- 在
index.css文件中创建另一个变量。它将被命名为--logo-size,它将保存标志的大小。App.css文件中定义了初始的标识尺寸为'40vmin',在App-logo类下的文件中可以看到。
--logo-size: 40vmin;
- 修改一下,这样就可以从变量集中获得标志的高度。
.App-logo {
height: var(--logo-size);
pointer-events: none;
}
- 创建一个范围类型的输入。它的范围是0到100,默认值是
--logo-size。在存放SVG的p标签上面做这个。
<p>
<input name="size" min="0" max="100" type="range" defaultValue="40" onChange={handleOSizeChange}/>
</p>
- 创建一个函数来处理
range类型的输入值的变化。然后它将在每次变化时动态地设置范围输入的当前位置的值。它还将在浏览器控制台中返回当前值。
在setColor() 方法下创建它。
function handleOSizeChange(event) {
console.log(event.currentTarget.value);
document.documentElement.style.setProperty('--logo-size', event.currentTarget.value);
}
- 刷新页面并调整输入范围的大小,看看是否一切正常。当使标志向右或向左方向滑动时,该应用程序将自动增加或减少标志的大小。只要移动范围滑块,这就会自动更新。

通过更新一个CSS自定义属性来加快CSS动画的速度
如果有人想提高每次点击的动画速度呢?那么在一个特定的速度下,它将重置为默认速度。
按照下面的步骤来完成上述工作。
- 创建一个名为
logo-speed的新变量。它应包含先前存储在App-logo类的'animation'属性中的值,找到媒体查询。
--logo-speed: 20s;
- 设置标志使用这个属性。
@media (prefers-reduced-motion: no-preference) {
.App-logo {
animation: App-logo-spin infinite var(--logo-speedTiming) linear;
}
}
- 在App.js文件中添加一个函数,在每次点击时增加存储在*'-logo-速度*'变量中的动画速度。然后它将速度重置为默认速度。
记住,当从变量中获取数值时,它的末尾有一个
s。这使得它很难进行计算。因此,它将被删除,然后再返回。
function onSVGClick() {
const timing = getComputedStyle(document.documentElement).getPropertyValue('--logo-speedTiming').replace('s', '');
let newTiming = timing;
/*Reset point*/
if (newTiming < 0.5){
newTiming = 20;
} else {
newTiming = newTiming / 2;
}
document.documentElement.style.setProperty('--logo-speedTiming', `${newTiming}s`);
}
- 通过包含SVG的段落来定位SVG。直接定位SVG是很麻烦的,要通过段落来定位它。
<p onClick={onSVGClick}>
<svg className="App-logo" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 841.9 595.3">
<g fill="#61DAFB">
...
</g>
</svg>
</p>
- 重新运行应用程序,以恒定的速度点击标志。
徽标的速度将不断加快,直到达到一个重置点。
应用程序将如图所示运行。

在上述函数中,变量已经被动态地获取,并在每个事件变化中更新。
上面所有的事情,如改变颜色、大小和应用程序中的旋转速度,都是CSS变量如何动态更新以创造出色效果的例子。
这让我们了解到如何以一种非常直观的方式在应用程序中实现它,以满足React或JavaScript应用程序中的需求。
结语
恭喜你走到这一步,这意味着我们已经学到了以下内容。
- 如何在React这样的JavaScript框架中设置自定义变量。
- 获取所使用变量的属性。
- 知道如何在状态变化和事件中使用自定义变量。
- 如何使用变量来动态更新组件属性。
- 如何配置变量,使其随应用状态动态变化。