Saturday, June 12, 2010

Goodbye Widows and Orphans, or yes you can force page breaks in ePub


[links to ePub samples now at end of article]

Working on a tip from a follower on Twitter, the other day I documented how to insert video into an iBook for iPad. Let's just say I got a lot of visits to my site for that, and continue to do so.

What I have to share with you today also originated from a follower on Twitter, Rick Gordon, and though it's not as sexy as video, it's much, much more significant. And it validates.

Rick tweeted the following yesterday afternoon:
Enclosing a ul or other block elements in a div set as inline-block causes whole block to shift page at once. Cool! #ipad #epub #ePrdctn
Having some control over page breaks is an ebook designer's number 1 concern right now. I'm thrilled to confirm that the battle has shifted to our favor.

Because it works. If you set the display property for a div to be inline-block, iBooks will display the contents of the entire div together on a single page, skipping to a new page if necessary, unless the entire div can't fit on a page by itself, in which case it will be divided across pages.

It's simple and very powerful: div {display: inline-block}

Here's a short document with no inline-block display. Notice how the header is separated from the paragraph that follows it, and even how a bit of the background bleeds through to the following page. Icks. The image and caption are likewise separated. Terrible!

page 1 No inline-block
page 2 no inline-block

Here's the exact same document with one div enclosing the header and paragraph and second div enclosing the image and caption. Both divs were set to display:inline-block. The result? Goodbye widows and orphans:
Page 1 inline-block
page 2 inline-block

Where can you use this? As shown here, if you have a series of illustrations with captions, use inline-block to keep the caption right under the illustration.

If you want a header to never appear alone at the bottom of the page, but always be followed by at least one paragraph, just enclose the header and the paragraph in an inline-block div.

Perhaps you don't want any orphans or widows at all. You could conceivably set every p element to have inline-block display so that they will always (when possible) be displayed on a single page. (If the div can't fit on a single page, it will be divided across multiple pages. Which makes sense.)

Anywhere you might use InDesign's Keep functions, the display:inline-block rule will come in handy.

The possibilities are endless. And it works in iBooks, Adobe Digital Editions, and seems to work also on Barnes & Noble's nook. Perhaps everywhere, please let me know if you test it on other readers.

Addendum: Here's the ePub without inline-block. And here's the ePub with inline-block.

25 comments:

  1. Could you provide a link to a test ePub? (I could make one myself, of course, but I'd like to be able to reproduce your results here)

    ReplyDelete
  2. As I haven't had any success tearing apart the epub to edit the code. Is there any way to do this in InDesign?

    ReplyDelete
  3. Liz,

    This is great, especially for the cases you've noted—heads and captions. Thanks for doing all this research!

    For widows and orphans in body text, I thought I had read of another way to avoid them, though I can't find my notes now. Recently, I read Wolf Hall (approx. 800 pages) on my nook and there were no widows or orphans. The extra line space at the bottom of a page was obvious to me (but not in any way distracting) when the last 2 lines of a paragraph were forced to the top of the next page. Do you know how this might have been done?

    ReplyDelete
  4. @Blaine: samples posted at end of article. Let me know what you think.

    @David: can I help you dig into the ePub? There's so much more to do once you do. And no, InDesign doesn't do this yet. There are a number of things you can style in InDesign AND style in CSS, that InDesign doesn't export. "Keep" is now one of them.

    @Tina: So do you mean paragraphs broke across pages but there were never a single-line widow/orphan? I'd love to see it. Very interesting.

    ReplyDelete
  5. Yes, that's what I meant. I wanted to open it to see what they did, but the ePub is encrypted. I'll send you a couple of pictures.

    ReplyDelete
  6. @Liz - thanks very much! I'll try these out in rePublish and see what I can do about ensuring that it does the right thing!

    ReplyDelete
  7. @Blaine: You're welcome! And what's rePublish?

    ReplyDelete
  8. Great work Liz. I am in a "discussion" with a customer who wants all their A Head sections turned into separate files so they start at the top of each reader page. This will show them that layout is better with CSS elegance than the file chopping brutality of a thousand XHTML files.

    One small step for mankind.

    ReplyDelete
  9. Very timely, thank you! I just spent a few hours last week validating that "page-break-after: avoid;" does not work on the iPad. I had just converted 100+ images to include their captions in the jpg. Then I watched Apple's iPhone 4 launch last week and its new iBook reader. The screen shot of the new iBook has the option to set the background color to offwhite. I presume that the jpgs with the embedded caption would look horrible since the "background" in the image is white. I am going to convert back to images and text captions and use this - along with using it to keep headers from breaking as a single line. Thanks!

    ReplyDelete
  10. Hi Liz,

    I couldn't find a field to ask questions, so I figured this would have to do.

    I have a landscape-oriented picture book that I'm trying to format into an ePub file, but it always save in portrait ratio. Is there a way to save the book in a landscape ratio?

    Also, is there a way to place text over an image, like a comic book, in ePub?

    Thanks,
    Clayton

    ReplyDelete
  11. Liz, thanks for the research. Having page break control is a massive bonus (especially for images with captions etc).

    Do you find that once the inline-block element gets larger than a page, that the page break is not clean? I was experimenting and it was breaking in the middle of a text line rather than between lines.

    Clayton, I was putting text over images just using absolute positioning. However, when I upgraded to iBooks 1.1, this stopped working - so I'm looking for a workaround here too. Did Apple stop supporting absolute positioning in the latest iBooks?

    ReplyDelete
  12. Breaking in the middle of a line? Can you point to a screenshot? I have found that if the inline-block is too big to fit on a page, it will break (which is probably a good thing, given possible alternatives).

    And yes, I heard that absolute positioning no longer works in iBooks 1.1.

    ReplyDelete
  13. I saw the breaking in the middle of a line with my original page-break control solution (a div with float: left and width: 100%). It would also do this in the middle of an image. It only happened when the size of the block you didn't want to break got bigger than a single page. It looks like your inline-block solution does not have this problem though, so I've switched to this.

    That's really unfortunate about no absolute positioning. I was using this to make clickable image maps that would scale when the user switched the iPad page orientation. iBooks seems to ignore any of the standard map/area tags specified as a percentage, so they don't scale with the image.

    ReplyDelete
  14. I have managed to place text over images by using position: relative and a negative top margin on a div immediately under the image. It works in iBooks on the iPad. I even used a nice 50% alpha background for the div so the image shows through.

    ReplyDelete
  15. @Eric: have you tried it with iBooks 1.1? If so, and it still works, I'd like to see it.

    ReplyDelete
  16. If there are div elements one after another with inline-block property, div elements will be displayed abreast and not one below another. There needs to be e.g. p element between two div elements to avoid this to happen.

    I'm not also quite sure what you mean by "You could conceivably set every p element to have inline-block display so that they will always (when possible) be displayed on a single page." I tried to put p{display:inline-block;} but it didn't work. What do you mean?

    ReplyDelete
  17. Hi Liz,
    Thanks - very helpful post!

    I am struggling with an image-caption problem.

    What I want is the image to fill the page with a caption beneath it. The image should also have a border.

    I can get the image size fairly easily done by setting height="100%". The width is then for pictures with greater height then width somewhere less than 100% of the page. However, the caption runs beond the width of the photo. THis looks really ugly.

    Is there anyway to set the css caption definition running only the width of the image?

    for some reason I cannot get the border to work either. It just does not show up. :(

    Any help would be much appreciated.

    Thanks,
    Ann.

    ReplyDelete
  18. What about how to make the image and caption centered on the page and the caption left-justified?

    I've tried but no luck.

    JK

    ReplyDelete
  19. Hi Liz,

    You say:

    "If the div can't fit on a single page, it will be divided across multiple pages. Which makes sense."

    For iBooks, I think you're right. But for one platform alone I don't think this is really usable. Try, for example, wrapping the first paragraph of your sample epub file in 'div class="keeptogether"' and then previewing in Adobe Digital Editions at the smallest size. It seems that if the content won't fit on a whole page in ADE, the rest of the container is just not displayed; the content in the next page skips to the next element outside the inline-block. The same, in fact, is true for floats in ADE - I'm trying to find a good way to set poetry (left-aligned centred block) and this seemed like the best solution, but it seems that ADE doesn't understand the concept of a block element spanning more than one page, making it impossible. And since ADE is the basis for a number of other e-readers, this technique becomes unworkable except for small / dispensable bits of text (like a caption perhaps).

    If you have any comments on a better way of setting poetry / long bits of inline-block text as I mentioned, I'd love to hear them... This feels horribly similar to coding rubbish HTML+CSS hacks for IE6 back in the day. Sigh.

    Cheers,

    Alex

    ReplyDelete
  20. Liz,
    Thankyou very much for this. I have just created my first epub, everything looked good at testing stage but when loaded it onto ibooks, I lost all the page breaks and looked really bad. I am going to give it another go with the inline block.
    I will keep-togther the heading and first image, which should start at the top of a new page, then all other 'p' stuff should follow inline underneath? Is this correct?
    Dave

    ReplyDelete
  21. I need help with what you're discussing here - but I use Jutoh to create my ebooks and the addition of the code you're talking about is a foreign language! Do you have any thoughts on how to make this work with Jutoh?

    ReplyDelete
  22. Hi Liz,

    iBooks Author seems to have some options to prevent widows and orphans et cetera. There must be some coding behind that, right?

    http://www.dummies.com/how-to/content/how-to-control-hyphenation-and-line-breaks-in-iboo.html

    ReplyDelete
  23. I have tried keeping images and captions together using the div tag with display:inline-bloc, as described above. The only problem is that the images and captions become left-aligned on the page instead of centred, as I would like. Is there a way around this?

    ReplyDelete
    Replies
    1. Peter,

      It's possible that it is being centered within a smaller block than the page width. Try setting the inline block's width to 100%.

      Delete

More of my books