Thursday, January 9, 2014

Captions on images

Sometimes you want to place a caption directly on top of an image - e.g. when then image is full screen. One almost-too-simple way to do this is to follow on the image with a paragraph, say, styled with a negative margin-top and with the text in a contrasting color. e.g.

<div><img scr=“../Images/theimage.jpg” /></div>
<p style=“margin-top: -2em; text-align: center; color: red;”>the caption</p>

This works in iBooks (iOS and OSX9) and Marvin. This scales pretty well as font-size is changed, but in any case any overflow comes out under the image.

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.