如何避免媒体查询重叠?

时间:2012-11-29 20:39:01

标签: css css3 responsive-design media-queries fluid-layout

级联是使CSS特别强大的原因。但在媒体查询的情况下,重叠可能似乎有问题。

考虑以下CSS(继续rules for CSS media query overlap):

/* Standard - for all screens below 20em */

body { color: black; font-size: 1em; }

/* Query A - slightly wider, mobile viewport */

@media (min-width: 20em) and (max-width: 45em) {
    body { color: red; } /* supposed to be unique for this width */
}

/* Query B - everything else */

@media (min-width: 45em) {
    body { font-size: larger; } /* because viewport is bigger */
}

因此,当屏幕正好是45em宽时,根据标准CSS级联在45em will be treated重叠:

  • 首先应用所有max-width: 45em定义,
  • 此后将应用所有min-width: 45em

考虑以下两个条件:

  • 所有文字通常都是black,但查询A 是唯一的,并且color: red
  • 由于查询B 适用于较大的视口,因此其文本具有CSS font-size: larger

因此,在45em的宽度处,我们会得到大文本和红色文本避免这种情况的最佳解决方案是什么?


我看到两种可能性:

  1. 重新声明文本在查询B 中有color: black,但如果您选择更改color,则会管理两个声明未来。 (当然,这一行代码没有这个问题,但想象一下还有很多其他声明和选择器。)

  2. 使用像max-width: 799pxmin-width: 800px这样的像素值避免重叠,但之后你会使用像素 - 我猜它们分别是49.9375em和50em。虽然如果默认值不再是16em并且某些内容被四舍五入怎么办?我们still not certain在那个差距发生了什么。 (一个打破时空连续体的黑洞?)

  3. 两者都有缺点......还有其他想法吗?

2 个答案:

答案 0 :(得分:10)

为任何给定的媒体查询创建两个互斥@media块的唯一可靠方法是使用not在其中一个块中取消它。不幸的是,这意味着每个@media块都会重复一次媒体查询。所以,而不是例如:

@media (max-width: 49.9375em) {
    body {
        color: red;
    }
}

@media (min-width: 50em) {
    body {
        font-size: larger;
    }
}

你会有这个:

/* 
 * Note: Media Queries 4 still requires 'not' to be followed by a
 * media type (e.g. 'all' or 'screen') for reasons I cannot comprehend.
 */
@media not all and (min-width: 50em) {
    body {
        color: red;
    }
}

@media (min-width: 50em) {
    body {
        font-size: larger;
    }
}

Interactive jsFiddle demo

这在缩小与widthheight等范围媒体功能的差距方面非常有效,因为它实际上将其转变为一种或两种情况。但是,与前两个选项一样,它并不完美:如上所述,您必须重复相同的媒体查询两次,并将not添加到其中一个。如Conditional Rules 3中所述,@media没有if / else结构。


虽然我在回答你上一个问题时提到过这个问题:

  

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

应该注意的是,在圆角方面,我注意到了一些怪癖。也就是说,我无法找到一个小数值来逃避两个媒体查询并最终没有从任何一组规则接收样式(顺便说一下,这是最糟糕的发生了,所以不要担心可能造成时空裂痕)。这必须意味着浏览器 - 至少是我测试过的Safari - 做一个合理的工作,确保它们满足媒体查询,即使你有不同的值(只有1个CSS像素)。

对于具有较大间隙的单元,可以在桌面浏览器上观察到,但是,与ems一样,存在更大的误差范围。例如,一条评论建议使用49.99999em而不是比49.9375em更随意的东西,但显然存在差异,至少默认字体大小为16px。

我简化了你的代码,更改了媒体查询以使用十进制值,并将代码放在jsFiddle中:

@media (max-width: 49.9375em) {
    body {
        color: red;
    }
}

@media (min-width: 50em) {
    body {
        font-size: larger;
    }
}

如果您将“结果”窗格的大小精确调整为800像素(文本将更新以引导您),您实际上会得到不同的结果,具体取决于@media (max-width: 49.9375em) is used还是@media (max-width: 49.99999em) is used(我很惊讶通过这个)...

无论哪种方式,你都是对的:选项2也有其缺点。说实话,我并不是特别喜欢它,因为我不想对我无法控制的设备和用户代理怪癖感到头疼。如果你像我一样,我认为最好不要再为了代码更加警惕重新规范你的规则(?),因为这至少仍然在你作为作者的控制之内。

答案 1 :(得分:0)

对我来说,最好的方法是保持0.01em的差距:

@media (min-width: 20em) and (max-width: 44.99em) {
    body { color: red; } /* supposed to be unique for this width */
}
@media (min-width: 45em) {
    body { font-size: larger; } /* because viewport is bigger */
}

我建议您阅读本文,了解different solutions to prevent media query overlapping

的详细信息和比较

干杯, 托马斯。