Determine iPhone orientation using CSS

With the beta of Firefox 3.5 showcasing 35 new features over 35 days, the article on CSS3 media queries stuck out, the orientation detection really got my attention and immediately put my thought process to mobile devices, in my case the iPhone. I thought this is great maybe this has been snuck into the iPhone 3.0, unfortunately for us it wasn’t. That didn’t stop me and I got thinking about how it could be done if at all on the iPhone without using JavaScript.

Still using the CSS3 media queries we can accomplish orientation detection with only CSS but instead of looking at the unsupported orientation property we can use the min-width and max-width propertities to our advantage to detect what orientation the user is currently in. Load the below demo in your iPhone/iPod Touch to see it in action, rotating the phone will either change the text from “Portrait” to “Landscape” depending on your orientation respectively.

Looking in the Apple Developer documentation on Human Interface Guidelines (HIG) we can determine the min and max width we need to target to find out the user orientation. Let’s look at the CSS from the demo to better understand how it works.

h1
{
	display: table-cell;
	vertical-align: middle;
	text-align: center;
}
	h1 span { display: none; }
 
/* Portrait */
@media screen and (max-width: 320px)
{
	h1 span:nth-child(1) { display: inline; }
}
 
/* Landscape */
@media screen and (min-width: 321px)
{
	h1 span:nth-child(2) { display: inline; }
}

In the demo we have a <h1> set with to display: table-cell, this isn’t important to the demo but allows me to easily vertically centre the text. Inside the <h1> there are 2 spans which will show or hide depending on what orientation you’re in, initially we hide both spans.

The next few lines are where we can figure out using only CSS what span to show. To determine if the user is in portrait mode we use the media query @media screen and (max-width: 320px) we know from the HIG that 320px is the max-width in portrait mode. We do the same for landscape but this time we use min-width and increase the value by 1 so viewport needs to be at least 321px wide before any styles in the media query will be applied. Inside each media query I use the CSS3 nth-child pseudo class to target an individual span.

Not without issues

In order for this to work we need to add the viewport meta tag to force the iPhone Safari viewport width to be that of the device, it is usually defaulted to 980.

<meta name="viewport" content="width=device-width, minimum-scale=1.0, 
 maximum-scale=1.0">

My original idea was to use the max-device-width and min-device-width properties which would bypass the need for viewport meta tag but unfortunately this doesn’t work. It may be due to the fact that it will always return a min-width of 320 and a max-width of 480 and therefore wouldn’t be possible to do it the current way I have devised.

Until the iPhone adds in support for the orientation media query, this technique is quite a capable work around. Of course there are still some things it can’t do so the orientation event handler will still be needed for more advanced changes to happen.

Post filed under: css.

Skip to comment form.

  1. Euan says:

    This works like a dream! Thank you.

    Do you happen to know if it works with pre 3.0 iPhones?

  2. @Euan – Cheers. This media query support has been available since 1.0 so it will work across the board. I don’t have an iPhone running OS1.0 so I haven’t tested the demo, but according to Apples documentation CSS3 media queries have been supported since 1.0

  3. Euan says:

    Thanks for that.

  4. Iraê says:

    Nice article!

    Solved some things for me, but left me with 2 questions =)

    1. Is there a way to filter just the iPhone out by CSS media queries? Something in the folowing fashion would be very usefull.
    @media [some-code]{
    /* IE6+ – Firefox 2+, Safari 3+ */
    }

    2. Is there any problem with newer handhelds, like hte NexusOne, because of it’s higher resosution? Have anyone tryed (min-width: 321px) and (max-width: 320px) on them?

  5. @Iraê – Thank you.

    1. Is there a way to filter just the iPhone out by CSS media queries? Something in the folowing fashion would be very usefull.
    @media [some-code]{
    /* IE6+ – Firefox 2+, Safari 3+ */
    }

    There is nothing in CSS to filter out specific devices, you could however do something like:

    @media screen and (max-device-width: 480px) { ... }

    In that media query you could then reset the styles for devices with a max width of 480px i.e. the iPhone.

    2. Is there any problem with newer handhelds, like hte NexusOne, because of it’s higher resosution? Have anyone tryed (min-width: 321px) and (max-width: 320px) on them?

    Hopefully the newer smart phones with the superior browsers will support the orientation media query. I believe Firefox mobile already does.

    Instead of doing (min-width: 321px) and (max-width: 320px) you would do the following:

    /* Portrait */
    @media screen and (orientation:portrait) { ... }
    /* Landscape */
    @media screen and (orientation:landscape) { ... }
  6. Steve Bruner says:

    I learn something new everyday. Really amazing… thank you so much.

  7. Jon Milani says:

    Is there a way to lock Mobile Safari’s orientation to either portrait or landscape (via javascript or otherwise)? In other words, I want the web page to remain in portrait mode regardless of the orientation of the device.

    The reason I ask is because I’m designing an iPhone specific “hello” page for a client, and they want the page to lock to portrait (aka 320px by 480px) regardless of the actual orientation of the iPhone.

    Any help would be very much appreciated!

  8. This is just what I was looking for, THANK YOU!
    min-width: 321px
    max-width: 320px

    So perfect.

  9. jordan says:

    does any one know how 2 get on n the way of the ninja 2???????????

  10. @Jon M – No you can’t lock the orientation in mobile Safari, the best you can do is display a message saying you need to be in portrait when the user is in landscape. But that would be a very annoying solution! You should educate your client on why it’s bad and that it’s actually not possible.

  11. Iraê says:

    @John M, CSS Ninja

    IMHO being unable to lock the mobile safari’s orientation is a flaw to apple’s or webkit mobile. They advocate HTML5 apps as a powerfull plataform, and for most cases it is. But for now we have to support both orientations, and we have no good way to make it really cross device.

    It’s a mess to detect iPhone, Android, and iPad orientations, widths and heights, and even the new pixel ratio in iPhone 4 – and make your webapp fit in all combinations. In fact, I’ve not had the time to research and test all of these. It would be nice to have an article about that =)

  12. @Iraê – I agree there should be an option to do it. The native apps can, why not Safari? Having said that we should embrace orientation changes and utilise it to our advantage.

    With the latest software for iPad and iPhone CSS orientation media queries (along with many other browsers) are supported so instead of using max/min-width we can use orientation:portrait/landscape in our CSS. I did a guest post about that subject on another blog for CSS3 media queries.

  13. Sei Pistole says:

    There are some sites that detect iPhone rotation and rejig the css so the text stays the same size, when this happens I usually close the page.

    This is because the number one reason I rotate my iPhone to landscape is because even after tapping to zoom the text it’s still too small to read comfortably in portrait.

    The iPad is big enough to think about portrait and landscape layouts, mobile screens aren’t, please assume those viewers are more interested in your content than your layout skills.

    pft maybe I’m just getting old.

  14. @Sei – I’m purely showing how to detect orientation changes in CSS, what people choose to do with that is up to them.

  15. cyrex says:

    Thx, nice tut and a great idea. :)

  16. Mark says:

    Thanks, I just started working on a mobile simple website and found out about the landscape issue, now it works..

  17. Mark says:

    Works fine on my iphone but not on an Android Samsung device, the layout does not stretch in landscape mode just like previously on my iphone, is there a trick to fix it for it?

  18. @Mark -

    The window dimensions will most likely be different I believe Android supports orientation media query use that.

    @media  screen and (max-width: 320px), screen and (oritation:portrait) { }
  19. Mamzelle says:

    Thank you, really useful!

  20. jagadeesh says:

    While chagening the position to portrait to landscape the website.. the website does not shows in full screen. It show in portrait width only.. after refreshing the page it show in full screen…. what is the solution for this….??

  21. Virneto says:

    This is awesome information!!
    I can’t believe it’s been published in 2009 and I’ve only found it now;(
    Thanks!!