先记住这个答案
@media 只是条件门槛:条件为真,里面的规则才参与 CSS 级联。它不会给选择器增加权重。因此两条媒体查询同时匹配时,要按正常级联判断同一属性的最终值,包括来源、!important、层叠层、选择器权重和书写顺序。在常见的同源、同层、同权重场景里,写在后面的声明覆盖前面的声明。
- 媒体查询本身不增加选择器权重
- 多个断点可以在同一宽度同时匹配
- 权重等条件相同时,后声明覆盖先声明
- 移动优先常按宽度递增排列规则
两个断点同时命中会怎样
假设卡片在窄屏单列,宽一些变双列,再宽一些变三列。若两个条件都用 min-width,到了大视口,它们都会匹配。把较大的断点放在后面,相同选择器就能自然覆盖较小断点的列数。
.cards { grid-template-columns: 1fr; }
@media (min-width: 40rem) {
.cards { grid-template-columns: repeat(2, 1fr); }
}
@media (min-width: 70rem) {
.cards { grid-template-columns: repeat(3, 1fr); }
}视口达到 70rem 时,两条媒体查询都命中,.cards 的权重相同,最后写的三列生效。若把两个媒体块顺序反过来,40rem 的双列规则反而可能盖住三列。移动优先代码常按断点递增排列,阅读时就能顺着空间增加的方向看布局增强。
为什么“最后一条”有时没赢
如果先前规则用的是 .page .cards,后来只用 .cards,即使后者在文件末尾,先前更高权重的选择器仍可能获胜。!important、CSS 层叠层和不同样式来源也会改变比较结果。媒体查询不会让里面的选择器自动变强,因此排查时不能只把断点顺序颠倒,还要看开发者工具里真正获胜的声明。
另一种常见冲突是 max-width 与 min-width 的边界重叠。max-width: 48rem 和 min-width: 48rem 都包含 48rem;刚好这个值时两条都匹配。若想避免重叠,可以调整条件范围或使用清晰的基础规则与单向断点。写断点前先画出每段宽度由哪些规则负责,通常比给某条声明临时加 !important 更稳。
移动优先为什么易读
移动优先把窄屏可用的状态写成无条件规则,再按视口变宽逐步增加列数、留白或导航形式。多数覆盖沿一个方向叠加,不必不断逆转之前的布局决定。它不会改变 CSS 级联算法,也不会保证任何冲突自动消失;可维护性来自规则排列的一致性。
桌面优先也能写得清楚,尤其是改造现有宽屏页面时。真正难维护的是一处用 min-width、另一处用 max-width,再混入不同权重的选择器和 !important,最后每个宽度都要猜哪条赢。团队应统一断点方向,并在临界宽度实测。
容易答错的地方
- 认为媒体查询的数值越大,优先级越高
- 断点数值只决定匹配区间,不参与选择器权重计算。70rem 规则放在 40rem 前面且权重相同时,宽屏上反而可能由后者覆盖。
- 认为只要写在最后就一定获胜
- 源码顺序只是级联靠后的比较环节。来源、重要性、层叠层或选择器权重不同,都可能让先写的声明获胜。调试时应先看是否都匹配,再看被划掉的声明为何输了。
面试官还会怎么问?
@media 会增加选择器的特异性吗?
不会。.cards 在媒体查询内外的选择器权重相同。媒体条件只控制那条规则何时可用,条件为真后仍按普通级联计算。
两条规则都用了 !important,还能靠顺序判断吗?
要先比较它们的来源、层叠层和选择器权重等因素。这些条件也相同,才轮到书写顺序。不能跳过前面的级联步骤直接看文件末尾。
如何定位窄屏正常、某个中间宽度却错乱的问题?
在出问题的宽度查看元素的计算样式,逐条确认哪些媒体查询命中。再看冲突属性的选择器权重和声明顺序,找出真正覆盖它的规则;通常比盲目移动断点数字更快。
参考资料
示例用于理解所注明的运行环境与边界;延伸学习可结合原文中的更多案例。