When people think about window.orientation, they probably envision something like the following poorly-done drawing.

0 is the bottom. 90 and -90 are the sides. 180 is the top. Simple concept. But there’s something implied by this drawing that is incorrect. Do you see it? Let’s get some devices out and see if we can discover the error. On each device, we’ll load a test page I wrote. Then, we will hold them in portrait orientation and see what the page says. We’ll keep turning them 90° counterclockwise and checking the results until we’ve done all 4 sides.
First, an iPod touch.

Apple has decided that you’re not allowed to use your iPod upside down. Other than that, this fits with our mental image.
Next, let’s get out a Nexus S.

Google also doesn’t think you should be using your phone upside down. This device is also reporting both sides as 90, which is not very useful if you care about which side is facing down. But it still mostly fits with what we expect.
Let’s try a tablet. This is a Kindle Fire.

Good job, Amazon! This fits exactly with our expectations.
Next up is our Toshiba Thrive.

How unexpected! After looking at the results for a minute, you might notice that the numbers have shifted one position to the right. Let’s shift them to the left so they line up with results for the other devices.

So, on the Thrive, orientation 0 is landscape rather than portrait. Why is this? Is it a bug? A bad interpretation of a spec? No. It’s because this is how someone at Toshiba intends for you to hold the device when using the browser.
This may seem weird to you. It’s certainly not the norm. But it’s not wrong. The problem is that many people assume that 0 means portrait. What 0 really means is the default orientation.
Have you run into any other devices where window.orientation 0 is landscape? If you can’t rely on window.orientation to determine if a device is in landscape or portrait, what do you use?
11 Comments
The code for the orientation page is here, if you don’t feel like viewing the source. https://gist.github.com/1943615
I hadn’t read thru to the last 2 paragraphs before I ran your test code on 2 Android devices. Thought I was going to get to the bottom of things, finally, but you really just explained the confusion more clearly :-)
Motorola Droid: Starting at 0 / Portrait then rotating counter-clockwise gave results like your 2nd (“Google”) example, BUT I found that if I started at 0 / Portrait and rotated CLOCKWISE by 90, it would report -90 for that landscape orientation – so apparently the “last known orientation” affects current reporting as well. (unless rotating 90 counter-clockwise is the only way to test!?)
Samsung Galaxy Tab 10.1: Like your Toshiba Thrive results, where default orientation / 0 appears to be Landscape (with lettering on back right-side-up). Well, except in the case of using jQuery Mobile, which tries to be clever and detect “default orientation”, but sometimes fails, or gets confused, depending on which orientation the device was in when the app launched.
One would think something so simple could be easily standardized..
I didn’t think about the possibility of getting different results when turning the device the other way. I just tried rotating my Galaxy Nexus clockwise. It returned -90 for both landscape orientations. Apparently, I’m not understanding something about this.
If you’re just in need for portrait/landscape detection, you still can use media queries. Even in JS: http://www.fettblog.eu/blog/2012/04/16/robust-(but-hacky)-way-of-portrait/landscape-detection/
Months ago I thought I had run your test page on my desktop – but now I get HIERARCHY_REQUEST_ERR Dom exception 3 (chrome). Should it work on desktop?
Still works great on my device, and I finally learned to bookmark it.
Good catch, Libby. The page is fixed. I don’t know if orientation is defined in any desktop browsers. It’s undefined in Chrome.
On my Galaxy Tab 10.1 inch, if I see 0 in landscape. If I slowly rotate to portrait, I see 90, if I rotate again, I see 180.
However, if I’m currently at 180 and rotate another 180 degrees all the way around, I should see 0, but I see 180.
Wat.
So on the Playbook Blackberry.
Start in Landscape mode with the logo at the bottom and turning 90º counterclockwise
Just treat window.orientationchange as window.resize. That is, you have no way of knowing what the new window dimensions (or in this case, the aspect ratio) will be, so just measure window.width/window.height once the even has been triggered. Proceed from there.
Simple is better:
window.isPortrait=(window.innerHeight/window.innerWidth)>1;
@Stefano,
If only things were this simple. Apple devices (iPod, iPad, iPhone) will not report the correct width / height based on orientation. Width will always be bigger then height, regardless.