Friday, June 28, 2013

Getting iBooks to respect image width

So, I wrote a long time ago about how iBooks doesn't apply the CSS width property to images properly. Despite the fact that the spec says that width applies to all elements except non-replaced inline elements, and that images are replaced inline elements, up til now, iBooks wouldn't apply width to img. There is a workaround: applying the width to the image's parent, and setting the width of the image itself to 100%, as I describe in that article.

What's more frustrating is that since InDesign follows the rules, dutifully applying the pixel or percentage dimensions in the CSS directly to the image—which again, should work but doesn't in iBooks—those images are not displayed properly in iBooks.

So here's a document in InDesign: (I'm showing you the example in InDesign, but I would have the same issue if I created the code myself from scratch.)

InDesign Width

Here's the code that InDesign generates when I choose "Preserve appearance" and "Relative to page"

idGeneratedStyles.css

And here's how iBooks displays that page:

iBooks and width before

I wrote Douglas Waterfall, Engineering Architect on InDesign, about the problem and he pointed me to the solution, right there in the iBooks Asset Guide (which you can download if you have an iBookstore account).

The solution consists of creating a super-charged or magic CSS class that you can then use to properly apply the width property to img elements in iBooks. And it won't confuse ereaders that already do.

First, in the content.opf file, you have to make sure you have declared the iBooks namespace in the package element. You need this namespace if you use iBooks versioning as well. And it's completely harmless for non iBooks ereaders. (Note that I'm doing this in EPUB 3. I don't know and haven't tested it in EPUB 2.)

<package xmlns="http://www.idpf.org/2007/opf"
prefix="ibooks: http://vocabulary.itunes.apple.com/rdf/ibooks/vocabulary-extensions-1.0/" version="3.0" unique-identifier="bookid">


Next, in the meta section of the content.opf file, define which class should be able to apply the width property properly.

<meta property="ibooks:respect-image-size-class">respect</meta>

I called my class respect, but you can call it whatever you like.

Next, in the HTML, apply the respect class to your images.

<p class="Basic-Paragraph"><span><img class="respect" src="image/imagefolder-2_fmt.png" alt="imagefolder-2.jpg" /></span></p>

You can actually create multiple classes, as long as they are equal to, or prefaced with the name you declared in the meta element. So I could use respect, respect-wide, respect-small, or whatever.

Finally, create a rule in your CSS that references the respect class and applies the width property:

img.respect {
width:51%;
}


(Of course, if you're using InDesign, you can simply create a style called respect and let InDesign create your HTML and CSS.)

And then, miracle of miracles, iBooks applies the width property, just as it should.

iBooks does width!

Seems crazy that we have to help iBooks follow the spec properly, but at least we can.

If you like this post, please consider subscribing!

7 comments:

  1. Liz, applying % to image widths for iBooks has been such a pesky problem and it drives me crazy. Thank you so much for taking the time to track down this solution. I see some nifty solutions to applying various image widths here. I can't wait to try it.

    ReplyDelete
  2. Unfortunately, it only works with one class. Inline images in iBooks became completely useless because nothing works anymore as it should.

    ReplyDelete
    Replies
    1. Actually, it does work with more than one class. It works with the "respected" class and any classes that are prefixed with the respected class name. So in this example, you could have "respect", "respect-wide", "respect-special", whatever. It's nowhere near ideal, but it's better than nothing.

      Delete
    2. Hi Liz,

      after intensive testing, I've finally get it work! Yeah

      (My mistake: I used Book Proofer to test and it seemed that I had a very bad cache problem. Restarting the iPad did the trick.)

      Thanks for counter checking,
      Yves

      Delete
  3. i really appreciate you work.. you have been a great helper to me. XX

    ReplyDelete
  4. Thank you!!
    It is working.
    Of course, epub with Apple steroids does not conform to epub standard and is rejected by epubcheck. :(

    ReplyDelete
  5. I couldn't get the multiple classes to work as described, but didn't dwell on it since I found that I could combine the respect-class with any chosen image-class like this: img class="respect image-4". (I'm not yet css-native enough to know what to call that kind of semantics.) The problem I found, though, was that the images were made negative in night-mode when they had the respect-class. Thanks a lot, anyhow.

    ReplyDelete

More of my books