分类
标签
API设计 BEM Core Web Vitals CSRF CSS CSS-in-JS CSS变量 Flexbox Grid HTTP HTTP-2 HTTP-3 HTTPS JavaScript Less RESTful Sass SSL-TLS Stylus WebSocket Web安全 Web性能 XSS 主题切换 全双工通信 前端 前端优化 前端安全 前端工程化 前端开发 前端架构 动画 后端开发 响应式设计 团队协作 媒体查询 子网格 实时通信 容器查询 层叠层 布局 性能优化 接口规范 架构设计 模块化 渲染性能 现代CSS 用户体验 移动优先 组件库 缓存策略 网络 网络协议 网络安全 网络请求 自定义属性 认证授权 设计令牌 设计系统 过渡 预处理器 颜色函数
1407 字
7 分钟
CSS 变量与自定义属性完全指南
CSS 变量与自定义属性完全指南
概述
CSS 自定义属性(CSS Variables)是 CSS3 的重要特性,允许开发者定义可重用的值并在整个文档中使用。
基础用法
1. 定义与使用
/* 定义变量 */
:root {
--primary-color: #3498db;
--secondary-color: #2ecc71;
--font-size-base: 16px;
--spacing-unit: 8px;
}
/* 使用变量 */
.element {
color: var(--primary-color);
font-size: var(--font-size-base);
margin: calc(var(--spacing-unit) * 2);
}
/* 变量回退值 */
.element {
color: var(--custom-color, #333); /* 如果 --custom-color 未定义,使用 #333 */
}
2. 作用域
/* 全局变量 */
:root {
--global-color: #333;
}
/* 局部变量 */
.container {
--local-color: #666;
}
/* 组件级变量 */
.button {
--button-bg: #007bff;
background-color: var(--button-bg);
}
.button.primary {
--button-bg: #0056b3; /* 覆盖父级变量 */
}
实战应用
1. 主题切换
/* 定义主题变量 */
:root {
/* 亮色主题 */
--bg-color: #ffffff;
--text-color: #333333;
--primary-color: #007bff;
--border-color: #dee2e6;
}
[data-theme="dark"] {
/* 暗色主题 */
--bg-color: #1a1a1a;
--text-color: #f8f9fa;
--primary-color: #4dabf7;
--border-color: #495057;
}
/* 应用主题 */
body {
background-color: var(--bg-color);
color: var(--text-color);
transition: background-color 0.3s ease, color 0.3s ease;
}
.button {
background-color: var(--primary-color);
border: 1px solid var(--border-color);
}
/* JavaScript 切换主题 */
document.documentElement.setAttribute('data-theme', 'dark');
2. 响应式设计
/* 定义响应式变量 */
:root {
--font-size: 16px;
--spacing: 20px;
--columns: 1;
}
/* 移动端调整 */
@media (max-width: 768px) {
:root {
--font-size: 14px;
--spacing: 15px;
}
}
/* 平板端调整 */
@media (min-width: 769px) and (max-width: 1024px) {
:root {
--columns: 2;
--spacing: 25px;
}
}
/* 桌面端调整 */
@media (min-width: 1025px) {
:root {
--columns: 3;
--spacing: 30px;
--font-size: 18px;
}
}
/* 应用变量 */
.grid {
font-size: var(--font-size);
gap: var(--spacing);
grid-template-columns: repeat(var(--columns), 1fr);
}
3. 设计系统
/* 设计系统变量 */
:root {
/* 颜色系统 */
--color-primary: #007bff;
--color-secondary: #6c757d;
--color-success: #28a745;
--color-danger: #dc3545;
--color-warning: #ffc107;
--color-info: #17a2b8;
/* 字体系统 */
--font-family-base: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
--font-size-base: 16px;
--font-weight-normal: 400;
--font-weight-bold: 700;
/* 间距系统 */
--spacing-xs: 4px;
--spacing-sm: 8px;
--spacing-md: 16px;
--spacing-lg: 24px;
--spacing-xl: 32px;
/* 边框系统 */
--border-radius-sm: 4px;
--border-radius-md: 8px;
--border-radius-lg: 12px;
--border-width: 1px;
/* 阴影系统 */
--shadow-sm: 0 1px 3px rgba(0,0,0,0.12);
--shadow-md: 0 4px 6px rgba(0,0,0,0.1);
--shadow-lg: 0 10px 15px rgba(0,0,0,0.1);
}
/* 应用设计系统 */
.button {
font-family: var(--font-family-base);
font-size: var(--font-size-base);
padding: var(--spacing-sm) var(--spacing-md);
border-radius: var(--border-radius-md);
border: var(--border-width) solid transparent;
box-shadow: var(--shadow-sm);
}
.card {
padding: var(--spacing-lg);
border-radius: var(--border-radius-lg);
box-shadow: var(--shadow-md);
background: white;
}
4. 动画与过渡
/* 动画变量 */
:root {
--transition-duration: 0.3s;
--transition-timing: ease;
--animation-duration: 1s;
}
.element {
transition: all var(--transition-duration) var(--transition-timing);
}
@keyframes slideIn {
from {
transform: translateX(var(--slide-distance, -100%));
}
to {
transform: translateX(0);
}
}
.slide-animation {
animation: slideIn var(--animation-duration) ease;
}
/* 动态控制动画 */
.slide-animation.fast {
--animation-duration: 0.5s;
}
.slide-animation.slow {
--animation-duration: 2s;
}
5. 动态样式
/* 通过 JavaScript 动态更新变量 */
const root = document.documentElement;
// 更新颜色
root.style.setProperty('--primary-color', '#ff6b6b');
// 更新尺寸
root.style.setProperty('--font-size', '18px');
// 更新间距
root.style.setProperty('--spacing', '30px');
// 响应鼠标位置
document.addEventListener('mousemove', (e) => {
const x = e.clientX / window.innerWidth;
const y = e.clientY / window.innerHeight;
root.style.setProperty('--mouse-x', x);
root.style.setProperty('--mouse-y', y);
});
/* CSS 中使用动态变量 */
.dynamic-element {
transform:
translateX(calc(var(--mouse-x, 0.5) * 100px))
translateY(calc(var(--mouse-y, 0.5) * 100px));
opacity: var(--mouse-y, 0.5);
}
高级技巧
1. 计算与函数
/* 使用 calc() 计算 */
:root {
--base-size: 16px;
--scale-factor: 1.2;
}
.element {
font-size: calc(var(--base-size) * var(--scale-factor));
padding: calc(var(--base-size) / 2);
margin: calc(var(--base-size) * 2);
}
/* 复杂计算 */
.grid-item {
--columns: 3;
--gap: 20px;
width: calc((100% - (var(--gap) * (var(--columns) - 1))) / var(--columns));
}
/* 使用 min()、max()、clamp() */
.responsive-text {
font-size: clamp(
var(--min-font-size, 12px),
var(--preferred-font-size, 4vw),
var(--max-font-size, 24px)
);
}
2. 继承与覆盖
/* 变量继承链 */
:root {
--color-base: #333;
--color-primary: var(--color-base);
}
.container {
--color-primary: #007bff; /* 覆盖根变量 */
}
.button {
color: var(--color-primary); /* 使用容器变量 */
}
/* 使用 inherit 关键字 */
.parent {
--custom-color: #ff6b6b;
}
.child {
--custom-color: inherit; /* 继承父级变量 */
color: var(--custom-color);
}
3. 媒体查询与变量
/* 在媒体查询中修改变量 */
:root {
--font-size: 16px;
--spacing: 20px;
}
@media (max-width: 768px) {
:root {
--font-size: 14px;
--spacing: 15px;
}
}
@media (min-width: 1200px) {
:root {
--font-size: 18px;
--spacing: 30px;
}
}
/* 使用变量 */
body {
font-size: var(--font-size);
padding: var(--spacing);
}
4. 组件变量
/* 组件变量系统 */
.alert {
--alert-padding: 1rem;
--alert-margin: 1rem 0;
--alert-border-radius: 0.25rem;
--alert-border: 1px solid transparent;
padding: var(--alert-padding);
margin: var(--alert-margin);
border-radius: var(--alert-border-radius);
border: var(--alert-border);
}
.alert-success {
--alert-color: #155724;
--alert-bg: #d4edda;
--alert-border-color: #c3e6cb;
color: var(--alert-color);
background-color: var(--alert-bg);
border-color: var(--alert-border-color);
}
.alert-danger {
--alert-color: #721c24;
--alert-bg: #f8d7da;
--alert-border-color: #f5c6cb;
color: var(--alert-color);
background-color: var(--alert-bg);
border-color: var(--alert-border-color);
}
性能优化
1. 变量命名优化
/* 使用有意义的命名 */
:root {
/* 好的命名 */
--color-primary: #007bff;
--spacing-md: 16px;
--font-size-base: 16px;
/* 避免的命名 */
--c1: #007bff; /* 无意义 */
--s1: 16px; /* 无意义 */
}
2. 减少变量数量
/* 合并相关变量 */
:root {
/* 合并前 */
--color-primary: #007bff;
--color-primary-hover: #0056b3;
--color-primary-active: #004085;
/* 合并后 */
--color-primary: #007bff;
--color-primary-hover: color-mix(in srgb, var(--color-primary) 20%, black);
--color-primary-active: color-mix(in srgb, var(--color-primary) 40%, black);
}
3. 避免过度使用
/* 只在需要时使用变量 */
.element {
/* 适合使用变量 */
color: var(--text-color);
font-size: var(--font-size);
/* 不适合使用变量(过于简单) */
display: var(--display, block); /* 过度使用 */
position: var(--position, relative); /* 过度使用 */
}
浏览器兼容性
1. 特性检测
/* 检测 CSS 变量支持 */
@supports (--css: variables) {
.modern-styles {
--primary-color: #007bff;
color: var(--primary-color);
}
}
@supports not (--css: variables) {
.fallback-styles {
color: #007bff; /* 回退样式 */
}
}
2. 渐进增强
/* 基础样式(所有浏览器) */
.button {
background-color: #007bff;
color: white;
padding: 10px 20px;
}
/* 增强样式(支持变量的浏览器) */
@supports (--css: variables) {
.button {
background-color: var(--primary-color, #007bff);
padding: var(--button-padding, 10px 20px);
}
}
工具与资源
1. 开发工具
- Chrome DevTools:变量检查器
- Firefox DevTools:变量调试工具
- CSS Variable Manager:变量管理扩展
2. 实用代码片段
/* 变量重置 */
:root {
--reset: initial;
--inherit: inherit;
--unset: unset;
}
/* 调试变量 */
.debug-variables::before {
content: '--primary-color: ' var(--primary-color, '未定义');
position: fixed;
bottom: 10px;
right: 10px;
background: #333;
color: white;
padding: 5px 10px;
font-family: monospace;
font-size: 12px;
z-index: 9999;
}
总结
CSS 自定义属性是现代 CSS 开发的重要工具,它提供了:
- 更好的可维护性:集中管理样式值
- 动态样式能力:通过 JavaScript 实时修改样式
- 主题切换支持:轻松实现多主题系统
- 响应式设计增强:媒体查询中的变量控制
- 设计系统基础:构建一致的设计语言
随着浏览器支持的完善,CSS 变量已经成为现代 Web 开发的标配技术。建议在实际项目中积极采用,提升代码质量和开发效率。
创建时间:2022-05-20 最后更新:2022-05-20 作者:前端开发团队 标签:CSS, CSS变量, 自定义属性, 主题切换, 前端开发
