sass本身不合并重复媒体查询,因其@media仅是语法糖、编译器不做语义分析,导致相同断点重复输出;需通过@mixin统一管理断点变量并配合postcss插件在构建时合并。

@media (min-width: 768px),编译后就是十段独立规则——这不是写法错,是 Sass 的设计使然。
为什么手动写 @media 会悄悄膨胀 CSS
现象很典型:Lighthouse 报“Reduce unused CSS”,DevTools 里看到同一断点反复出现,甚至在同一个组件里因嵌套过深生成两份一模一样的 @media (min-width: 768px) 块。
根本原因是 Sass 的 @media 只做文本拼接,不分析语义。它不管你在 _button.scss、_card.scss 还是 _header.scss 里各写了一次,统统原样输出。
用 @mixin 统一管理断点,但别只封装语法
光把 @media (min-width: 768px) 包成 @mixin md 不够,关键在参数设计和调用方式:
- 断点值必须抽成变量映射:
$breakpoints: ("sm": 576px, "md": 768px, "lg": 992px); - Mixin 接收键名而非像素值:
@include media-breakpoint-up("md") { ... },内部用map-get($breakpoints, "md")查表 - 务必用
@media (...) { @content; }包裹,不能漏掉大括号,否则&在嵌套中会失效 - 避免在 Mixin 内拼选择器(比如
.#{$name}-hover),让调用方用&:hover更安全
PostCSS 合并才是落地刚需
就算 Mixin 写得再规范,编译后的 CSS 仍是分散的。真正减体积靠的是构建时合并:
- 装插件:
npm install postcss-combine-media-query --save-dev - 配置
postcss.config.js,确保postcss-combine-media-query在cssnano之前运行 - 注意写法统一:
@media (min-width: 768px)和@media screen and (min-width: 768px)被视为不同断点,必须全项目统一省略screen - 复合条件慎用:
@media (min-width: 768px) and (orientation: landscape)不会被合并,拆成基础断点 + JS 判断更稳
哪些地方最容易漏掉合并逻辑
团队协作时最常栽在三个地方:一是 @import 的 partial 文件各自定义媒体查询,彼此不可见;二是第三方 UI 库(如 Bootstrap SCSS)和业务样式混用,断点单位不一致(px vs rem);三是构建流程里 PostCSS 配置被 Webpack/Vite 的默认 CSS 处理器绕过,导致插件压根没生效。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











