@content 是 sass 编译期占位符,仅在 @include 后紧跟大括号时原样插入内容,不支持传参、条件渲染或作用域共享,必须配合嵌套语法使用。

@content 不是动态插槽,也不是运行时样式注入机制——它只在 @include 后紧跟大括号时,把那块 SCSS 原样塞进编译位置。想靠它“传参式定制”或“条件渲染样式”,会直接失败。
为什么 @content 调用必须带大括号,否则报错 Content block not provided
因为 @content 是编译器识别的占位符,不是函数参数。Sass 只在 @include my-mixin { ... } 这种语法下,才把花括号内整个块(含嵌套、& 引用、声明)原样插入。
-
@include layout-flex;→@content为空,编译器报错 -
@include layout-flex { width: 100%; }✅ →&仍指向调用处父选择器,如.card下调用则生成.card { display: flex; width: 100%; } -
@include layout-flex; { width: 100%; }❌ → 分号提前终止@include,后面代码变成孤立块,不进容器也不进媒体查询
如何封装 Flex/Grid 布局但保留调用处的嵌套上下文
关键不是“加一层 wrapper”,而是让 @content 直接落在规则体里,不包裹额外选择器。
- ✅ 正确写法:
@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; } - ❌ 错误写法:
.wrapper { @content; }→ 强制加了一层.wrapper,破坏调用灵活性 - 若需统一控制子元素(如所有直接子项加 margin),应在 mixin 中显式写出结构:
> * { margin: 0.5rem; @content; },此时@content插入到> *内部
@content 和参数混用时的作用域陷阱
参数在 mixin 内部生效,@content 中的代码却始终运行在调用者作用域,二者变量不互通。
- 能做的:用参数控制是否启用某层包装,再把
@content塞进去,例如@mixin with-gap($size: 1rem) { gap: $size; @content; } - 不能做的:在 mixin 内声明
$temp: 20px;,然后指望@content里能用width: $temp;—— 它访问不到 - 想“传值”给
@content块?不行。替代方案是定义带参数的子 mixin,在@content里@include它 - 别在
@content块里用@extend—— 编译时报错:Invalid CSS after "@extend": expected selector
真正容易被忽略的是:@content 的生效完全依赖调用方式
它不解析字符串、不支持递归、不参与逻辑判断,只是编译期单次展开。每个 @include 都生成独立 CSS;大量组合(如 @each + @content)会让输出体积激增,尤其断点循环中慎用。设计 mixin 时得想清楚:这个结构,该由调用者写,还是该由 mixin 预埋?边界模糊,就容易掉进作用域和体积双重坑里。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











