用 @mixin 定义带默认值的按钮变体(如 $bg、$radius、$size),调用时仅传需覆盖参数;提取公共样式到基础类,变体只写差异属性,避免重复输出和体积膨胀。

怎么用 @mixin 给按钮写可传参的变体
直接传颜色、尺寸、圆角这些变量进去,比复制粘贴几套 CSS 更安全。Sass 的 @mixin 本质是带参数的样式块,不是函数,不返回值,只展开——所以别在 @mixin 里写 @return,会报错。
常见错误是把变体写成独立类名(比如 .btn-primary、.btn-danger),结果改个间距要同步改七八个地方。用 @mixin 就能统一控制基线样式,变体只负责覆盖关键属性。
-
@mixin btn($bg: #007bff, $radius: 4px, $size: 1em)—— 所有参数设默认值,调用时只传想改的 - 调用写法:
@include btn(#dc3545, 6px),第三个参数$size自动用默认值 - 别在
@mixin里写&:hover等嵌套规则后又在外面再套一层选择器,容易生成冗余 CSS(比如.btn .btn:hover)
为什么不能直接用 CSS 自定义属性(--color)代替 @mixin
运行时动态换肤确实该用 CSS 变量,但编译期确定的变体(比如主题包、组件库预设风格)用 @mixin 更轻量:它不增加运行时开销,也不依赖 JS 注入,更不会因变量未定义导致样式失效。
典型踩坑是混用两者:比如用 @mixin 生成基础类,又用 --bg 覆盖背景色——结果发现 background-color: var(--bg, <code>#007bff) 在旧版 Safari 里 fallback 不生效,而 @mixin 编译后就是纯 CSS,兼容性稳得多。
立即学习“前端免费学习笔记(深入)”;
- SSR 或静态站点生成时,
@mixin输出的是确定 CSS,无需客户端计算 - CSS 变量无法做条件编译(比如
@if $size == 'lg'),@mixin可以结合@if控制输出逻辑 - 如果项目已用 Tailwind 这类原子类方案,就别硬套
@mixin变体——它们设计哲学冲突,强行融合反而难维护
@mixin 传参时哪些类型容易出错
Sass 对参数类型不做强校验,但传错类型会导致编译失败或样式异常。最常出问题的是颜色值、单位、列表和空值。
比如传字符串 "small" 当尺寸,却在 mixin 里直接当数值加减;或者传 null 进去,lighten($bg, 10%) 就崩了。
- 用
@if type-of($bg) != 'color'做简单校验,比报错后翻日志快得多 - 单位必须显式带上(
12px、1.2rem),不能只传数字12,否则font-size: $size会输出font-size: 12,浏览器不认 - 传列表(比如
(1px, solid, #ccc))时,用nth($border, 1)取值,别直接当单值用
变体太多时怎么避免 CSS 体积爆炸
每个 @include 调用都会生成一份完整样式块,10 个变体 × 按钮 50 行 CSS = 500 行重复代码。这不是语义问题,是真实打包体积和渲染性能问题。
核心思路是「提取公共样式 + 差异最小化」:把不变的部分(如 display、box-sizing、transition)抽到基础类,变体只写真正不同的属性(background、color、border-radius)。
- 基础类写成
.btn { @include btn-base() },所有变体继承它,再用.btn--primary { @include btn-variant(#007bff) } - 禁用
@mixin中的@extend,它会让 Sass 难以优化重复选择器 - Webpack 或 Vite 构建时开启 CSS Minifier,但别指望它合并语义相同的规则——那是 Sass 编译层该干的事
变体不是越多越好,真正需要的通常不超过 4 种(主色、危险、幽灵、禁用)。多出来的往往是设计系统没收敛,而不是技术实现没到位。


















