一、变量是什么?为什么需要它们?

想象你正在装修房子。每次看到"主卧墙面颜色"时,都需要翻看色卡本找到"#FFD700"这个色号,是不是很麻烦?如果有个标签写着"主卧墙面=#FFD700",后面直接引用这个标签就方便多了。CSS变量和Sass变量就是这样的"标签"。

传统CSS写法就像每次都翻色卡:

/* 技术栈:纯CSS */
.header { background: #FFD700; }
.button { color: #FFD700; }
.footer { border-color: #FFD700; }

而使用变量后:

/* 技术栈:CSS原生变量 */
:root {
  --main-color: #FFD700; /* 定义变量 */
}
.header { background: var(--main-color); } /* 使用变量 */
.button { color: var(--main-color); }

二、CSS变量使用详解

原生CSS变量(也叫自定义属性)就像是浏览器自带的便利贴。它们最大的特点是可以在运行时被JavaScript动态修改,实现主题切换等效果。

完整示例:

/* 技术栈:CSS原生变量 */
:root {
  --primary: #4285f4;       /* 蓝色 */
  --spacing: 8px;           /* 基础间距 */
  --border-radius: 4px;     /* 圆角大小 */
}

.button {
  padding: var(--spacing) calc(var(--spacing)*2); /* 计算 */
  border-radius: var(--border-radius);
  background: var(--primary);
}

/* 暗色模式切换 */
@media (prefers-color-scheme: dark) {
  :root {
    --primary: #34a853;     /* 绿色 */
  }
}

注意事项:

  1. 变量名区分大小写
  2. 建议在:root中定义全局变量
  3. 可以通过var()函数设置默认值:var(--size, 16px)

三、Sass变量进阶用法

Sass就像是CSS的加强版工具箱,它的变量在编译阶段就被处理,支持复杂的逻辑运算和代码组织。

典型示例:

// 技术栈:Sass
$font-stack: Helvetica, sans-serif;  // 字体变量
$primary-color: #333;                // 颜色变量
$spacing-unit: 8px !default;        // 可覆盖的默认值

body {
  font: 100% $font-stack;
  color: $primary-color;
}

// 嵌套计算
.container {
  $container-width: 960px;          // 局部变量
  width: $container-width;
  padding: $spacing-unit * 2;
}

// 映射类型变量
$theme-colors: (
  "primary": #007bff,
  "danger": #dc3545
);

.alert {
  background-color: map-get($theme-colors, "primary");
}

Sass特有的优势:

  1. 支持数据类型(数字、字符串、颜色、布尔值等)
  2. 局部变量作用域
  3. 可进行数学运算和颜色计算
  4. 提供!default标志设置可覆盖默认值

四、两种技术的核心差异

通过一个主题切换的例子对比两种实现方式:

CSS变量实现动态主题:

/* 技术栈:CSS变量 + JavaScript */
:root {
  --text-color: #333;
  --bg-color: #fff;
}

.dark-mode {
  --text-color: #fff;
  --bg-color: #333;
}

/* 通过JS切换类名即可改变主题 */
document.body.classList.toggle('dark-mode');

Sass实现多主题编译:

// 技术栈:Sass
$themes: (
  light: (
    text-color: #333,
    bg-color: #fff
  ),
  dark: (
    text-color: #fff,
    bg-color: #333
  )
);

@mixin theme($name) {
  $theme: map-get($themes, $name);
  body.#{$name} {
    color: map-get($theme, text-color);
    background: map-get($theme, bg-color);
  }
}

// 编译时会生成多套主题CSS
@include theme(light);
@include theme(dark);

关键区别点:

  1. 生效时机:CSS变量在浏览器运行时生效,Sass变量在编译阶段生效
  2. 作用域:CSS变量遵循DOM层级,Sass变量遵循代码作用域
  3. 动态性:CSS变量可通过JS实时修改,Sass变量编译后固定

五、如何选择合适的技术方案

选择CSS变量当:

  • 需要实现运行时动态效果(如主题切换)
  • 项目规模较小,不想引入构建工具
  • 需要与第三方CSS代码交互
  • 希望减少CSS文件体积(变量可复用)

选择Sass变量当:

  • 项目已使用Sass预处理器
  • 需要复杂的计算或逻辑判断
  • 需要代码模块化和组织管理
  • 开发组件库需要编译多套样式

混合使用建议:

// 技术栈:Sass + CSS变量
// 定义Sass配置
$breakpoints: (small: 480px, medium: 768px);

// 转换为CSS变量
:root {
  @each $name, $value in $breakpoints {
    --breakpoint-#{$name}: #{$value};
  }
}

// 同时使用两种变量
@media (min-width: map-get($breakpoints, medium)) {
  .grid {
    display: grid;
    gap: var(--grid-gap, 20px); // CSS变量
  }
}

六、常见问题与解决方案

  1. 浏览器兼容性问题:

    • CSS变量不支持IE11,可通过PostCSS插件降级
    • Sass变量需要编译,兼容所有浏览器
  2. 调试技巧:

    // 查看所有CSS变量
    console.log(getComputedStyle(document.documentElement));
    
    // Sass调试需要检查编译后的CSS
    
  3. 性能考量:

    • 过度使用CSS变量可能导致重绘
    • Sass变量不影响运行时性能,但会增加构建时间
  4. 命名规范建议:

    • CSS变量:--component-state-property (如--button-active-bg)
    • Sass变量:$property-state-modifier (如$bg-active-button)

七、实战应用场景分析

企业官网案例:

// 技术栈:Sass
// _variables.scss
$brand-blue: #1e88e5;
$transition-speed: 0.3s;

// _mixins.scss
@mixin hover-effect {
  transition: all $transition-speed ease;
  &:hover {
    transform: translateY(-2px);
  }
}

// main.scss
@import 'variables', 'mixins';

.cta-button {
  background: $brand-blue;
  @include hover-effect;
}

管理后台案例:

/* 技术栈:CSS变量 */
/* 动态调整布局 */
:root {
  --sidebar-width: 240px;
  --content-padding: 16px;
}

.layout {
  display: grid;
  grid-template-columns: var(--sidebar-width) 1fr;
}

.content {
  padding: var(--content-padding);
}

/* 通过JS调整布局 */
document.documentElement.style.setProperty('--sidebar-width', '200px');

八、技术决策检查清单

做选择前问这些问题:

  1. 是否需要运行时动态改变样式值?

    • 是 → 选择CSS变量
    • 否 → 考虑Sass变量
  2. 项目是否已经使用CSS预处理器?

    • 是 → 优先使用Sass变量保持一致性
    • 否 → 评估引入预处理器的必要性
  3. 是否需要支持IE11等老旧浏览器?

    • 是 → 使用Sass或CSS变量降级方案
    • 否 → 可自由选择
  4. 团队成员的熟悉程度如何?

    • 更熟悉CSS → 从CSS变量开始
    • 有Sass经验 → 可利用更强大功能

九、未来发展趋势

CSS新特性正在缩小与预处理器的差距:

  1. CSS Color Module Level 5带来了颜色计算函数
  2. CSS Nesting规范将支持原生嵌套写法
  3. @custom-media查询允许定义媒体查询变量

但Sass也在持续进化:

  1. 模块系统更完善
  2. 更好的与CSS原生特性集成
  3. 改进的数学计算精度

建议保持对两种技术的关注,根据项目需求灵活选择。

十、总结与建议

就像选择电动工具还是手动工具,没有绝对的好坏,只有适合的场景。CSS变量像是灵活的多功能刀,Sass变量则像专业的电动工具组。

对于大多数现代项目,建议:

  1. 使用Sass变量管理设计系统和配置
  2. 使用CSS变量实现动态交互效果
  3. 通过构建工具将Sass变量编译为CSS变量

最终记住:技术是为人服务的,选择让团队开发效率更高、维护成本更低的方案,才是明智的架构决策。