Why does the order of media queries matter in CSS? - css

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">Contact us</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?

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

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.

Related

I was told I can't use max-width and have to use min-width in css

This is with #media screen and (max-width:700px) {
https://i.gyazo.com/eab7c69146b5d47f3ce9adefae6e712d.png
When I do #media screen and (min-width:700px) { It gets screwed up. How do I change it to min-width without it messing up?
https://gyazo.com/3c27f20efe29a4cf001bf531dac59405.png
Use this code
#media only screen and (min-width: 700px) {
}
this will surly help you
You can use both min-widht and max-width and also combine them if you want.
min-width example:
#media screen and (min-width: 576px) {
body {
background-color: lightgreen;
}
}
max-width example:
#media screen and (max-width: 767.98px) {
body {
background-color: lightgreen;
}
}
min-width and max-width combination example:
#media (min-width: 576px) and (max-width: 767.98px) {
body {
background-color: lightgreen;
}
}
Note that I used 767.98px for the max-width because the next media rule would be for example #media (min-width: 768px) and (max-width: 991.98px) {}.
Read more about media rules here. You can also view how media rules are used in bootstrap here.

Is there any way to use OR condition in CSS media query

I am applying this`
#media screen and (max-width: 800px OR max-height: 600px) {
...
}
It's comma separated
#media (max-width: 600px), (min-width: 800px) {
html { background: red; }
}

#media queries in CSS

I have the following CSS to align page content within different brower sizes. However or some reason it does not like the first #media statement, in other words changing anything in there does not do anything to the layout. I use http://quirktools.com/screenfly/ to verify the layout.
Changing the sequence of the statements will mess things up as well. I am lost
Your help is greatly appreciated
Thanks
#media (min-width: 500px) and (max-width: 820px) {
CSS HERE
}
#media (min-width: 830px) and (max-width: 1025px) {
CSS HERE
}
#media (min-width: 1026px) and (max-width: 1580px) {
CSS HERE
}
#media (min-width: 1590px) and (max-width: 2000px) {
CSS HERE
}
First you want to define a screen size for anything larger than, from there you make your media queries for the sizes in between.
Here is an example.
/* Large desktop */
#media only screen and (min-width :75.000em) {
.test {
display: none;
}
}
/* Portrait tablet to landscape and desktop */
#media only screen and (min-width :61.250em) and (max-width:74.938em) {
.test {
display: block;
color: #FF0;
}
}
/* Portrait tablet to landscape and desktop */
#media only screen and (min-width :48.000em) and (max-width:61.188em) {
.test {
display: none;
}
}
/* Landscape phone to portrait tablet */
#media only screen and (min-width :30.063em) and ( max-width :47.938em) {
.test {
display: none;
}
}
/* portrait phones and down */
#media only screen and (max-width :30.000em) {
.test {
display: block;
color: #FF0;
}
}
<meta name="viewport" content="width=device-width initial-scale=1" />
Include above code into html to run media query.
You need to set your first one to say "anything smaller than (max-width: 829px), do this"
For EG:
#media (max-width: 829px) {
.bg {background-color:blue;}
}
#media (min-width: 830px) and (max-width: 1025px) {
.bg {background-color:red;}
}
#media (min-width: 1026px) and (max-width: 1580px) {
.bg {background-color:green;}
}
#media (min-width: 1590px) and (max-width: 2000px) {
.bg {background-color:yellow;}
}
See it in effect at this Plunker - I added the bg class to the body so you can see the background change color when you change the frame width.
You can simplify your queries too by saying:
#media (max-width: 829px) {
.bg {background-color:blue;}
}
#media (min-width: 830px){
.bg {background-color:red;}
}
#media (min-width: 1026px) {
.bg {background-color:green;}
}
#media (min-width: 1590px) {
.bg {background-color:yellow;}
}

Responsive Font Media Query Less Loop

I thought this would be a helpful tutorial on how to create a loop in less that create media queries to allow for responsive fonts.
I was unhappy with how my font would never scale while all my DIVs and images would do so. As you scale down. The font appears to get larger making the design and layout look terrible. Of course I could leave it that way and let the text wrap but that also looks terrible.
So I created these media queries to incrementally increases the font size every 20 pix by 0.05. Then that evolved into less logic so that I could use less code. However, I've included both css and less bellow.
With the font changing every 20 pix of resizing can look a little choppy. But that's much better then only having 3 media queries to change font size. That's garbage. And Lazy. Why do it manually? I digress. See the advantage of having a loop is that you can refine and increase the amount of media queries to get more smoothness in font/browser sizing.
One last thing. once you have you fonts set this way; to html. Everything else must be set to percentage font sizes. That way they are a percentage of the html font size and will be responsive. Here's an example:
html{
font-size: 1em;
}
h1{
font-size: 120%; //1.2em
}
h2{
font-size: 110%; //1.1em
}
Please tell me what you think.
-Love PAT
LESS LOOP:
//Set font for 300 pix devices and lower. Font size will increase by 0.05 every 5pix of width.
#fontSize: 0.7em; //em
//#media start at?
#screenWidth: 300px;
#screenWidthMax: 640px;
#loop: (((#screenWidthMax - #screenWidth)/20)-1);
//Size for 640px and above
#fontSizeMath640: round(#fontSize + (#fontSize * (0.05*(#loop+2))),2);
#media (min-width: #screenWidthMax) {
html {
font-size: "#{fontSizeMath640}";
}
}
//Create loop that repeats from 300 pix all the way to 640 pix incrementing by 20px. So, (640-300=340)/20=17. Loop 68 times.
.responsiveFont (#index) when (#index >= 0) {
#minWidth: (#screenWidth+(20*#index));
#maxWidth: (#minWidth + 19);
#fontSizeMath: round(#fontSize + (#fontSize * (0.05*(#index+1))),2);
#media (min-width: #minWidth) and (max-width: #maxWidth) {
html {
font-size: "#{fontSizeMath}";
}
}
// next iteration
.responsiveFont(#index - 1);
}
// end the loop when index is 0
.responsiveFont (0) {}
// "call" the loopingClass the first time with highest value
.responsiveFont (#loop);
//Size for 300px and below
#media (max-width: #screenWidth) {
html {
font-size: "#{fontSize}";
}
}
Which Prints out this:
CSS
#media (min-width: 640px) {
html {
font-size: "1.33em";
}
}
#media (min-width: 620px) and (max-width: 639px) {
html {
font-size: "1.29em";
}
}
#media (min-width: 600px) and (max-width: 619px) {
html {
font-size: "1.26em";
}
}
#media (min-width: 580px) and (max-width: 599px) {
html {
font-size: "1.22em";
}
}
#media (min-width: 560px) and (max-width: 579px) {
html {
font-size: "1.19em";
}
}
#media (min-width: 540px) and (max-width: 559px) {
html {
font-size: "1.15em";
}
}
#media (min-width: 520px) and (max-width: 539px) {
html {
font-size: "1.12em";
}
}
#media (min-width: 500px) and (max-width: 519px) {
html {
font-size: "1.08em";
}
}
#media (min-width: 480px) and (max-width: 499px) {
html {
font-size: "1.05em";
}
}
#media (min-width: 460px) and (max-width: 479px) {
html {
font-size: "1.01em";
}
}
#media (min-width: 440px) and (max-width: 459px) {
html {
font-size: "0.98em";
}
}
#media (min-width: 420px) and (max-width: 439px) {
html {
font-size: "0.94em";
}
}
#media (min-width: 400px) and (max-width: 419px) {
html {
font-size: "0.91em";
}
}
#media (min-width: 380px) and (max-width: 399px) {
html {
font-size: "0.88em";
}
}
#media (min-width: 360px) and (max-width: 379px) {
html {
font-size: "0.84em";
}
}
#media (min-width: 340px) and (max-width: 359px) {
html {
font-size: "0.8em";
}
}
#media (min-width: 320px) and (max-width: 339px) {
html {
font-size: "0.77em";
}
}
#media (min-width: 300px) and (max-width: 319px) {
html {
font-size: "0.73em";
}
}
#media (max-width: 300px) {
html {
font-size: "0.7em";
}
}
For best responsive Media queries we use Bootstrap class where defined these :
/* Small devices ( #screen-sm-min Phones (<768px) ) */
#media (min-width: 368px) {
}
/* Small devices (#screen-sm-min tablets, 768px and up) */
#media (min-width: 768px) {
}
/* Medium devices ( #screen-md-min desktops, 992px and up) */
#media (min-width: 992px) {
}
/* Large devices ( #screen-lg-min large desktops, 1200px and up) */
#media (min-width: 1200px) {
}

Multiple #media tags not working

#media only screen and (min-width: 767px) and (max-width: 2000px) {
html { background-color: green; }
}
#media only screen and (min-width: 481px) and (max-width: 766px) {
html { background-color: green; }
}
#media only screen and (min-width: 321px) and (max-width: 480px) {
html { background-color: green; }
}
#media only screen and (max-width: 320px) {
html { background-color: green; }
}
html {
background-color: blue;
}
I'm using opera, 1920x1080 screen. The first #media tag works, the background changes to green when opera is at 100% zoom.
Changing zoom to 90% makes the background blue already...and it stays blue the whole time even at 10% zoom. Why is that so?
The first #media tag seems to be working, the others don't. And even so the first tag doesn't work properly (90% * 1080px > 767px; so the color should be green while at 90% zoom but it's not).
Move your single html definition to the top, you can also reduce the media queries to just use max
html {
background-color: blue;
}
#media only screen and (max-width: 2000px) {
html { background-color: green; }
}
#media only screen and (max-width: 766px) {
html { background-color: red; }
}
#media only screen and (max-width: 480px) {
html { background-color: black; }
}
#media only screen and (max-width: 320px) {
html { background-color: white; }
}
http://jsfiddle.net/Y5tLf/

Resources