Ryan Seddon
Read Post
For a long time we have been able to specify styles for different media types using CSS, print and screen being the most recognizable. With CSS3 these media types have been extended to allow additional expressions, aka media queries, which gives us greater control on when specific styles should be applied. In this article I will focus on the orientation media query and have a fun demonstration showing how to use it.
Orientation
The orientation media query allows us to target specific styles based on the current screen or device orientation. We have 2 properties; landscape and portrait which allow us to change a pages layout based on the browsers current orientation.
A browser or device determines the orientation by listening to the width and height of the window. If the height is larger than the width the window is in portrait mode. If the width is larger than the height it’s in landscape mode.
/* Portrait */
@media screen and (orientation:portrait) {
/* Portrait styles */
}
/* Landscape */
@media screen and (orientation:landscape) {
/* Landscape styles */
}
Within our style sheet we can specify our media query which will target a media type of screen and an orientation of portrait or landscape.
Karma karma karma karma karma chameleon
To show off a quirky use for orientation media queries I have put together an example that upon orientation change will adjust the colour of the chameleon image, and as a bonus for the nicer browsers that support CSS3 transitions it will fade between the colours when the orientation changes.
Take a look at the CSS3 Chameleon demo and make sure to re-size your browser to see the chameleon change colour. To see the best results view in a WebKit browser such as Safari or Chrome. You can also download the demo files here.
Deconstructing the demo
Let’s go through how the above demo was put together in a little detail.
html { background: #000 url(chameleon2.jpg) 50% 100% no-repeat; }
body { background: url(chameleon.jpg) 50% 100% no-repeat; }
Basically it consists of 2 images of the chameleon. One for landscape and one for portrait, with 1 image being applied as a background to the html tag and the other on the body.
/* Portrait */
@media screen and (orientation:portrait) {
body { opacity: 1; }
}
/* Landscape */
@media screen and (orientation:landscape) {
body { opacity: 0; }
}
To switch between the images the body tag has opacity of 0 when the browser is in landscape mode and opacity of 1 when in portrait mode. That way we can easily switch between the images.
Fade the color change
If you had viewed the demo in a CSS3 transition supporting browser, such as Safari or Chrome, changing the orientation would trigger a smooth fade between colors of the chameleon.
body {
background: url(chameleon.jpg) 50% 100% no-repeat;
-moz-transition: opacity 1s ease; /* FF3.7+ */
-o-transition: opacity 1s ease; /* Opera 10.5 */
-webkit-transition: opacity 1s ease; /* Saf3.2+, Chrome */
transition: opacity 1s ease;
}
In order to-do that smooth transition we apply it to the body and set the opacity property to fade over 1s using the ease timing function. I also specify the various vendor extensions for the transition property.
Since the transition is applied on the body outside of the orientation media queries the fade will be triggered for both fading in and out depending on the browsers current orientation.
Browser support
Media query support varies from browser to browser but orientation media queries have pretty good support.
- Safari 4+
- Chrome 4+
- Firefox 3.5+
- Safari iPad
All of the browsers above except Firefox 3.5 also support CSS3 transitions. Firefox 3.7 however supports transitions but is still in alpha stages.
Unfortunately Opera 10.5 (Presto 2.5) supports all media queries except orientation, hopefully this will be added in a future update.
Bonus: iPhone support
As of writing the latest iPhone firmware doesn’t yet support the orientation media query, but with iPad support it’s very likely that the upcoming 4.0 release will include it.
In the mean time we can emulate orientation detection in the iPhone by utilizing the min and max-width media queries which have been available since 1.0.
/* Portrait */
@media screen and (max-width: 320px) {
body { opacity: 1; }
}
/* Landscape */
@media screen and (min-width: 321px) and (max-width: 480px) {
body { opacity: 0; }
}
Since we know that the iPhones max width in portrait mode is 320px we use that to our advantage to apply our portrait styles. To detect landscape we use a combination of min/max-width and since CSS3 media queries allow us to chain expressions together we make sure the min-width is at least 321px, that way these styles won’t be applied in portrait mode. The max-width property is used so we don’t affect our desktop counterparts that support the orientation media query, its set to 480px which is the iPhones max landscape width.
In order for these styles to work on the iPhone we also need to set the viewport meta tag
<meta name="viewport" content="width=device-width, minimum-scale=1.0, maximum-scale=1.0">
This will force the iPhone to render the page in its actual scale rather than doing its usual thing of auto scaling the website to fit the phone dimensions.
Now the background image is too big
By setting that meta tag the background image is way too big to fit within the iPhone dimensions. Luckily there is a CSS3 property called background-size which the iPhone supports.
@media screen and (max-device-width: 480px) {
html, body {
-moz-background-size: 80% auto;
-webkit-background-size: 80% auto;
background-size: 80% auto;
}
}
In order to apply the background-size adjustment to smaller devices like the iPhone we use the max-device-width media query to target only devices with a maximum width of 480px. Then on both the html and body tags we adjust the background-size to be an 80% width of the available space on the current device, with the second value set to auto so we can keep the correct aspect ratio of the image.
But this presents another issue
Changing the iPhone orientation will also change the size of the background image to be larger in landscape than in portrait. To get around this we further adjust the background-size in landscape so changing between orientations will keep the background sizes relative to each other.
@media screen and (min-width: 321px) and (max-width: 480px) {
html, body {
-moz-background-size: 50% auto;
-webkit-background-size: 50% auto;
background-size: 50% auto;
}
body { opacity: 0; }
}
We add a slight addition to the iPhone landscape orientation media query, instead of making it 80% of the available width we adjust it to 50% which keeps the background image the same size as it would be in portrait.
Conclusion
CSS3 media queries add a lot of control and power on how your webpage will be display depending on multiple factors such as device size, orientation, aspect-ratio and many others.
I’ve only scratched the surface of what Media Queries allows us to accomplish with relative ease. As browser support becomes better we can truly start to take advantage of the power that media queries provide. Let me know if you have some questions and I will try to answer them in comments.

