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

时间:2012-11-05 22:37:42

标签: css css3 responsive-design media-queries

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

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

@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像素呢? (显然不是常规显示器,而是视网膜显示器?)


考虑到规范,我对此答案最为好奇。

3 个答案:

答案 0 :(得分:90)

  

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像素呢? (显然不是常规显示器,而是视网膜显示器?)

我不完全确定; CSS中的所有像素值都是逻辑像素,我很难找到一个报告视口宽度的小数像素值的浏览器。我已经尝试过试验一些iframe,但却无法想出任何东西。

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


1 虽然Conditional Rules moduleCascade module(后者目前正在进行重写)中没有明确说明这一点,级联暗示通常会发生,因为规范只是说在任何和所有与浏览器或媒体匹配的@media规则中应用样式。

答案 1 :(得分:2)

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

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

的相关信息:

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

答案 2 :(得分:1)

我已按照此处的建议进行尝试:

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

,但发现这不是一个好主意,因为它目前无法在Chrome上在我的Ubuntu桌面或Android手机上运行。 (如此处的说明:calc() not working within media queries)但是,我找到了一种更好的方法...

@media screen and (max-width: 47.9999em) {
    /*mobile styles*/
}
@media screen and (min-width: 48em) {
    /*desktop styles*/
}

还有ba!