不能说这是一个真正的问题,或者我只是偏执狂,但媒体查询的这种行为让我在过去几个小时里疯狂。
让我们考虑一下这个非常简单的CSS。
body {background:yellow}
@media (max-width:399px) {
body {background:red}
}
@media (min-width:400px) {
body {background:blue}
}
宽度为399.333px时出现问题!(或399到400整数之间的任何浮点值)
我的逻辑说通过使用这个CSS样式的页面永远不会变黄,对吧?当视口大小小于400px宽度时应为红色,当400px及以上时视口大小为蓝色。
当页面被放大时,Opera浏览器(我现在使用36.0)在Windows上发生了奇怪的行为。我知道视口宽度是使用实际视口宽度和当前缩放级别计算的,此值应始终为整数。但...
看起来Opera并没有围绕这个影响整个页面的值/ floor / ceil。当Opera发现视口宽度不是399px或400px而它的399.333px 时,我得到黄色背景!?所以媒体查询都不符合条件。
我已经尝试在这里和网络上找到答案,但没有什么能够接近这个问题。当我使用em
单位时,我已经遇到了这个问题,所以我可以解决它并将它们转换为像素,但我无法影响用户使用浏览器缩放功能的决定
我能做些什么来防止这种或那种情况发生?
模拟此行为的最简单方法是点击CTRL,+
三次,然后轻松移动对象检查器中的垂直滑块。
是的,我可以先用"移动/桌面修复它"通过将每个媒体断点链接到前一个断点,但这不是我的问题的一部分。此外,默认body
样式仅作为视觉辅助,并且更改它实际上并不能解决问题。
答案 0 :(得分:1)
该问题的答案应该是完全避免该问题,仅将其中一种媒体查询排除在外,而让一种媒体查询覆盖另一种即可:
body {background: red;}
@media (min-width: 400px)
{
body {background: blue;}
}
但是,当您需要一种根本上不同的布局时,这将导致大量其他代码,而仅仅是将一种情况重新设置为另一种情况。如以下示例所示:
.some-element {background-color: red;border-left: 30px;}
@media (max-width: 399px)
{
.some-element {border-left: none;padding-bottom: 40px;}
}
写起来会更短更优雅:
.some-element {background-color: red;}
@media (min-width: 400px)
{
.some-element {border-left: 30px;}
}
@media (max-width: 399px)
{
.some-element {padding-bottom: 40px;}
}
但是,如果宽度为399.5px
,则上一个示例代码中的所有媒体查询都不会生效。如果您仍然希望编写覆盖范围很广的代码,请阅读此答案的下一部分。
不幸的是,媒体查询的最小宽度和最大宽度值始终包含在内。浏览器具有缩放功能时,会使用小数像素。因此,解决此问题的简单方法是将您的阈值像素值400px
以尽可能小的分数增加,例如增加到400.00001px
。但是,关键问题仍然是,最低的分数是多少?
The CSS specification并没有说明用于存储数字的数据类型:
<number>
可以是<integer>
,也可以是零个或多个数字,后跟一个点(。),然后是一个或多个数字。
但是根据对'Why does Bootstrap use a 0.02px difference between screen size thresholds in its media queries?'的回答:
真正的跨浏览器兼容性是原因:根据Bootstrap的消息来源,使用0.02px“而不是0.01px来解决Safari中当前的舍入错误。
显然,引导程序是一种广泛使用的框架,在这种特定情况下,似乎0.02是正确的值。
对于您而言,要完全覆盖您的媒体查询-从而防止出现黄色背景,解决方案应如下所示:
body {background: yellow;}
@media (max-width:400px) {
body {background: red;}
}
@media (min-width:400.02px) {
body {background: blue;}
}
从CSS4开始,您可以对诸如>=
和<=
之类的媒体查询使用直观的运算符,例如min-
和max-
,更重要的是,您可以使用独占>
和<
之类的运算符可立即解决问题(see here)。
但是,它可能未得到广泛支持。不幸的是,this feature is not yet on Can I Use检查浏览器支持。您可以自己使用this codepen进行检查。似乎可以在最新版本的Firefox中使用。
解决方案将非常简单:
body {background: yellow;}
@media (width <= 400px) {
body {background: red;}
}
@media (width > 400px) {
body {background: blue;}
}
答案 1 :(得分:1)
以下是一个简单的解决方案:
body {background:yellow}
@media (max-width:400px) {
body {background:red}
}
@media (min-width:400px) {
body {background:blue}
}
由于顺序,最后一个媒体查询中的规则将简单地覆盖以前存在的任何参数。
这样,这两个媒体查询就不会出现这种情况/宽度:399.9999 ...以下的所有内容都满足第一个条件,400以上的所有内容都满足第二个条件,并且如果宽度恰好是400,则第二个媒体查询中的规则由于顺序而将覆盖先前的规则。