弹窗组件必须用@mixin封装而非@function,因涉及整套样式规则;@content需紧跟大括号调用,缩进对齐以透传嵌套上下文,禁用@extend和变量拼接样式字符串。

弹窗组件必须用@mixin封装,不能用@function
因为弹窗涉及的是整套样式规则(定位、z-index、遮罩、动画、子元素结构),不是返回一个颜色或数值。@function只能返回数据类型,无法生成选择器和嵌套声明。@mixin modal-base才能接收@content、支持参数控制层级、透传&__header等嵌套上下文。
@content必须紧跟大括号调用,否则媒体查询为空
这是最常踩的坑:写成@include modal-responsive(sm); color: red;,编译后@media里什么都没有。Sass只在@include xxx { }这种语法下才把花括号内代码识别为@content块。
正确写法是:
.login-modal {
@include modal-responsive(sm) {
&__form { width: 100%; }
}
}
注意缩进对齐,否则&__form可能被错误解析为.login-modal .login-modal__form。
立即学习“前端免费学习笔记(深入)”;
透传嵌套上下文的关键是@content不加 wrapper
错误做法是在 mixin 里强行包裹一层.modal-wrapper { @content; }——这会破坏调用处的&语义,让&__body变成.modal-wrapper__body而非预期的.login-modal__body。
正确结构示例:
@mixin modal-base($z: 1000) {
position: fixed;
z-index: $z;
top: 0;
left: 0;
width: 100%;
height: 100%;
@content;
}
调用时&__overlay和&__dialog仍能正确解析为.login-modal__overlay和.login-modal__dialog。
@content里禁止用@extend和变量拼接样式字符串
这两类操作在编译期直接崩溃或静默失效:
-
@include modal-base { @extend .btn-reset; }→ 报错:Invalid CSS after "@extend": expected selector -
$style: "opacity: 0.9;"; @include modal-base { #{$style} }→ 输出纯文本opacity: 0.9;,不参与样式编译,也不继承作用域
替代方案很明确:
- 把需复用的样式抽成独立 class(如
.btn--ghost),在@content中直接写&__close { @extend .btn--ghost; }(不推荐)或更稳妥地写&__close { @include btn-ghost; } - 需要动态值就用参数:
@mixin modal-fade($opacity: 0.85) { opacity: $opacity; @content; }
真正容易被忽略的是:@content不是“运行时插槽”,它在编译早期就被展开;所有变量、&、嵌套层级都来自调用点,而非 mixin 内部定义——这点决定了你没法在 mixin 里声明一个变量然后指望@content里能读到它。


















