Thursday, January 9, 2014

Scaling full screen images with Media Queries

Images with an aspect ratio (width/height) less than that of the screen’s should be scaled by height while those greater should be scaled by width. e.g. extreme cases are portraits in landscape screen orientation and landscapes in portrait screens. There are no programming capabilities in xhtml/css (except possibly in javascript), but media queries can be used for a kind of solution. [svg wrappers might be another  way to go?]

In particular, take the three ratios (and their inverses) in iOS devices: 

2/3 for original iPhones and iPod Touches
3/4 for iPads
40/71 for current iPhone and iPod Touch [9/16 is advertised but it’s actually 40/71]

Then place the image ratio on this scale increasing to the right:
40/71  2/3  3/4  4/3  3/2  71/40
and note the screen ratio immediately to the right, i.e. >=

Now define classes in css corresponding to these ratios as follows, and (e.g. for a square image) use a construct in xhtml like

<div class=“ratio4x3”><img class=“ratio4x3” scr=“../Images/theimage.jpg” /></div>

@media  (device-aspect-ratio: 40/71) and (orientation: landscape) {
.ratio71x40 {height: 100%; }
.ratio3x2 {height: 100%; }
.ratio4x3 {height: 100%; }
.ratio3x4 {height: 100%; }
.ratio2x3 {height: 100%; }
.ratio40x71 {height: 100%; }
}
@media  (device-aspect-ratio: 2/3) and (orientation: landscape) {
.ratio71x40 {width: 100%; }
.ratio3x2 {height: 100%; }
.ratio4x3 {height: 100%; }
.ratio3x4 {height: 100%; }
.ratio2x3 {height: 100%; }
.ratio40x71 {height: 100%; }
}
@media  (device-aspect-ratio: 3/4) and (orientation: landscape) {
.ratio71x40 {width: 100%; }
.ratio3x2 {width: 100%; }
.ratio4x3 {height: 100%; }
.ratio3x4 {height: 100%; }
.ratio2x3 {height: 100%; }
.ratio40x71 {height: 100%; }
}
@media  (device-aspect-ratio: 3/4) and (orientation: portrait) {
.ratio71x40 {width: 100%; }
.ratio3x2 {width: 100%; }
.ratio4x3 {width: 100%; }
.ratio3x4 {height: 100%; }
.ratio2x3 {height: 100%; }
.ratio40x71 {height: 100%; }
}
@media  (device-aspect-ratio: 2/3) and (orientation: portrait) {
.ratio71x40 {width: 100%; }
.ratio3x2 {width: 100%; }
.ratio4x3 {width: 100%; }
.ratio3x4 {width: 100%; }
.ratio2x3 {height: 100%; }
.ratio40x71 {height: 100%; }
}
@media  (device-aspect-ratio: 40/71) and (orientation: portrait) {
.ratio71x40 {width: 100%; }
.ratio3x2 {width: 100%; }
.ratio4x3 {width: 100%; }
.ratio3x4 {width: 100%; }
.ratio2x3 {width: 100%; }
.ratio40x71 {height: 100%; }
}

This works in iBooks and Marvin on iOS devices. Media Queries don’t seem to work in other reader apps except for Kobo, which has other issues. They don’t seem to work in iBooks with OSX9 or Calibre, but these apps seem to scale the images correctly automatically.

Here are the gotchas:
First is that you need to use “device-aspect-ratio”, not just “aspect-ratio”. 
Next is that ratios>1 don’t match - you need to use the inverse with “orientation: landscape”. 
Finally, “@media” can’t take a qualifier - even “all” - or it won’t work right.

No comments:

Post a Comment