Wednesday, February 26, 2014

(legible) captions on images

The previous post gives a method to overlay text atop an image, and though any color can be used, the text may not stand out clearly enough from the background. It's possible to specify a background for the text, but it lies behind the image so this approach doesn't work.

Instead, however, if the text is made a link, then the link's background color does show above the image and can be used to contrast with the text. Also, the background color can be made partially transparent so as not to completely block out the image. Strangely, any color specified for the link text itself seems to be ignored.

Notes:
The "href" in the anchor tag is needed to make it a link, and the empirically determined value "*" stops it from actually going anywhere when touched. (Otherwise it would have to point to some unique id). The padding and rounded corners are for aesthetics.

There is still visual feedback when the link is touched and this could be used, for example, to change the background or eliminate it altogether to better see the underlying image (as in the hover selector). Or perhaps better, just double tap the image to zoom and pan without the caption and then hit done to restore.

This works in iBooks and Marvin.



XHTML
<div class="container">
<img alt="" src="../Images/theimage.jpg" />
<p class="caption up"><a class="frame" href="*">the caption</a></p>
</div>

CSS
div.container {
 display: inline-block;
 width: 100%;
 text-align: center;
}
p.caption {
 font-size: .8em;
 font-style: italic;
 text-align: center;
}
p.up {
 margin-top: -2em;
 margin-bottom: 0;
}
a.frame.link {
 padding: 0em 2em;
 border-radius: 10px;
 text-decoration: none;
 background-color: rgba(255,255,255,0.75); /*white with transparency*/
}
a.frame:hover {
 text-decoration: none;
 background-color: transparent;
 visibility: hidden; /*zap entire caption */
}


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.

Monday, September 10, 2012

pop-up footnotes in iBooks with Sigil

Liz Castro describes the basics of getting pop-up footnotes to work in iBooks but lacking an epub3 editor this feature is hard to explore. As a workaround, the current (epub2) versions of Sigil can produce epubs with pop-up footnotes that work in iBooks if the appropriate (epub) namespace is declared. e.g. here is the complete xhtml.

<?xml version="1.0" encoding="utf-8" standalone="no"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" xmlns:epub="http://www.idpf.org/2007/ops">
<head>
<title>Book</title>
</head>

<body>
<p>worthy of a footnote <a epub:type="noteref" href="#ref">[ref]</a></p>

<p epub:type="footnote" id="ref">the footnote</p>
</body>
</html>

Sigil doesn't honor the <aside> tag, but styling <p> or <div> with "display:none" gives the same effect.

The resulting epub doesn't pass epubcheck but does work ok in iBooks.

Wednesday, January 18, 2012

iBooks body margin contortions


 One annoying aspect of iBooks is how much whitespace is wasted on the margins of the body text. Applying background colors (cyan and yellow respectively) you can see that the <body> element is contained within the <html> element. 

It's possible, though, to squeeze a little more space (10 pixels on a retina display) out on the left by adjusting the left margin by 5 (CSS) pixels. For images, 5 pixels means 5 screen pixels as seen above.

On the right side, it turns out that setting "width:100%" on the body element, which you'd expect would be innocuous, actually pushes the the right side a little beyond the <html> edge, so things get clipped.
So presumably replacing "100%" with the appropriate pixel value would get you exactly to the edge...

Thursday, December 15, 2011

with iBooks 1.5

iBooks 1.5 has solved one problem with this technique, but introduced another. Previously there would sometimes be spurious page turns, backwards or forwards, after tapping an affected paragraph. This doesn't seem to happen any longer. The new problem is that this technique doesn't work at all when the new night theme is selected.

Sunday, November 20, 2011

more popout notes for iBooks with Javascript

The previous post showed how to expose a concealed note as white on gray. Here's a related technique to show the note as black on white.


XHTML:
<p onclick="popoutblack(this)"><span class="inlinenote" style="color: transparent;">some text for the note</span>some text for the paragraph</p>

CSS:
span.inlinenote {
display: block;
height: 0; /* default overflow is "visible", but 'invisible' since transparent */
}

javascript:
function popoutblack(obj) { //switch transparencies
  switch (obj.style.color) {
case "": { //case no inline style defined for <p>
 obj.style.color = "transparent";
 obj.firstChild.style.color = "black"; // otherwise color (now transparent) is inherited
}
break;
default: { // restore to original conditions
 obj.style.color = "";
 obj.firstChild.style.color ="transparent";
}
};
}