CSS Media Query - Soft-keyboard breaks css orientation rules - alternative solution? CSS Media Query - Soft-keyboard breaks css orientation rules - alternative solution? android android

CSS Media Query - Soft-keyboard breaks css orientation rules - alternative solution?


I know this is a couple of years late but I found a great solution

For landscape media:

@media screen and (min-aspect-ratio: 13/9) { /* landscape styles here */}

And for portrait media:

@media screen and (max-aspect-ratio: 13/9) { /* portrait styles here */}

The full solution and why it works can be found here Michael Barret - Android browser challenges

Edit: this link is now expired, but a snapshot can be found on the internet archive: Michael Barret - Android browser challenges


The problem lies in the way that orientation is calculated:

http://www.w3.org/TR/css3-mediaqueries/#orientation

The ‘orientation’ media feature is ‘portrait’ when the value of the ‘height’ media feature is greater than or equal to the value of the ‘width’ media feature. Otherwise ‘orientation’ is ‘landscape’.

Since the height/width is calculated on the visible viewport, the soft keyboard apparently causes the orientation to flip now that the viewport width is less than the height. One solution would be just to use your media queries based on just width instead. This makes it more flexible across devices regardless of orientation, not to mention width/height is more widely supported than orientation.

If you want to account for the width instead of orientation, I'll use the iPhone as an example:

@media screen and (max-width: 320px) {  /* rules applying to portrait */}@media screen and (max-width: 480px) {  /* rules applying to landscape */}

This approach is more flexible than orientation since the queries aren't limited to devices/user-agents that support orientation, not to mention that orientation tells you very little versus the width.

Of course if you really need to know orientation, it seems like setting the class initially and just use that might be your best option.


An alternative might be to use device-aspect-ratio, which remains unchanged. However, in Webkit, rotating the device doesn't trigger an update of CSS rules using this query, even though JavaScript tests return true for the new aspect ratio. This is apparently due to a bug, but I'm not able to find a bug report. Using a combination of orientation and {min,max}-device-aspect-ratio seems to work fine:

@media screen and (max-device-aspect-ratio: 1/1) and (orientation: portrait)@media screen and (min-device-aspect-ratio: 1/1) and (orientation: landscape)

The use of orientation triggers updates as expected, and the use of device-aspect-ratio restricts updated to actual changes of orientation.