先记住这个答案
当多条媒体查询的规则都命中某元素时,它们仍遵循CSS级联的源码顺序与特异性裁决:同源同重要时,特异性高者胜出;特异性相等时,后出现在样式表的声明获胜。媒体查询本身不新增优先级,只是一个条件壳。移动优先先把默认基础样式写在最前,再以 min-width 媒体查询逐步追加更宽视口的修正,使所有覆写都指向同一边。这种写法因大屏覆盖规则总在小屏之后出场,天然匹配预期冲突最少,拆读也方便。桌面优先若用 max-width 递减,则覆写方向相反,容易漏写回退值,代码更脆。
- 媒体查询本身无额外优先级
- 同特异性后写的声明覆盖先写
- 移动优先使覆写方向单一可预期
级联算法如何裁决媒体查询
CSS级联算法排序:先比较作者、用户和用户代理来源,再比较特异性,最后才看源码与书写顺序。两条规则都套在媒体查询内并不改变这一步——它们只是条件命中时的候选声明,互相之间依然依照统一分级。因此在无内联、无!important前提下,特异性比较优先级最高,后出现只在特异性相同时起决定作用。
以 @media (min-width:600px){p{color:red}} 和 @media (min-width:900px){p{color:blue}} 为例,宽度1000时两段都命中。若两个选择器同为 p,特异性相同,第二条声明获胜。假如第一段选择器改为 main p,则其特异性为0,1,1,大于 p 的0,0,1,所以即使第二段在文件中更靠后,也仍由第一段决定。核心在于特异性比较先于源码顺序。
一个两断点的移动优先卡片布局
假设基础规则让卡片宽度为100%。随后在 @media (min-width:600px) 中设宽度为50%,又在 @media (min-width:1000px) 中设为33%。视口宽度为800px时,只有600那条媒体查询满足,最终宽度为50%。视口为1200px时,两条都满足,因两条规则类选择器特异性相同,后写的33%胜出。这个结果对开发人员显然,因为断点自小到大排列,覆盖也自然由后文完成。
这种安排避免为回退值再做一次清空:小屏基准在最外层,任何命中的媒体查询中后面的断点总能覆盖前面同特异性的声明。开发者可开DevTools查看该元素已计算值,浏览器会列出被淘汰的声明及来源。若改成桌面优先并用 max-width 递减,宽屏规则在前,窄屏覆写在后面,则要给每个窄屏断点做更复杂的差值选择,否则某个中间宽度会继承不合适的默认值。
特异性与书写顺序不匹配时的反向局面
这条规律在两类场景失灵:其一,前一条媒体查询里使用了更高特异性的选择器,例如 .card .action{},后一条只有 .action{};后者即使写在后面也不能覆写前者。其二,任一处出现 !important,会将声明推到普通声明之前,后面的普通声明再写也无效。此时不是媒体查询的问题,而是级联的根本规则。判断时应先剥离媒体条件,将两条规则独立看待,先比出处、再比特异性,最终看先后位置。
移动优先模式不一定清除全部风险——若基础样式采用了ID选择器或嵌套过深,而媒体查询修正用类选择器,依然无法覆盖。实践中应维持选择器特异性层级平坦,统一用类或元素选择器,并将修正项放在更靠后的位置。故意用 !important 修正容易让维护者无法预测下一个样式是否生效,只在临时补丁可用。
容易答错的地方
- 媒体查询自带更高优先级
- 媒体查询不会让规则的优先级自动上升,它只是条件;真正决定胜负的仍是被比较的声明来源、!important与特异性。若规则放在了媒体查询里但选择器更弱,仍会被前面的普通规则推翻。
- 源码顺序一定后写覆盖前写
- 源码顺序只有在两个声明处于同一来源、重要性、特异性级别才有裁决权。若一个选择器是
.card .title,另一个只写.title,就是特异性不同,后者后写也不能覆盖前者。
面试官还会怎么问?
如果两条媒体查询命中,一条用ID选择器而另一条用类选择器,谁赢?
ID选择器特异性极高,即使它写在前面。先比较特异性,再比较源码顺序。要控制结果,应该转用同权重选择器或调整结构。
我想在小屏执行某一条覆写但不想靠源码顺序,怎么办?
把希望赢的规则写成更高特异性的选择器,例如给子元素增加一个辅助类。但这种做法会让后续改动变脆,建议保持低且均匀的特异性,用顺序控制。
prefers-color-scheme 这类媒体条件参与覆写吗?
任何条件查询都只提供命中与否,不参与级联排序。一旦命中,内部声明依然按来源、特异性和源码顺序比较,同样适用这里的原则。
参考资料
示例用于理解所注明的运行环境与边界;延伸学习可结合原文中的更多案例。