@content是Sass中唯一能安全透传嵌套上下文的编译期机制,必须配合@include mixin-name { ... }大括号调用才能生效,否则媒体查询内为空;它原样插入已解析的作用域,使.card内调用的img编译为.card img,避免手动拼接或插值错误。

@content 是 Sass 响应式开发里唯一能安全“透传嵌套上下文”的编译期机制,不是语法糖,而是解决媒体查询中选择器继承问题的基础设施。
为什么 @content 必须配合大括号调用才能生效
@content 不是运行时参数,它只在 @include mixin-name { ... } 这种带花括号的调用形式下被识别为“内容块插入点”。Sass 编译器会把花括号内的整个 SCSS 片段(含嵌套、&、变量引用)原样塞进 @content 所在位置。
常见错误现象:@include respond-to(sm); color: red; → 编译后媒体查询内部为空,因为分号终止了调用,@content 没收到任何内容。
- ✅ 正确写法:
@include respond-to(sm) { color: red; } - ❌ 错误写法:
@include respond-to(sm);后续样式不会进入媒体查询 - ⚠️ 注意缩进:花括号内样式需与
@include行对齐或缩进一致,否则可能意外嵌套进父选择器
@content 如何保持调用处的选择器上下文
关键在于 @content 插入的是“已解析的作用域”,不是字符串。你在 .card 下调用 @include responsive-md { img { width: 100%; } },编译结果是 .card img,不是孤立的 img。
立即学习“前端免费学习笔记(深入)”;
这直接避免了手动拼接前缀(如 .card img)、重复写断点、或用 #{$selector} img 这类易错插值。
- 调用位置有
&__header→@content中的h2编译为&__header h2 - 调用位置有
&.active→@content中的color: red编译为&.active { color: red; } - 不能靠
@content实现“动态选择器注入”,比如想把$sel变量拼成.#{$sel} img—— 那得用插值,不是@content的职责
@content 和 @extend / 变量传样式混用会出什么问题
@content 是编译期插入,而 @extend 需要编译器提前确定目标选择器。两者时机冲突,导致报错或生成无效 CSS。
错误信息典型如:Invalid CSS after "@extend": expected selector, was ";",或更隐蔽地编译失败但无提示。
- ❌ 禁止在
@content块里写@extend .btn-base - ✅ 替代方案:抽成独立 class,如
.btn .btn--primary,然后在@content中直接使用该 class - ❌ 禁止用变量存样式再传给
@content:$style: "color: red;"; @include foo { #{$style} }→ 输出字面量"color: red;",不编译、不作用域继承 - ✅ 参数和
@content可共存:@mixin card($bg: #fff) { background: $bg; @content; },参数控制值,@content控制结构
多个断点 + 嵌套调用时的边界限制
Sass 明确不支持递归解析 @content。外层 @include respond-to(md) { @include hover-state { color: blue; } } 中,内层 @content 不会被注入到外层媒体查询内,而是脱离上下文单独展开。
这意味着:你不能靠嵌套 @include 实现 “md 屏幕下的 hover 效果”,必须把逻辑收束到单层 @content 内,或改用组合 mixin(如先定义 @mixin md-hover)。
- 一个 mixin 里只能有一个
@content,且必须出现在所有其他语句之后、@return之前 - 断点 map 推荐用
map-has-key($breakpoints, $name)校验,避免键不存在时报错 - 性能上无运行时开销,但 CSS 体积随断点数量线性增长;10+ 断点需警惕冗余输出
真正难的从来不是写对 @content 语法,而是判断哪些逻辑该放进 mixin 参数、哪些必须留给调用方通过 @content 注入——边界模糊时,生成的 CSS 往往既难读又难维护。


















