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.

Andrea Simone Costa
  • 1,164
  • 6
  • 16

1 Answers1

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.

raina77ow
  • 103,633
  • 15
  • 192
  • 229