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.

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.

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!

19 Comments

Leave a Reply to content resizes to window size - repost from javascript forum - SitePoint Forums Cancel reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.