Why Does the Order of Media Queries Matter in Css

Why does the order of media queries matter in CSS?

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).

CSS media queries - Order matters?

My answer on how you should use media queries can be applied to your question:

Here is how you should use media queries:

Remember use the sizes you like/need. This below is just for demo
purposes.

Non-Mobile First Method using max-width:

/*==========  Non-Mobile First Method  ==========*/

@media only screen and (max-width: 960px) {
/*your CSS Rules*/
}
@media only screen and (max-width: 768px) {
/*your CSS Rules*/
}
@media only screen and (max-width: 640px) {
/*your CSS Rules*/
}
@media only screen and (max-width: 480px) {
/*your CSS Rules*/
}
@media only screen and (max-width: 320px) {
/*your CSS Rules*/
}

Mobile First Method using min-width:

/*==========  Mobile First Method  ==========*/

@media only screen and (min-width: 320px) {
/*your CSS Rules*/
}
@media only screen and (min-width: 480px) {
/*your CSS Rules*/
}
@media only screen and (min-width: 640px) {
/*your CSS Rules*/
}
@media only screen and (min-width: 768px) {
/*your CSS Rules*/
}
@media only screen and (min-width: 960px) {
/*your CSS Rules*/
}

Here is a good tutorial from W3.org


Based on your edited question:

I guess this depends on each developer and how they need/think to develop his/her project.

Here is what I use to do ** (when not not using Pre-compliers)**:

I create a file styles.css which includes the general styles that will apply to the project like this:

/*==========  All Screens  ==========*/
{
/*General CSS Rules*/
}

Then having the media queries below, either using the non-mobile or mobile approach method explained above (in my case I usual use the non-mobile approach method).

But, depending on the projects you may need to have some other breaks besides the "standard" which can led you to use the rules in the way you mentioned.

Plus there are developers who prefer to separate into 2 files, the one with general styles CSS and other one with media queries styles.

Important: There is one difference from creating a file with general styles + 1 media queries (min-width:800px or max-width:799px), then only having a file with 2 media queries (min-width:800px/max-width:799px), which is when you have the general rules it will apply to ALL widths, therefore you just need to set the rules for 1 media queries.


Based on your last comment, the answer I could give you would be opinion-wised, so the best I can do for you is to give you a few articles so you can have your own opinion on this topic:

How many media queries is too many?

Web Performance: One or thousands of Media Queries?

Debunking Responsive CSS Performance Myths

Why do I have to put media queries at the bottom of the stylesheet?

Because css is read from top to bottom. The rule that is set last, is the one that will be executed.

Translating, it is like this:

@media (max-width: 600px) { //If my screen fits this size
.text {
color: red; //Paint it red
}
}

.text {
color: yellow; //Now, forget about everything and paint it yellow!
}

When you add !important is like saying:

@media (max-width: 600px) { //If my screen fits this size
.text {
color: red !important; //Paint it red, and don't change it ever!!!
}
}

.text {
color: yellow; //Ok, I'm not going to paint it yellow....
}

Why media queries has less priority than no media queries css

This has to do with the way the Cascade in CSS works. When two conflicting rules target the same element, the browser uses the rules of the cascade to determine which one to apply.

Selector specificity is the most important part of this: styles with a more specific selector will override those with a less-specific selector... but
media queries do not change the specificity of your selectors. This means that your two selectors have the same specificity. When that happens, the one appearing later in your stylesheet will override the earlier one.

Your easiest and best fix is to swap the order of your rulesets:

.logo img{
width: 100%;
}

@media screen and (min-width: 100px) and (max-width: 1499px) {
.logo img {
width: 120%;
}
}

This way, the media query comes later, and will override the earlier rule when the media query matches the viewport size.


If that's not an option for some reason, you will need to increase the selector specificity of the rule you want to win. Changing it to the following would work:

@media screen and (min-width: 100px) and (max-width: 1499px) {
.logo img {
width: 120%;
}

}
.logo a img{
width: 100%;
}

This way the selector now has two tags and a class, or [0,1,2], making it more specific than one tag and one class, or [0,1,1] (the zero in each of those indicates no ids, which are highly specific).


Do not use !important to fix specificity issues like this. If you need to override the style again elsewhere, the only way to do it is to add another !important. This will eventually lead to !importants all over the place, and then you will still need to deal with the specificity of the selectors.

why i have to write my media query at the end of my css.Is there any sequence to write media query from larger to smaller screen size?

You have to write your media as below.

Learn here:https://www.w3schools.com/cssref/css3_pr_mediaquery.asp

See here:https://jsfiddle.net/r60xs5j7/3/

@media only screen and (max-width: 767px) {body{background:#fff;}  }
@media only screen and (max-width: 992px) {body{background:blue;} }
@media only screen and (min-width: 1200px) {body{background:red;} }

and whenever you put them in css they have to work(Except for a case of override that you will need use !important)

See here(end of css):https://jsfiddle.net/r60xs5j7/5/

Note!

You need this meta in head tag to make media query works:

<meta name="viewport" content="width=device-width, initial-scale=1">

Media queries: Overriding CSS rules vs defining screen specific CSS rules

<link> tags with unmatched media queries are download with low priority so that they don't block page rendering, but are still downloaded in order to be available in case media properties change (for example by rotating a smartphone or by zooming out a desktop browser). There is an advantage in having separate stylesheets for different media types, but there is also a disadvantage in creating multiple HTTP requests.

Media blocks inside a stylesheet are already downloaded and I would assume that they are compiled anyway, so it's not really the same as a media query in the tag. But if a certain set of rules is only relevant to a certain width and is always overriden in wider screens, it makes sense to tell the browser that by encapsulating it inside a media query. It's not just about the original page rendering but about any change to the window or to the DOM that requires a redraw - the less rules the browser would need to evaluate, the faster it would be.

Why is !important needed for h1 element media query to work?

Because there is a later style that will override it and it's the one in the last media query:

@media screen and (max-width: 1199px) {
h1 {
font-size: 2rem;
}
}

So if we only consider the styles of your h1 we have this CSS: