101

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

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

@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 的屏幕宽度呢?(显然不是在常规显示器上,而是在视网膜显示器上?)


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

4

3 回答 3

120

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: none并将float: left应用于任何具有 class 的元素.sidebar

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

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

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

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

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

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

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

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

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

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

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


1尽管在 Conditional Rules 模块Cascade 模块(后者目前计划重写)中都没有明确说明,但级联暗示正常发生,因为规范只是说在任何以及与浏览器或媒体匹配的所有规则。@media

于 2012-11-28T18:01:35.093 回答
12

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

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

但发现这不是一个好主意,因为它现在不能在我的 Ubuntu 桌面或我的 Android 手机上的 Chrome 上运行。(如此处所述:calc() 在媒体查询中不起作用)但是,我找到了更好的方法......

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

和砰!

于 2018-09-21T15:18:35.973 回答
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单元将有助于您的查询堆叠。

于 2012-12-12T19:12:36.713 回答