先有问题再有答案
css变量设计的目的是什么?css变量如何声明与使用?该如何理解变量的作用域?css变量的作用域有什么特点?有人说css变量是css与js的桥梁 这个理解对嘛?
设计目的
- 提高代码的可维护性:通过定义变量,可以将常用的值(如颜色、字体大小等)集中管理,便于维护和修改。
- 增强灵活性:变量可以在多个地方重复使用,减少代码冗余。
- 支持动态样式:CSS 变量可以通过 JavaScript 动态修改,从而实现动态样式变化。
- 模块化开发:通过局部变量,可以实现模块化的样式管理,避免全局污染。
使用方式
- 声明 CSS 变量
CSS 变量以
--开头,定义选择器中。
:root {
--primary-color: #3498db;
--font-size: 16px;
}
- 使用 CSS 变量
通过
var()函数使用 CSS 变量。
body {
color: var(--primary-color);
font-size: var(--font-size);
}
变量作用域
CSS 变量具有作用域,分为全局变量和局部变量。
全局变量
定义在 :root 中的变量是全局的,可以在整个文档中使用。
:root {
--global-color: #2ecc71;
}
body {
color: var(--global-color);
}
局部变量
局部变量可以在任何选择器中定义,例如类选择器、ID 选择器或元素选择器。
局部变量的作用域仅限于定义它的选择器及其子元素。
如果在其他选择器中使用未定义的局部变量,则不会生效。
<div class="container">
<p>这是一个段落。</p>
</div>
<div class="another-container">
<p>这是另一个段落。</p>
</div>
.container {
--local-color: #e67e22;
}
.container p {
color: var(--local-color); /* 生效 */
}
.another-container p {
color: var(--local-color); /* 不生效,因为 --local-color 未在 .another-container 中定义 */
}
CSS 变量遵循 CSS 的优先级规则。
如果同一个变量在多个作用域中定义,离目标元素最近的定义会生效。
<div class="container">
<p>这是一个段落。</p>
<div class="inner-container">
<p>这是内部段落。</p>
</div>
</div>
.container {
--local-color: #e67e22;
}
.inner-container {
--local-color: #3498db;
}
.container p {
color: var(--local-color); /* 外部段落颜色为 #e67e22 */
}
.inner-container p {
color: var(--local-color); /* 内部段落颜色为 #3498db */
}
局部变量的模块化开发.
局部变量非常适合用于模块化开发,每个模块可以定义自己的变量,避免全局污染。
<div class="module-a">
<p>模块 A 的段落。</p>
</div>
<div class="module-b">
<p>模块 B 的段落。</p>
</div>
.module-a {
--local-color: #e67e22;
}
.module-a p {
color: var(--local-color);
}
.module-b {
--local-color: #3498db;
}
.module-b p {
color: var(--local-color);
}
变量的默认值
在使用 var() 函数时,可以为变量提供默认值。如果变量未定义,则使用默认值。
.container {
/* --local-color 未定义 */
}
.container p {
color: var(--local-color, #e67e22); /* 使用默认值 #e67e22 */
}
css&js的桥梁
CSS 变量可以被视为 CSS 与 JavaScript 之间的桥梁。通过 JavaScript 动态修改 CSS 变量,可以实现许多动态样式变化的能力。
js传值给css实现动态变化
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>CSS 变量与 JS 交互</title>
<style>
:root {
--primary-color: #3498db;
}
body {
background-color: var(--primary-color);
transition: background-color 0.5s;
}
button {
margin-top: 20px;
}
</style>
</head>
<body>
<button id="changeColor">改变背景颜色</button>
<script>
const button = document.getElementById('changeColor');
const root = document.documentElement;
button.addEventListener('click', () => {
const newColor = '#' + Math.floor(Math.random() * 16777215).toString(16);
root.style.setProperty('--primary-color', newColor);
});
</script>
</body>
</html>
点击按钮时,js世界的变量通过注入css变量的方式 动态改变了css的值,实现背景颜色会随机变化。
与animation配合实现强大的动画能力
将一个矩形 通过animation动画移动到一个指定距离嘛 距离是动态获取的可能是50px 可能是200px具体值不定。如果我们想使用animation的keyframes能力 如何实现这个功能?
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>矩形移动动画</title>
<style>
#rectangle {
width: 100px;
height: 80px;
background-color: red;
position: absolute;
top: 0;
left: 0;
}
.btn {
margin-top: 100px;
}
@keyframes move {
20% {
left: 30px;
}
100% {
/* 使用 CSS 变量动态设置终点 */
left: var(--target-distance);
}
}
</style>
</head>
<body>
<div id="rectangle"></div>
<button id="moveButton">移动矩形</button>
<button class="btn" id="changeButton">切换状态</button>
<script>
// 获取矩形元素和按钮
const rectangle = document.getElementById('rectangle');
const moveButton = document.getElementById('moveButton');
const changeButton = document.getElementById('changeButton');
function getTargetDistance() {
const distances = [200, 300];
return distances[Math.floor(Math.random() * distances.length)] + 'px';
}
// 移动矩形
function moveRectangle() {
// 获取目标距离
const targetDistance = getTargetDistance();
// 设置 CSS 变量
rectangle.style.setProperty('--target-distance', targetDistance);
// 应用动画
rectangle.style.animation = 'move 5s forwards';
}
let curState = 'running'
function changeAni() {
if (curState === 'running') {
curState = 'paused';
} else {
curState = 'running';
}
rectangle.style.animationPlayState = curState;
}
// 绑定按钮点击事件
moveButton.addEventListener('click', moveRectangle);
changeButton.addEventListener('click', changeAni);
</script>
</body>
</html>
如上代码 通过css变量我们实现了动画参数动态变化的能力。
而且还可以复用animation动画提供给我们的暂停 重运行的能力。
也避免了过多js的操作导致的性能风险。具体可以参考这里raf:写动画我可能没那么合适...
这也是为什么我们要使用animation动画的原因。