@content是sass中安全透传嵌套上下文的编译期容器,仅原样插入调用处大括号内代码并保持作用域、嵌套层级和&引用不变,必须配合@include mixin-name { ... }语法使用,不解析逻辑、不拼接字符串、不支持多实例或与@extend/变量字符串混用。

@content 不是“自定义媒体查询”的万能开关,而是让 mixin 成为**安全透传嵌套上下文的编译期容器**。它本身不生成断点、不解析设备名、不拼接 CSS 字符串——它的唯一职责是:把调用处的大括号内代码,原样塞进 mixin 定义的规则体里,并保持 &、嵌套层级、变量作用域不变。
为什么 @content 必须配合 @include mixin-name { ... } 大括号调用
这是 Sass 编译器识别“内容块”的硬性语法约定。@content 不是参数,也不是运行时值,它只在 @include 后紧跟 { 时才被激活。
-
@include respond-to(md); color: red;→ 分号终止调用,@content收不到任何内容,编译后@media内为空 -
@include respond-to(md) { color: red; }✅ → 整个花括号块被原样注入,color: red;出现在媒体查询内部 - 缩进不一致(比如
{后换行但没缩进)可能触发意外嵌套,导致选择器变成.card .card img这类重复前缀
如何用 @content 封装断点并保留调用处的选择器上下文
关键不是“写断点”,而是让 @content 插入的位置不破坏父级结构。例如在 .card 下调用,里面写的 img 应编译为 .card img,而非孤立的 img。
- mixin 定义里不要手动加选择器:
@mixin respond-to($bp) { @media (min-width: map-get($breakpoints, $bp)) { @content; } }—— 正确 - 错误写法:
@mixin respond-to($bp) { @media (...) { .card { @content; } } }→ 强行包裹,破坏调用灵活性 - 调用位置有
&__header,@content中的h2自动编译为&__header h2;有&.active,则color: red变成&.active { color: red; } - 不能靠
@content注入动态选择器,比如想把变量$sel拼成.#{$sel} img—— 那得用插值,不是@content的能力范围
@content 和 @extend / 变量字符串混用会崩溃
它们的编译时机根本冲突:@extend 要求目标选择器在编译早期就确定,而 @content 是延迟注入;变量存的字符串不会被 Sass 二次编译,只会字面输出。
-
@include responsive-md { @extend .btn-base; }→ 报错:Invalid CSS after "@extend": expected selector, was ";" -
$style: "color: red;"; @include foo { #{$style} }→ 输出color: red;作为纯文本,不参与样式编译 - 替代方案:把需复用的样式抽成独立 class(如
.btn--primary),在@content中直接使用该 class 名 - 一个 mixin 内只能有一个
@content,且必须位于参数声明之后、其他语句之前;不支持递归(即@content块里再@include另一个含@content的 mixin)
@include ... { ... },背后都依赖 Sass 编译器对嵌套上下文的精确解析。一旦混用 @extend、插值或错误缩进,问题往往不报错,而是生成无效 CSS 或意外选择器——这种 bug 很难 debug,因为源码看着没问题,编译结果却不对。前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











