如何避免媒体查询重叠?
Posted
技术标签:
【中文标题】如何避免媒体查询重叠?【英文标题】:How can I avoid media query overlap? 【发布时间】:2012-11-18 00:44:30 【问题描述】:级联使 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 的宽度上,我们会得到大而红色的文本。 避免这种情况的最佳解决方案是什么?
我看到了两种可能性:
在 查询 B 中重新声明文本以具有 color: black
,但是如果您选择在将来更改 color
,那么您将管理两个声明。 (当然,这一行代码没有这样的问题,但想象一下还有很多其他的声明和选择器。)
通过使用像max-width: 799px
和min-width: 800px
这样的像素值来避免重叠,但是你使用的是像素——我猜它们可能分别是49.9375em和50em。虽然如果默认值不再是 16em 并且某些东西被四舍五入怎么办?我们是still not certain 在那个间隙发生了什么。 (打破时空连续性的黑洞?)
两者都有各自的缺点......还有其他想法吗?
【问题讨论】:
你分析过度了:你永远不会写出那样的样式。媒体查询通常用于处理相关视口的元素。没有理由选择像 49.9375em 这样的数字作为断点而不是 49.99999em。 @cimmanon,我的意思更多是作为一个侧面(随意忽略奇怪的em
值,只是为了保持问题的一致性——我考虑在@987654335 中写下整个问题@但我更喜欢em
)
@Baumr--我认为 cimmanon 的观点是你应该使用你的#2 解决方案,但在max-width
上将值设置为49.99999em
,这样你就不应该有“差距”处理(就像你可能处理的49.9375em
)。
浏览器在计算像素值时会四舍五入,据我所知,50em
仍然适用。
【参考方案1】:
为任何给定的媒体查询创建两个互斥的@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
这对于缩小与width
和height
等范围媒体功能之间的差距非常有效,因为它本质上将这变成了一个非此即彼的场景。但是,就像您的前两个选项一样,它并不完美:如前所述,您必须重复两次相同的媒体查询,并将not
添加到其中一个。 @media
没有 if/else 构造,如 Conditional Rules 3 中所述。
虽然我在回答您之前的问题时提到了这一点:
从我的实验来看,ios 上的 Safari 似乎会对所有小数像素值进行四舍五入,以确保
max-width: 799px
和min-width: 800px
中的任何一个都匹配,即使视口确实是 799.5 像素(显然与前者匹配)。
仍然应该指出,在舍入时我注意到了一些怪癖。也就是说,我还没有找到一个可以规避 both 媒体查询并最终无法从任何一组规则中接收样式的小数值(顺便说一句,这是最糟糕的发生,所以不要担心可能会造成时空裂痕)。这一定意味着浏览器——至少,我测试过的 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 也有其缺点。老实说,我并不是特别喜欢它,因为我不想在我无法控制的设备和用户代理怪癖上大发雷霆。如果您像我一样,我想最好还是以对您的代码更加警惕为代价(?)来重新声明您的规则的不便,因为这至少仍在您作为作者的控制范围内。
【讨论】:
谢谢!在您的第一段中,我是否理解正确:做我在问题中所做的事情应该没问题?只是为了澄清。此外,毫无疑问,您对重新声明规则的建议是简单情况下的一种选择,但如果这些查询变得更加复杂,那么对于大型网站(目前不是我的情况)可能会出现问题。我开始觉得这是min-width
和max-width
在媒体查询中使用的限制。或许像 below-width
和 above-width
这样的声明可能对除有用——允许选择高于某个特定值的所有值,除了它。
@Baumr:您对below-width
和above-width
的建议给了我一个想法,但我不确定它是否符合您的要求。完成后查看编辑。
哇,真是个好答案!我正在考虑创建另一个帐户并再次对其进行投票;D 谢谢博尔特!
@Baumr:暂停这样的事情会非常尴尬 :) 你总是可以奖励赏金!
有关于这个话题的消息吗?浏览器是否开始在缩放方面以相同的方式处理 px 和 em 媒体查询?是否找到了重叠问题的解决方案?谢谢!【参考方案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 */
我建议您阅读这篇文章以了解详细信息以及different solutions to prevent media query overlapping的比较。
干杯, 托马斯。
【讨论】:
以上是关于如何避免媒体查询重叠?的主要内容,如果未能解决你的问题,请参考以下文章
Styled Components - 内联样式与媒体查询样式重叠