Media queries running weird because of non-integer width

前端 未结 2 545
南方客
南方客 2021-01-19 23:39

Can\'t say is it a real problem or I\'m just being paranoid but this behavior of media queries is really driving me crazy for last couple of hours.

Let\'s consider t

相关标签:
2条回答
  • 2021-01-20 00:25

    Similar layout

    The answer to this question should be to avoid the problem altogether, and simply leave one of the media queries out, and let one media query override the other:

    body {background: red;}
    
    @media (min-width: 400px)
    {
        body {background: blue;}
    }
    

    However, when you need a fundamentally different layout, this would cause a lot of additional code simply to reset one case from the other. As is the case in the following example:

    .some-element {background-color: red;border-left: 30px;}
    
    @media (max-width: 399px)
    {
        .some-element {border-left: none;padding-bottom: 40px;}
    }
    

    Whereas it would be shorter and more elegant to write:

    .some-element {background-color: red;}
    
    @media (min-width: 400px)
    {
        .some-element {border-left: 30px;}
    }
    
    @media (max-width: 399px)
    {
        .some-element {padding-bottom: 40px;}
    }
    

    But neither of the media-queries in the last example code will take effect if the width is for instance 399.5px. Read the next part of this answer, if you still wish to write such code with perfect coverage.

    Use floating-point numbers

    Unfortunately the media queries for min-width and max-width values are always inclusive. A browser uses fractional pixels when it has zooming capabilities. Therefore, a simple solution to this problem is to increment your threshold pixel value of 400px with the lowest possible fraction, for instance to 400.00001px. However, the crucial question then remains, what is the lowest possible fraction?

    The CSS specification does not say anything about which data types are used to store numbers:

    A <number> can either be an <integer>, or it can be zero or more digits followed by a dot (.) followed by one or more digits.

    But according to the answer to 'Why does Bootstrap use a 0.02px difference between screen size thresholds in its media queries?':

    Indeed, cross-browser compatibility is the reason: according to Bootstrap's source, 0.02px is used "rather than 0.01px to work around a current rounding bug in Safari.

    Apparently, bootstrap being a widely used framework, it seems that 0.02 would be the correct value to use in this specific case.

    In your case, to get a perfect coverage of your media queries - and thereby prevent a yellow background, the solution would look like this:

    body {background: yellow;}
    
    @media (max-width:400px) {
        body {background: red;}
    }
    
    @media (min-width:400.02px) {
        body {background: blue;}
    }
    

    Use CSS4

    As of CSS4 you may use intuitive operators for media queries such as >= and <= instead of min- and max-, and more importantly, additionally you may use exclusive operators such as > and < which immediately solves the problem (see here).

    However, it may not be widely supported. Unfortunately, this feature is not yet on Can I Use to check browser support. You may check it yourself using this codepen. It seems to work in the latest version of Firefox.

    The solution would then be as simple as:

    body {background: yellow;}
    
    @media (width <= 400px) {
        body {background: red;}
    }
    
    @media (width > 400px) {
        body {background: blue;}
    }
    
    0 讨论(0)
  • 2021-01-20 00:31

    A simple solution could be the following:

     body {background:yellow}
    
     @media (max-width:400px) {
       body {background:red}
     }
    
     @media (min-width:400px) {
       body {background:blue}
     }
    

    The rules in the last media query will simply overwrite any parameters that exist previously, just because of the order.

    That way there won't be a situation/width which isn't covered by these two media queries: Everything up to 399.9999... (whatever) fulfills the first condition, everything above 400 will meet the second condition, and if the width is exactly 400, the rules in the second media query will overwrite the previous ones due to their order.

    0 讨论(0)
提交回复
热议问题