CSS媒体查询重叠的规则是啥?

Posted

技术标签:

【中文标题】CSS媒体查询重叠的规则是啥?【英文标题】:What are the rules for CSS media query overlap?CSS媒体查询重叠的规则是什么? 【发布时间】:2012-10-25 20:16:56 【问题描述】:

我们如何准确地分隔媒体查询以避免重叠?

例如,如果我们考虑代码:

@media (max-width: 20em) 
    /* for narrow viewport */


@media (min-width: 20em) and (max-width: 45em) 
    /* slightly wider viewport */


@media (min-width: 45em) 
    /* everything else */

在所有支持的浏览器中,恰好 20em 和 45em 会发生什么?

我见过人们使用:799px 和 800px 之类的东西,但是 799.5 px 的屏幕宽度呢? (显然不是在常规显示器上,而是在视网膜显示器上?)

考虑到规范,我对这里的答案非常好奇。

【问题讨论】:

您当前的问题标题似乎与您的要求不符。您的问题内容的第一行似乎更适合作为标题:) @BoltClock,一如既往的感谢——我把它们调换了;但是您如何解释“分隔媒体查询”? @Baumr:问得好——实际上,我不太明白你的意思。剩下的问题我明白了,我正在写一个答案。 我假设如果你的宽度正好是 20em,那么它将首先应用 max-width: 20em 定义,然后也应用 min-width: 20em 定义。 @Baumr,我相信它只是级联一般的 CSS 声明。由于 20em 的宽度满足两个查询,因此将应用两个查询定义。 【参考方案1】:

CSS媒体查询重叠的规则是什么?

级联。

@media 规则对级联是透明的,所以当两个或多个@media 规则同时匹配时,浏览器应该应用所有匹配的规则中的样式,并相应地解析级联。 1

在所有支持的浏览器中,恰好 20em 和 45em 会发生什么?

在 20em 宽处,您的第一个和第二个媒体查询都将匹配。浏览器将在@media 规则和相应的级联中应用样式,因此如果有任何需要覆盖的冲突规则,最后声明的规则将获胜(考虑特定的选择器,!important 等)。当视口正好是 45em 宽时,第二个和第三个媒体查询也是如此。

考虑到您的示例代码,添加了一些实际的样式规则:

@media (max-width: 20em) 
    .sidebar  display: none; 


@media (min-width: 20em) and (max-width: 45em) 
    .sidebar  display: block; float: left; 

当浏览器视口正好是 20em 宽时,这两个媒体查询都将返回 true。通过级联,display: block 覆盖 display: nonefloat: left 将应用于具有类 .sidebar 的任何元素。

您可以将其视为应用规则,就好像媒体查询一开始就不存在一样:

.sidebar  display: none; 
.sidebar  display: block; float: left; 

当浏览器匹配两个或多个媒体查询时如何发生级联的另一个示例可以在this other answer 中找到。

但请注意,如果您的声明 在两个 @media 规则中重叠,则所有这些规则都将适用。这里发生的是@media 规则中声明的联合,而不仅仅是后者完全推翻了前者......这将我们带到您之前的问题:

我们如何准确地分隔媒体查询以避免重叠?

如果您希望避免重叠,您只需编写互斥的媒体查询。

请记住,min-max- 前缀表示“最小包含”和“最大包含”;这意味着 (min-width: 20em)(max-width: 20em) 都将匹配正好 20em 宽的视口。

看起来您已经有了一个示例,这将我们带到您的最后一个问题:

我见过人们使用:799px 和 800px 之类的东西,但是 799.5 px 的屏幕宽度呢? (显然不是在常规显示器上,而是在视网膜显示器上?)

这个我不完全确定; CSS 中的所有像素值都是逻辑像素,我一直很难找到一个浏览器可以报告视口宽度的小数像素值。我尝试过使用一些 iframe,但无法提出任何建议。

从我的实验来看,ios 上的 Safari 似乎会对所有小数像素值进行四舍五入,以确保 max-width: 799pxmin-width: 800px 中的任何一个都匹配,即使视口确实是 799.5 像素(显然与前者匹配)。


1尽管在Conditional Rules module 或Cascade module(后者目前计划重写)中都没有明确说明,但级联隐含在正常发生,因为规范只是说在任何和所有匹配浏览器或媒体的@media 规则中应用样式。

【讨论】:

@Baumr:没问题,虽然我还没有完成——我错过了你关于重叠媒体查询的问题。我已经更新了我的答案,并且我称之为一个晚上。哦,只是为了好玩:媒体查询是我最喜欢的 CSS 主题之一,但我无法忍受 RWD 一词;) BoltClock,这可能是我第一次使用“RWD”——已经注意到你的冷遇了,哈哈!晚安,但是当您返回时,请查看我对原始问题所做的更新。现在来看看你的更新... BoltClock,我应该取出那个更新并将其变成自己的问题吗?我觉得我做的很复杂 @Baumr:是的,这样会好很多。 BoltClock:我把它拿出来放在一个更简洁的问题中:How to avoid media query overlap?——如果你有任何编辑建议使它更适用于其他人,请分享。 附言它不会让我在 cmets 中@你。【参考方案2】:

我已经按照这里的建议尝试过:

@media screen and (max-width: calc(48em - 1px)) 
    /*mobile styles*/

@media screen and (min-width: 48em) 
    /*desktop styles*/

但发现这不是一个好主意,因为它现在不能在我的 Ubuntu 桌面或我的 android 手机上的 Chrome 上运行。 (此处解释:calc() not working within media queries)但是,我找到了更好的方法...

@media screen and (max-width: 47.9999em) 
    /*mobile styles*/

@media screen and (min-width: 48em) 
    /*desktop styles*/

然后砰!

【讨论】:

这应该是公认的答案。 BoltClock 提供了迂腐的答案,但这个答案是最有用的!【参考方案3】:

calc() 可用于解决此问题,(min-width: 50em and max-width: calc(50em - 1px) 将正确堆叠),但浏览器支持不佳,我不推荐它。

@media (min-width: 20em) and (max-width: calc(45em - 1px)) 
    /* slightly wider viewport */

信息:

https://developer.mozilla.org/en-US/docs/CSS/calc http://caniuse.com/calc http://www.w3.org/TR/css3-values/#calc

其他一些人提到,不使用em 单元将有助于您的查询堆叠。

【讨论】:

calc() 不是媒体查询规范的一部分,因此不起作用。

以上是关于CSS媒体查询重叠的规则是啥?的主要内容,如果未能解决你的问题,请参考以下文章

如何避免媒体查询重叠?

没有媒体类型的@media 规则是啥?

CSS媒体查询中的“唯一屏幕”代码是啥意思? [复制]

IE 的 CSS 选择器限制中如何计算媒体查询?

CSS3 @Media 媒体查询

CSS3 @Media 媒体查询