如何避免媒体查询重叠



级联使CSS变得特别而强大。但在媒体查询的情况下,重叠似乎有问题。

考虑以下CSS(CSS媒体查询重叠的连续规则):

/* 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时,45em处的重叠将根据标准CSS级联处理:

  • 将首先应用所有CCD_ 1定义
  • 并且此后将应用所有CCD_ 2

考虑这两个条件:

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

因此,在宽度正好为45em的情况下,我们会得到大而红色的文本<避免这种情况的最佳解决方案是什么>


我看到两种可能性:

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

  2. 通过使用像max-width: 799pxmin-width: 800px这样的像素值来避免重叠,但您使用的是像素——我想它们可能分别是49.9375em和50em。不过,如果默认值不再是16em,有些东西被取整了怎么办?我们仍然不确定在这个差距会发生什么。(一个打破时空连续体的黑洞?)

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

为任何给定的媒体查询创建两个互斥的max-width: 45em0块的唯一可靠方法是使用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;
}
}

交互式jsFiddle演示

这在缩小与widthheight等范围媒体功能的差距方面非常有效,因为它本质上把这变成了非此即彼的场景。但是,就像您的前两个选项一样,它并不完美:如前所述,您必须重复两次相同的媒体查询,并向其中一个添加not。如条件规则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)还是使用min-width: 45em0,您最终会得到不同的结果(我也对此感到惊讶)。。。

无论哪种方式,你都是对的:选项2也有缺点。老实说,我不是特别喜欢它,因为我不想因为我无法控制的设备和用户代理怪癖而头疼。如果你和我一样,我想最好以对代码更加警惕为代价,重新制定规则,因为这至少仍在你作为作者的控制范围内。

对我来说,最好的方法是保持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 */
}

我建议您阅读这篇文章,了解不同解决方案的详细信息和比较,以防止媒体查询重叠。

干杯,托马斯。

最新更新