🧩 一、CSS变量的基础语法
CSS 变量的语法形式是:
:root {
--main-color: #3498db;
--font-size-large: 18px;
}
这里:
-
变量名:必须以
--
开头,例如--main-color
-
定义:通常定义在
:root
选择器中(代表全局) -
使用:通过
var()
函数调用button {
color: var(--main-color);
font-size: var(--font-size-large);
}
📘 二、作用域规则(scope)
CSS 变量是 基于层级继承(cascade)和作用域的:
:root {
--text-color: black;
}
.dark-theme {
--text-color: white;
}
p {
color: var(--text-color);
}
结果:
-
普通页面下:
p
的文字颜色是黑色。 -
如果
p
在.dark-theme
元素里,则颜色变成白色。
➡️ 变量可以在局部覆盖全局值。
🧮 三、提供默认值
var()
可以指定 备用值(fallback),当变量未定义时使用:
p { color: var(--text-color, #333); }
如果
--text-color
未定义,则使用#333
。
🧱 四、变量的动态修改(非常强大🔥)
CSS 变量的最大优势之一:
它们能被 JavaScript 动态修改,立即生效,无需重新渲染 DOM。
:root {
--theme-color: #4caf50;
}
button {
background-color: var(--theme-color);
}
document.documentElement.style.setProperty('--theme-color', '#e91e63');
✅ 页面上所有引用 --theme-color
的地方颜色都会实时变化。
🌈 五、常见实用场景
1️⃣ 主题切换(明亮 / 暗黑模式)
:root {
--bg-color: #fff;
--text-color: #000;
}
[data-theme='dark'] {
--bg-color: #121212;
--text-color: #fff;
}
body {
background-color: var(--bg-color);
color: var(--text-color);
}
JS 动态切换:
document.documentElement.setAttribute('data-theme', 'dark');
2️⃣ 组件复用(例如按钮样式)
.button {
--btn-bg: #007bff;
--btn-color: white;
background: var(--btn-bg);
color: var(--btn-color);
}
.button.secondary {
--btn-bg: #6c757d;
}
➡️ 不用重复写 .button-secondary { background: ... }
。
3️⃣ 响应式尺寸控制
:root {
--space: 8px;
}
.container {
padding: calc(var(--space) * 2);
}
@media (min-width: 768px) {
:root {
--space: 16px;
}
}
当屏幕变大,--space
自动变大,所有基于它的布局一起调整。
4️⃣ 与动画结合
:root {
--rotate-deg: 0deg;
}
.box {
transform: rotate(var(--rotate-deg));
transition: transform 0.3s ease;
}
JS 控制动画效果:
document.documentElement.style.setProperty('--rotate-deg', '45deg');
5️⃣ 与渐变 / 颜色组合使用
:root {
--start-color: #ff9a9e;
--end-color: #fad0c4;
}
.hero {
background: linear-gradient(45deg, var(--start-color), var(--end-color));
}
轻松实现 主题渐变变化。
⚙️ 六、计算与嵌套使用
CSS 变量可以与 calc()
、var()
嵌套使用:
:root {
--base-size: 10px;
--scale: 2;
}
.box {
width: calc(var(--base-size) * var(--scale));
}
或者嵌套定义:
:root {
--color-primary: #007bff;
--button-bg: var(--color-primary);
}
🚫 七、注意事项
注意点 | 说明 |
---|---|
❌ 无法在媒体查询外计算(例如 var() 不能用于 @media 条件) |
如:@media (min-width: var(--bp)) 不支持 |
⚙️ 不同于预处理器变量(如 SCSS $color ) |
CSS变量是运行时变量,而 SCSS 是编译时变量 |
💡 支持层叠继承 | 会被父级作用域覆盖 |
🧩 可以在任意选择器中定义 | 不必只放在 :root |
🧠 八、与 SCSS/SASS 对比
对比点 | CSS 变量 | SCSS 变量 |
---|---|---|
定义时机 | 运行时(浏览器实时解析) | 编译时(打包阶段) |
动态修改 | ✅ 可以用 JS 修改 | ❌ 只能在编译前固定 |
支持作用域 | ✅ 可继承和局部覆盖 | ❌ 全局(除非嵌套限定) |
浏览器支持 | ✅ 现代浏览器全支持 | 不需要支持(预编译) |
💡 九、进阶技巧:动态主题示例
:root {
--primary: #3498db;
--secondary: #2ecc71;
--font: 'Segoe UI', sans-serif;
}
[data-theme='dark'] {
--primary: #9b59b6;
--secondary: #f39c12;
}
body {
background: var(--secondary);
color: var(--primary);
font-family: var(--font);
}
JS 控制:
function toggleTheme() {
const current = document.documentElement.getAttribute('data-theme');
document.documentElement.setAttribute('data-theme', current === 'dark' ? 'light' : 'dark');
}
🧾 十、总结
能力 | 描述 |
---|---|
✅ 定义 | --变量名: 值 |
✅ 使用 | var(--变量名[, 默认值]) |
✅ 局部覆盖 | 支持继承作用域 |
✅ 动态修改 | JS 实时更改 |
✅ 与 calc / linear-gradient 等结合 | 强大灵活 |
⚡ 典型用途 | 主题切换、响应式间距、动画参数、组件复用等 |
开关css实现一
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>细腻动画开关(无竖条)</title>
<style>
:root {
--switch-width: 80px; /* 开关宽度 */
--switch-height: 36px; /* 开关高度 */
--toggle-size: 30px; /* 按钮尺寸 */
--bg-color-off: #ffffff; /* 关闭背景(白) */
--bg-color-on: #4cd964; /* 开启背景(绿) */
--border-color-off: #e0e0e0; /* 关闭边框(浅灰,避免生硬) */
--border-color-on: #3bc053; /* 开启边框(深绿,增加层次) */
--shadow-off: 0 2px 6px rgba(0,0,0,0.05); /* 关闭阴影(柔和) */
--shadow-on: 0 2px 6px rgba(76, 217, 100, 0.25); /* 开启阴影(透绿) */
--toggle-shadow-off: 0 2px 4px rgba(0,0,0,0.15); /* 按钮关闭阴影 */
--toggle-shadow-on: 0 2px 4px rgba(76, 217, 100, 0.15); /* 按钮开启阴影 */
--transition-base: 0.4s cubic-bezier(0.34, 1.56, 0.64, 1); /* 主缓动(柔和加速) */
--transition-toggle: 0.35s cubic-bezier(0.25, 1, 0.5, 1); /* 按钮缓动(更丝滑) */
--border-radius: 18px; /* 开关圆角(高度一半,保证两端圆) */
}
/* 开关容器(确保整体点击区域) */
.switch {
position: relative;
display: inline-block;
width: var(--switch-width);
height: var(--switch-height);
margin: 50px;
cursor: pointer;
}
/* 隐藏原生复选框 */
.switch input {
opacity: 0;
width: 0;
height: 0;
}
/* 开关背景(分层动画:背景色+边框+阴影) */
.toggle-bg {
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-color: var(--bg-color-off);
border: 1px solid var(--border-color-off);
border-radius: var(--border-radius);
box-shadow: var(--shadow-off);
/* 背景/边框/阴影分开过渡,避免同步生硬 */
transition:
background-color var(--transition-base),
border-color var(--transition-base),
box-shadow var(--transition-base);
}
/* 开关按钮(核心动画:移动+阴影+轻微缩放) */
.toggle-btn {
position: absolute;
top: calc((var(--switch-height) - var(--toggle-size)) / 2);
left: 3px;
width: var(--toggle-size);
height: var(--toggle-size);
background-color: white;
border-radius: 50%;
box-shadow: var(--toggle-shadow-off);
/* 按钮动画:移动为主,阴影/缩放为辅 */
transition:
transform var(--transition-toggle),
box-shadow var(--transition-base),
scale var(--transition-base);
transform: translateX(0) scale(1);
}
/* 选中状态:分元素触发动画 */
.switch input:checked ~ .toggle-bg {
background-color: var(--bg-color-on);
border-color: var(--border-color-on);
box-shadow: var(--shadow-on);
}
.switch input:checked ~ .toggle-btn {
transform: translateX(calc(var(--switch-width) - var(--toggle-size) - 6px));
box-shadow: var(--toggle-shadow-on);
scale: 1.02; /* 开启时轻微放大(0.02倍,不突兀) */
}
/* 点击反馈:弱化缩放,避免生硬跳动 */
.switch:active .toggle-btn {
scale: 0.98; /* 点击时缩小(0.02倍,柔和反馈) */
}
.switch input:checked:active .toggle-btn {
transform: translateX(calc(var(--switch-width) - var(--toggle-size) - 6px));
scale: 0.98;
}
</style>
</head>
<body>
<label class="switch">
<input type="checkbox">
<span class="toggle-bg"></span>
<span class="toggle-btn"></span>
</label>
</body>
</html>
开关css实现二
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>CSS变量实现iOS风格开关</title>
<style>
/* ===== 全局变量(只改这些就能改变样式) ===== */
:root {
--switch-width: 60px; /* 开关宽度 */
--switch-height: 30px; /* 开关高度 */
--switch-bg-off: #ccc; /* 关闭时背景 */
--switch-bg-on: #4caf50; /* 开启时背景 */
--knob-color: #fff; /* 滑块颜色 */
--transition-speed: 0.3s; /* 动画时间 */
}
body {
font-family: "Segoe UI", sans-serif;
background: #f5f5f5;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
height: 100vh;
gap: 30px;
}
h2 {
color: #333;
margin-bottom: 10px;
}
/* ===== 开关容器 ===== */
.switch {
position: relative;
display: inline-block;
width: var(--switch-width);
height: var(--switch-height);
}
/* 隐藏原始checkbox */
.switch input {
opacity: 0;
width: 0;
height: 0;
}
/* ===== 滑动条 ===== */
.slider {
position: absolute;
cursor: pointer;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-color: var(--switch-bg-off);
border-radius: var(--switch-height);
transition: background-color var(--transition-speed);
}
/* ===== 滑块(小圆点) ===== */
.slider::before {
content: "";
position: absolute;
height: calc(var(--switch-height) - 6px);
width: calc(var(--switch-height) - 6px);
left: 3px;
bottom: 3px;
background-color: var(--knob-color);
transition: transform var(--transition-speed);
border-radius: 50%;
}
/* ===== 开启状态:用:checked控制 ===== */
input:checked + .slider {
background-color: var(--switch-bg-on);
}
/* 滑块移动到右侧 */
input:checked + .slider::before {
transform: translateX(calc(var(--switch-width) - var(--switch-height)));
}
/* 悬浮微亮效果 */
.slider:hover {
filter: brightness(1.1);
}
</style>
</head>
<body>
<h2>CSS 变量实现的 iOS 风格开关</h2>
<label class="switch">
<input type="checkbox" id="toggle" />
<span class="slider"></span>
</label>
</body>
</html>