能成,但需变量在\_variables.scss中提前定义并带单位,用@mixin card-base封装结构逻辑,%card-hoverable处理共用状态,CSS自定义属性驱动皮肤,@content插入调用处样式且必须紧跟大括号。

直接改变量就能让所有卡片响应式变圆角、换阴影、调间距——这事能成,但前提是变量得在正确位置声明、被正确消费,且不能被后续重定义覆盖。
用 @mixin card-base 封装结构逻辑,别重复写 border-radius 和 box-shadow
很多人一上来就给每个卡片写一遍 border-radius: 8px; box-shadow: 0 2px 6px rgba(0,0,0,0.1);,结果改个阴影色得全局搜替换。用 @mixin card-base 把这些视觉契约收口:
@mixin card-base {
border-radius: $card-border-radius;
box-shadow: $card-shadow;
background: $card-bg;
overflow: hidden;
}
关键点在于:$card-border-radius 等变量必须提前定义在 _variables.scss 中,且值要带单位(如 8px),否则编译报错 Invalid CSS after "$card-border-radius";@mixin 不会生成实际 CSS,必须被 @include 调用才生效。
用 %card-hoverable 处理共用状态,避免类名爆炸
卡片常有 is-hoverable、is-clickable 等状态,如果每个都写完整规则,HTML 里就得堆一堆类:class="card is-hoverable is-clickable"。更干净的做法是用占位符 + @extend:
立即学习“前端免费学习笔记(深入)”;
%card-hoverable {
transition: transform 0.2s, box-shadow 0.2s;
&:hover {
transform: translateY(-2px);
box-shadow: $card-shadow-hover;
}
}
.card {
@extend %card-hoverable;
// 其他基础样式
}
@extend 会合并选择器,如果多个组件都 @extend %card-hoverable,最终生成的 CSS 可能出现长链选择器(如 .card, .product-card, .user-card:hover),影响可维护性;只对真正共用的、语义明确的状态用占位符,别为了“看起来高级”而滥用。
用 --card-bg 这类 CSS 自定义属性驱动皮肤,别把颜色硬塞进 Sass 变量
Sass 编译期无法响应运行时主题切换。真正可扩展的方案是分离结构与皮肤:
- 结构层:用
@mixin card-base定义padding、border-radius、box-shadow等不变逻辑 - 皮肤层:用 CSS 自定义属性(
--card-bg、--card-border)驱动视觉,Sass 只生成background-color: var(--card-bg) - 调用时写
.card { @include card-base; },主题色由 JS 注入或根元素class控制
硬编码 $primary 到 background-color 声明里,它无法被 :root 覆盖,会阻断主题切换能力。
用 @content 插入调用处样式,但必须带大括号且不破坏嵌套上下文
@content 是编译期占位符,只在 @include 后紧跟大括号时原样插入内容,不支持传参或条件渲染:
@mixin flex-center {
display: flex;
justify-content: center;
align-items: center;
@content;
}
.card {
@include flex-center {
&__header { color: red; }
}
}
编译为:.card { display: flex; } + .card__header { color: red; }。若写成 @include flex-center; { width: 100%; },分号提前终止 @include,后面代码变成孤立块,不进容器也不进媒体查询。
复杂点在于:@content 中的代码始终运行在调用者作用域,和 mixin 内部参数变量不互通;想控制是否启用某层包装,得用参数开关,再把 @content 塞进去,而不是指望它能读取 mixin 参数。


















