由于非整数宽度

时间:2017-01-03 17:51:37

标签: css media-queries page-zoom

不能说这是一个真正的问题,或者我只是偏执狂,但媒体查询的这种行为让我在过去几个小时里疯狂。

让我们考虑一下这个非常简单的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样式仅作为视觉辅助,并且更改它实际上并不能解决问题。

2 个答案:

答案 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

从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,则第二个媒体查询中的规则由于顺序而将覆盖先前的规则。