CSS3 Media Queries and creating adaptive layouts
With the myriad of devices, web browsers and screen sizes out there, we need a way to to be able to easy detect how we want to layout a web page for them. This is now offered to us through Media Queries in CSS3.
CSS3 Media Queries will help you retrieve information about the device/web browser accessing your web page, and from there you can decide how you want the content presented in the best manner according to its capabilities. The things you should be able to check, according to the CSS3 Media Queries specification, are:
- width
- height
- device-width
- device-height
- orientation
- aspect-ratio
- device-aspect-ratio
- color
- color-index
- monochrome
- resolution
- scan
- grid
(Please note that not all of the above might not be supported in web browsers as of right now)
The most interesting to me, and the ones I will be covering here are:
- min-width
- max-width
- orientation
A simple example
Let’s start with a very simple example. In this case, the background color of an element is red by default. However, if the available width is over 500 pixels, we want it to be blue:
.media-query-elm { background: #f00; } @media screen and (min-width: 500px) { .media-query-elm { background: #00f; } }
So, just as you might have known from before, you specify the media (perhaps you have used this for screen-specific CSS and then print-specific one) and together with that, you set the criteria for the minimum width. Any web browser client that matches that will apply/override all CSS rules specified within the block.
Having a flexible layout
The power of media queries then means that if you have a high resolution you can get one layout, and for lower resolutions, mobile phones and such, you can totally change the layout to fit best into that view – all without scripting and other non-optimal detection methods (thinking about user agent sniffing and such).
Therefore, to expand on the simple example above, we will have different width and layout depending on the available width:
.navigation { float: left; width: 300px; } .main-content { float: right; width: 500px; } @media screen and (min-width: 1000px) { .navigation { width: 350px; } .main-content { float: right; width: 650px; } } @media screen and (max-width: 399px) { .navigation { display: block float: none; width: 100%; } .main-content { display: block float: none; width: 100%; } }
The result of this is that we have a default size for the navigation and main-content elements and place them next to each other, but if the user’s web browser/device supports a higher width, we will bump them up a little. However, for lower width values (presumably iPhone, Android phones and such), we instead put the two elements each on a line of their own, remove the floating and let them take all the available width.
Using and, or, only and not
You can expand Media Queries by checking for several values, or statements or not statements. As you could see above, to check for several values if they are all true, you use the and
keyword:
@media screen and (min-width: 100px) { .navigation { width: 350px; } }
To check for or statements, you interestingly use comma-separation (which sort of makes sense, but also feels a bit twisted, because for other things in CSS, like multiple backgrounds, you use commas to combine them). Anyway, it would look like this:
@media screen and (min-width: 100px), @media handheld { .navigation { width: 350px; } }
For older user agents, you can use the only
keyword to make sure it’s not processing the content:
@media only screen and (min-width: 100px) { .navigation { width: 350px; } }
And finally, we also have a not
keyword to exclude certain criteria (i.e. it will apply to everyone that doesn’t match this):
@media not screen and (min-width: 100px) { .navigation { width: 100%; } }
Getting orientation
There’s also an interesting property available called orientation
, which is there to help you detect if something is rendered in landscape or portrait mode. This is how to use it:
@media screen and (orientation: portrait) { .portrait { display: inline; } .not-detected { display: none; } } @media screen and (orientation: landscape) { .landscape { display: inline; } .not-detected { display: none; } }
and combined with this HTML, it would show you the current rotation:
Device rotation is <span class="portrait">portrait</span> <span class="landscape">landscape</span>
Note on desktop web browsers
Above code for checking orientation is all good and well for iPhones, Android phones etc, but what about desktop web browsers? Interestingly enough, they do support this, and they return a value based on the ratio between the current window’s width and height. What this means in practice is that if the web browser window is wider than it is high, it is regarded as landscape
, otherwise it’s seen as portrait
.
I guess this sort of makes sense, but you wouldn’t necessary want to change the layout for desktop web browsers solely based on orientation. A tip is to always combine it with other values such as min-width
/max-width
.
The iPhone and width detection
For some reason there seems to be a constant use for various meta
elements. What I want to point out is that to make the iPhone check the width and change the layout, you need to add a meta
element and set the width accordingly (otherwise it won’t do it):
<meta name="viewport" content="width=device-width, maximum-scale=1.0">
I seen some examples online where you would also have to specify the minimum-scale to 1.0, but there are times when you don’t want that, and in my tests maximum-scale has been sufficient.
Web Browser support
The web browsers that support CSS3 Media Queries are:
- Internet Explorer 9 (upcoming)
- Firefox 3.5+
- Google Chrome 5+
- Safari 4+
- Opera 10.6+ (might need some more feedback on support level here)
The orientation
property is also available in these mobile devices/systems:
- iOS4
- Android 2+
- Mobile Firefox
- Bolt
- MicroB
(mobile support taken from PPK’s The orientation media query)
A little demo
As part of my CSS3 tests, I have a page for testing CSS3 Media Queries with available width and orientation.
CSS3 Media Queries are here today!
Except for Internet Explorer (prior to version 9), all other web browsers out there, desktop as well as mobile, support this and I think it’s a great tool to adapt your layout to best fit the end user’s conditions. Try it out and let me know!
Thanks for this article! I have not known, that i can use some media queries allready. That makes web devs life more easy π
Theres a little typo: "min-width: 100px" should be 1000px in the second code box.
David,
Glad you liked it! And thanks for the typo fix. π
Nice articel π
Lena,
Thank you!
Beauty information, thank you
Well done Robert!
Nice to have you back from your summer hiatus π
I guess something happened since these comments, or else I just need more coffee (entirely possible)…
1. The box labels signify an overlap between 400 and 500, so…
2. I never got a green box.
FF 3.6.9
I'm gonna start brewing now lol.
Matbaa,
You are welcome!
Morgan,
Thank you! π
BillyG,
No, you are absolutely correct! The demo can fail in its most narrow state in Firefox on Mac OS X, since it weirdly seems to calculate the web browser toolbar width as part of the min-width for CSS.
In my mind that is completely incorrect, but I'll leave the demo just as it is for testing purposes.
Cool article. The demo is very handy to test on an iPad switching the orientation
Nils,
Thanks, glad you liked it!
Just found your article. Thanks.
I’ve been looking into media queries myself, mainly with mobile devices in mind. In fact I’ve made a simple test rig for them which is on my tumblr if you’re interested:
http://swervo.tumblr.com/
One thing that I have noticed is that if I load your test page into my test rig that it doesn’t quite behave as described. A page that is 450 pixels wide fulfils two of your criteria (between 400 and 1000, and, less than 500 pixels) so it’s not clear which colour it should be. I think comment #7 mentions this as well.
Anyhow if you want to try your page in my rig follow this link (which will open your test page in an iFrame on my site):
http://www.papersnail.co.uk/sandbox/shell/index.html?http://robertnyman.com/css3/media-queries/media-queries.html
It only works with webkit browsers for now as I’ve only been thinking about mobile use (sorry, I’ll fix this shortly).
swervo,
Interesting, thanks for sharing!
thanks for this summary π
you might want to update your browser list: Opera 9.0 already added (useful) support for media queries
http://www.opera.com/docs/specs/opera9/css/
Mhelcor,
In my tests, though, those basic things didn’t seem to work until Opera 10.6. Have you tried the demos in Opera 9 and gotten other results?
This is some great information. It took me a while to find something that works and easy to learn. You did a fantastic job and I have been working on my redesign with these concepts. It should be up within the next few weeks but I did have a question. Is there a way to re-size input boxes for forms? If you have any input about that I would love to hear it!!!
Thanks a lot!
Kosta
Konstandinos,
Just use media queries to set the width of the input boxes; i.e. if the page width, for instance, is over a certain width have one size, if it’s under, give them another.
[…] media queries in action. Different Stylesheets for Differently Sized Browser Windows | CSS-Tricks CSS3 Media Queries and creating adaptive layouts – Robert's talk CSS3: Media Queries: width and height // Think Vitamin Membership Media queries don't work in ie8 […]
[…] appropriate size (i.e. width and height – file size is a discussion for another day). We have CSS3 Media Queries helping us detect available width, like […]
[…] appropriate size (i.e. width and height – file size is a discussion for another day). We have CSS3 Media Queries helping us detect available width, like […]