6

I was working on a project and I encountered a problem. I'll show you with the following demonstration example:

This is css code:

    *, *::after, *::before {
    box-sizing: border-box;
    margin: 0;
    border: 0;
}

@media only screen and (max-width: 600px) {
    div {
        background: blue;
    }
}


@media only screen and (min-width: 601px) and (max-width: 1000px)  {
    div {
        background: green;
    }
}


@media only screen and (min-width: 1001px) {
    div {
        background: red;
    }
}

So my div should be:

  • blue from 0px to 600px
  • green from 601px to 1000px
  • red from 1001px to ...

Instead it is:

  • blue from 0px to 600px
  • white at 601px
  • green from 602px to 1000px
  • white at 1001px
  • red from 1002px to ...

Why? It seems that (min-width:) is not inclusive.

So I tried:

    *, *::after, *::before {
    box-sizing: border-box;
    margin: 0;
    border: 0;
}

@media only screen and (max-width: 600px) {
    div {
        background: blue;
    }
}


@media only screen and (min-width: 600px) and (max-width: 1000px)  {
    div {
        background: green;
    }
}


@media only screen and (min-width: 1000px) {
    div {
        background: red;
    }
}

So my div should be:

  • blue from 0px to 600px
  • green from 601px to 1000px
  • red from 1001px to ...

Instead it is:

  • blue from 0px to 599px
  • green from 600px to 999px
  • red from 1000px to ...

Why? Now seems that (min-width:) is inclusive.

But If I try:

    *, *::after, *::before {
    box-sizing: border-box;
    margin: 0;
    border: 0;
}

@media only screen and (max-width: 601px) {
    div {
        background: blue;
    }
}


@media only screen and (min-width: 601px) and (max-width: 1001px)  {
    div {
        background: green;
    }
}


@media only screen and (min-width: 1001px) {
    div {
        background: red;
    }
}

Seems that (min-width:) is not inclusive again:

  • blue from 0px to 601px
  • green from 602px to 1001px
  • red from 1002px to ...

I am confused.

10
  • What browser are you using? I don't see the behaviour that you describe when testing in Chrome. Your first example works fine: jsfiddle.net/wbqexc1h Commented Jun 13, 2018 at 12:54
  • As media queries follow the same rules of cascading as the rest of CSS, you'll get the desired effect if you reverse the order of your declarations. And yes, both min-width and max-width are inclusive Commented Jun 13, 2018 at 12:54
  • @Turnip all browser...yes there is the effect if you change the width also on jsfiddle slowly....try very very slowly Commented Jun 13, 2018 at 12:57
  • I did. It works fine for me. Commented Jun 13, 2018 at 12:58
  • Pixel widths aren't necessarily integer values. What you're seeing displayed as a "600px" screen might actually be 599.9px or 600.1px. Commented Jun 13, 2018 at 12:58

1 Answer 1

2

Both 'min' and 'max' prefixes are inclusive. Quoting the spec:

Most media features accept optional ‘min-’ or ‘max-’ prefixes to express "greater or equal to" and "smaller or equal to" constraints.

The problem is a bit different: while you expect pixel dimensions to be integer, it's not always like that. This article describes the problem in quite a bit of detail:

You might think "Half a pixel? That's not possible", and for the most part it's not. But if you use Ctrl+ or Ctrl- to change your browser zoom then you'll often end up with non-integer viewport sizes, and that non-integer viewport size can be used by the browser when working out which media queries to apply to the page [...]

On Windows 7 and higher, there is a zoom level used by the operating system for things like text and icons, and on larger screens (1920px wide for example) this will automatically be set to a 125% zoom. But IE, Edge and Firefox all inherit this 125% value in their own way and end up applying it as browser zoom, creating the conditions for this bug to appear by default on most Windows machines with decent resolution screens in the past five or six years.

Check the discussion opened on the similar issue in Bootstrap. A telling quote:

Chrome does not report decimal viewport widths even when zoomed, I assume it rounds the values when applying media queries.

Quite convenient, I suppose.

In short, I'd drop either max-width or min-width here and go with overlapping rules, letting the latter rule to be a decider.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.