Why does the order of media queries matter in CSS?
Asked Answered
R

6

98

Of late, I've been designing sites that are more responsive and I've been using CSS media queries frequently. One pattern I noticed is that the order in which the media queries are defined actually matters. I didn't test it in every single browser, but just on Chrome. Is there an explanation for this behaviour? Sometimes it gets frustrating when your site doesn't work as it should and you are unsure if it's the query or the order in which the query is written.

Here's an example:

HTML

<body>
    <div class="one"><h1>Welcome to my website</h1></div>
    <div class="two"><a href="#">Contact us</a></div>
</body>

CSS:

body{
font-size:1em; /* 16px */
}

.two{margin-top:2em;}



/* Media Queries */

@media (max-width: 480px) {
    .body{font-size: 0.938em;}

}
/* iphone */
@media only screen and (-webkit-min-device-pixel-ratio: 2) {
    body {font-size: 0.938em;}
}
/*if greater than 1280x800*/
@media (min-width: 1200px) {
       .two{margin-top:8em;}
            }
/*1024x600*/
@media (max-height: 600px) {
       .two{margin-top:4em;}
}
/*1920x1024*/
@media (min-height: 1020px) {
       .two{margin-top:9em;}
}
/*1366x768*/
@media (min-height: 750px) and (max-height: 770px) {
       .two{margin-top:7em;}
}

However, If I wrote the query for 1024x600 in the last, the browser would ignore it and apply the margin value specified in the starting of the CSS (margin-top:2em).

/* Media Queries - Re-arranged version */

@media (max-width: 480px) {
    .body{font-size: 0.938em;}
}
/* iphone */
@media only screen and (-webkit-min-device-pixel-ratio: 2) {
    body {font-size: 0.938em;}
}
/*if greater than 1280x800*/
@media (min-width: 1200px) {
       .two{margin-top:8em;}
}
/*1920x1024*/
@media (min-height: 1020px) {
       .two{margin-top:9em;}
}
/*1366x768*/
@media (min-height: 750px) and (max-height: 770px) {
       .two{margin-top:7em;}
}
 /*1024x600*/
@media (max-height: 600px) {
       .two{margin-top:4em;}
}

If my understanding of media queries are correct, the order shouldn't matter, but it seems it does. What could be the reason?

Rolfston answered 9/1, 2012 at 14:56 Comment(0)
F
167

That's by design of CSS — Cascading Style Sheet.

It means that, if you apply two rules that collide to the same elements, it will choose the last one that was declared, unless the first one has the !important marker or is more specific (e.g. html > body vs just body, the latter is less specific).

So, given this CSS

@media (max-width: 600px) {
  body {
    background: red;
  }
}

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

if the browser window is 350 pixels wide, the background will be blue, while with this CSS

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

@media (max-width: 600px) {
  body {
    background: red;
  }
}

and the same window width, the background will be red. Both rules are indeed matched, but the second one it's the one that is applied because is the last rule.

Finally, with

@media (max-width: 400px) {
  body {
    background: blue !important;
  }
}

@media (max-width: 600px) {
  body {
    background: red;
  }
}

or

@media (max-width: 400px) {
  html > body {
    background: blue;
  }
}

@media (max-width: 600px) {
  body {
    background: red;
  }
}

the background will be blue (with a 350 pixels wide window).

Fullbodied answered 9/1, 2012 at 16:58 Comment(4)
Thank you. I never imagined such a simple logic would ruin my sleep for nights together. Thanks.Rolfston
In a style sheet if same rules are applied without any media query and then within a media query for small screen mobile deices and there are some images to down load. So what would be happened, does browser will ignore the rules without media query and apply only specific media query's rules?Fredra
Is there a programmatic way to find out which media-query (between multiple matched-queries) will overcome over others? I mean something like matchMedia() function that gets an array of queries and returns only one (or none) ... or even sorts them based on the priority.Analects
@Analects — I'm not aware of a programmatic way (nor can I really see a use for one) but the DOM Inspector features of the developer tools in most browsers will show you which rules are applied to any given element and will indicate which are overridden.Neoptolemus
M
24

Or you could just add min-width to the bigger media query/ies and not have any issues, regardless of the order.

@media (min-width: 400.1px) and (max-width: 600px) {
  body {
    background: red;
  }
}

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

Using this code, in any order, the background-color will always be red for resolutions with a width of 400.1px-600px, and will always be blue for resolutions with a width of 400px or less.

Messmate answered 6/11, 2014 at 15:58 Comment(6)
I cringe at the sight of a value like 400.1px in CSS. Or 1023px, 1025px etc.Moldy
@Moldy what's wrong with 1023px or 1025px?Dingdong
@Dingdong It's indicative of a hack job, rather than logically correct CSS.Moldy
@Moldy Yikes, I've always used the "hack job" method. What is your preferred method in this situation?Watterson
@BrianC You should be able to logically structure the conditions such that you get the desired outcome with rounded resolution values, without relying on *99px or *.1px conditions.Moldy
Is there a scenario where a device / screen had half-pixels? In that case, this 0.1 thing could be a paranoid way of making sure there isn't any case, where none of the layouts apply - but this should only be a problem with ranges. Max-width: 400, max-width: 600 ... has the benefit of always having a "fallback".Zoba
B
1

Encourage you to follow the principle of mobile-first design. That means that your base styles are the mobile styles (phones held vertically), then write min-width media queries where necessary at the following breakpoints and in the following order:

  • base styles - phones held vertically
  • min-width: 500px - overrides for phones held horizontally
  • min-width: 750px - overrides for ipads held vertically
  • min-width: 1000px - overrides for ipads held horizontally
  • min-width: 1250px - overrides for laptops and desktops
Backfield answered 9/11, 2023 at 5:19 Comment(0)
O
0

<body>
    <div id="div1">
        <p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Illo similique minus facere error sunt tenetur deleniti debitis esse animi dolores repudiandae assumenda incidunt ipsa odio sapiente, omnis expedita aliquam sequi, cum reprehenderit? Asperiores aut officia dolorem voluptatem natus ipsum voluptates fuga odio qui velit et fugit consectetur esse obcaecati id, repudiandae alias delectus eveniet assumenda. Facere ex ea rem assumenda, in sequi animi quibusdam necessitatibus, totam error sed officia vel at maxime voluptate nam ipsam, provident aperiam nobis minus voluptates inventore? Voluptates minima debitis, qui architecto eius natus minus consectetur blanditiis unde suscipit tempore, nulla, fugit magni molestias odio doloribus!</p>
    </div>
</body>

Or you could just write that in Different Order i.e. Write a bigger media query first and then the smaller ones.

@media screen and (max-width: 900px) {  /* CSS runs from top to bottom  */
    #div1{
        background-color: red;
    }
}

@media screen and (max-width: 600px) {
    #div1{
        background-color: blue;
    }
}

Now, As you gradually going to decrease the size of the screen i.e. if the size of the screen is 601px (which is more than 600px but less than 900px) then, the background color will be "red" in that case. Similarly, if the screen size is 599px (which is less than both 600px and 900px) then the later one going to apply i.e. background becomes "blue". So, it checks each condition as you gradually decrease the screen size from top to bottom.

Orpha answered 18/7, 2023 at 19:18 Comment(0)
J
0

while applying max-width, higher pixel should be added first and lower pixels should be below

Jannette answered 9/11, 2023 at 5:12 Comment(1)
As it’s currently written, your answer is unclear. Please edit to add additional details that will help others understand how this addresses the question asked. You can find more information on how to write good answers in the help center.Manoeuvre
C
-1

I may be dumb but why not:

@media (max-width: 399px) {
  body {
    background: blue;
  }
}

@media (min-width: 400px) and (max-width: 600px) {
  body {
    background: red;
  }
}
Culbertson answered 3/4, 2023 at 16:17 Comment(2)
While that is an approach for keeping the rules in that order and having them apply as expected … you haven't answered the question that was asked.Neoptolemus
Yes, but it doesn't matter which order the statements are in, the result is the same. The order only matters if the specificity is equal.Culbertson

© 2022 - 2024 — McMap. All rights reserved.