Tuesday, April 19, 2011

Resizing images in EPUB

Some time ago, a reader wrote to tell me that I had gotten the code wrong for resizing images in my EPUB Straight to the Point book. At first, I thought he was right, but at second and third glance, I realize that he wasn't.

The problem is that the iPad doesn't recognize when you add width information directly to a img element. That is non-standard behavior (read: a bug) and should be fixed.

First, let's look at how CSS deals with images. An image has an intrinsic size, that is, its actual size in pixels. If you don't apply width or height information to the image, either in the HTML or the CSS, the image will appear at its original size. CSS allows you to set the height and the width of an image explicitly in pixels, or as a percentage of a parent element. This means that if you set the width of an image to 50%, the image should be displayed at 50% of the width of the element in which the image is contained, not 50% of the image's original width.

Here's what it looks like in Firefox. The image takes up half of the window width since its ancestor element is the body. So far so good.

image 50%

Enter iBooks. Unfortunately, iBooks has a bug that ignores a width explicitly set for an img element. Just completely ignores it:

image 50% in ibooks

The first part of the solution, as a I describe in EPUB Straight to the Point, is to enclose the img in a div and then set the width of the div to the desired width, either in pixels or as a percentage.

But observe what happens if you remove the width property from the img and apply it to the div that contains the img. In iBooks it (erroneously) works as you want it to:

div 50% ibooks

But iBooks, as we noted, doesn't follow the CSS spec. However, and this is a big however, Firefox, Safari, and Adobe Digital Editions—and all of the ereaders based on ADE, like the Sony Reader and Barnes & Noble Nook—do follow the spec.

The spec says that, by default, if a replaced element, like an image, is too big for its container (say, a div that you've reduced by half) then the image spills out over the edges. That is, it displays just the same. What the spilled out part (the overflow) doesn't do is affect the layout. Which means that any surrounding text just runs over it as if it weren't there. It's ugly.

image width bad on Nook

As you can see, the div has been reduced to 50% of the width of the window, but the image is unaffected. By default, overflow is visible, but doesn't affect the flow of the page, which is why that text just rolls right over it. Ick.

The second part of the solution, (also contained in EPUB Straight to the Point) is to set the width of the img element to 100% of its parent, in this case, the div. Since the div is 50% of the width of the window, and the img is 100% of the div, then the img will also be set to 50% of the window. This works in both iBooks and more standards-compliant ereaders:

div 50%, img 100%

Image width better on nook

At some point, I had suggested using max-width instead of width but that only works in iBooks, not the other ereaders. In other words, it's no solution.

13 comments:

  1. What I've never gotten a handle on is portrait-oriented images. If something's taller than about 600px, it will end up off screen on some ADE-based device at some point. Putting height in the CSS seems to make no difference. Any good catch-alls for all orientations?

    ReplyDelete
  2. Use a size %. That will be based on the screen size of the device. So say you only want the image to be 50% high on the screen, height="50%" would do the trick.

    ReplyDelete
  3. I try this solution, but it didnt work?
    I have image in td tag.
    I try to add div around img and to set div width to 50% and img to 100% but then ibooks dont display image?
    When I remove div around img, image appears...

    ReplyDelete
  4. Hi Liz,

    Im trying to convert a book to epub and in one instance a page consists of one half text running top to bottom and the other half a stack of 3 images. I'd like the photos to stay on this particular page like it is in the print edition, but allow the text to flow if a reader decides to change the font size. In other words, i dont want to attach the photos to a particular paragraph and just wrap the text because if the text size changes, the images may split across pages. Is this possible as far as you've seen?

    ReplyDelete
  5. Given all of the above, for those of us who find it difficult getting our head around coding and want to make some simple epub docs for our students, what editors (preferably Windows) exist that act like e.g. MS-Word (wysiwyg) and will produce epub's (or something that can be converted to epub easily) and conform to the rules as you have described above to ensure images and text flow appropriately, and images scale properly according to the reader device/software being used.

    ReplyDelete
  6. Hi Liz
    Could you explain how to size an inline graphic which appears between two words of a paragraph? If I wrap the img tag in div tag as explained above, it forces the word which appears after the graphic to start on a new line. I've tried assigning 'display: inline' and 'display:inline-block' css properties to the div tag. Any advice you could give would be very much appreciated.

    ReplyDelete
    Replies
    1. I know I'm very very very late but since this bug has not been fixed… and maybe that can help as I discovered other issues!

      In this case, you can't put div (which is a block element) in a paragraph (an inline element). So, in order to achieve what you want to do, you have to specify width/height in img tag

      And specify this width/height in CSS (.class)

      or else iBooks won't display the picture. Please note that also works when the picture is the last element in the paragraph. And the picture is perfectly aligned (baseline)

      It works when the picture is the first element in the paragraph too. However, there is a bug in iBooks in this particular case. All but a few pictures will be shifted (instead of align baseline, it is aligned bottom). Needless to say editing the picture won't help. If you put some extra space at the bottom of the picture, then it will be aligned well in ibooks but aligned top anywhere else…

      For some reason, some pictures will be displayed properly... and I can't guess why.
      Sent a ticket to Apple, answered me to take a look at iBooks Author support. Don't know if it's my EPUB template – which is I admit quite complex – that looks like an iba template but that won't obviously help (and the bug won't be reported to ibooks dev unfortunately).

      Delete
  7. Dear Liz,

    I have a question regarding the new retina display and images sizes - wondering what your solutions or recommendation would be.
    When preparing a cover for instance for the new iPad and image has to be quite large. So we have used - according to the Apple Guidelines - wrapping div containers - so that those large images would be downsized for other displays. Now, we have recognized that this technique results in horrible image display for instance ADE or Sony Readers - with images looking horribly pixelated - I guess thats due to the downscaling. Would you know a good workaround for that?

    Sabine

    ReplyDelete
  8. Well, I got things to resize. I've looked all over the place, read your other blog entries on the matter, tried things to make it center - and it just flat won't! Text-align: center is a bust.

    But thank you for a wonderful blog post.

    ReplyDelete
  9. @ Katrina

    A bit late, but I have had success with putting the image in a div, setting the width of the div, and then putting a corresponding left/right margin around it:
    i.e.
    .image{
    width:50%;
    margin-left:25%;
    margin-right:25%;
    }

    God Bless

    ReplyDelete
  10. One thing that I've tested to work in on-line and PC-based readers is wrapping a link around an image. But it doesn't work at all in my Nook Simple Touch. At the end of every chapter (in a foreign language) I have a long list of footnoted definitions (for beginners in that language). I've made a small graphic as a visual dividier, which if clicked on (you not being a language beginner) skips you past the footnoted list directly to the start of the following chapter. But like I said, it works on the PC in FBReader and Calibri...but not on the Nook. Can you (or anyone) reply with if that's supported on other readers (Kindle, et al)?

    ReplyDelete
  11. Hi Liz,
    I read through your EPUB book but there are no explanations (pardon me if I actually missed that) on how to link an image to external page (internet webpage or itune app store). I could only see how one can link a word to another part of the page within the book.
    In your EPUB book, I could click on the LEARN MORE in the 'Digital Publishing with Adobe InDesign CS6' page to go to the website and also the 'Rate This Book' page, where I could click on the individual book and it would bring me to the iBook Store...this is what I need to do in my book, and will be great if I can get this done as my last hurdle
    Thank you so much, appreciate alot :)

    ReplyDelete

More of my books