iBooks 3.0.1 inline-block Bug

I’m back on ebook formatting after a long period working on paper book layouts, and I find that something I used to rely on is broken in the latest version of iBooks (on iPad, at least), which was released a few days ago. It’s been commonplace to use a CSS declaration like:

div.nobrk {display:inline-block;}

to group elements (such as a heading and the paragraph that follows it) such that iBooks will avoid, if possible, separating them with a page break. This is a work-around for iBooks’ lack of support for CSS’s official page break properties, and the previous behaviour was that iBooks pushed the whole block (the heading plus the first paragraph, for example) onto the next page, whenever there is not enough space to render that block on the current page.

What I’m observing with iBooks 3.0.1 is that it fails to push the block onto the next page. Instead, it renders as much of the block as possible on the current page, and then renders the remainder on the next page. The bad news is that “as much as possible” means as many lines and/or fractional lines as will fit in the space. That’s right, it will render part of a line (which could even be the title) at the bottom of a page, and the rest of that line at the top of the next page. Sometimes you get most of the line rendering at the bottom, with various lopped-off descenders appearing as “debris” at the top of the next page. I’ve seen similar behaviour on older versions of iBooks before, in ePubs that meddle with the line height, but that is not the explanation for what I am seeing now.

This new way of rendering inline blocks means that many ePubs that used this technique and worked well on older versions of iBooks, will currently render incorrectly, with the books that have been most carefully designed being the ones most likely to fall prey to the bug, since those are the ones where the designer will have painstakingly inserted all those <div class="nobrk"> ... </div> blocks to keep elements together on the same page.

Update: here is a screenshot showing the bug in action:

iBooks 3.0.1 Inline-Block Bug

The good news is that iBooks currently supports page-break-inside:avoid;, meaning that the page I showed above now renders correctly, with the titles and text kept together and no split line (though I’ve still had no luck in iBooks with page-break-after or page-break-before). This is of course not much help for books that have been previously released using display:inline-block; to keep elements together, but at least it gives us an option going forward.

Kindle Format 8 Tools and Information Released

New Kindlegen, new Kindle Previewer, new Kindle guidelines…


Ahem. The days of Kindle Previewer being a quick, lightweight download appear to be over; hardly surprising given that KF8 requires a much more complex rendering engine than the old Mobi format.

My advice for the time being is to consider what aspects of KF8 will genuinely benefit your project, and to keep portability (both of your book’s source files to ePub, and of your Kindle files to older devices that will never see KF8 support) very much in mind.

Manually Tweaking eCub’s Generated Table-of-Contents

In Handcrafted Ebooks I relied extensively on the excellent (and free) eCub program to build ePub files. eCub is an ebook builder, not an ebook layout tool — it takes the content and layout expressed in a set of .xhtml and .css files, and compiles them into a .epub file with the proper internal references and format.

One set of internal references it creates is a table-of-contents file, which can be found in the OPS subdirectory of eCub’s BUILD directory, and is called TableOfContents.html. This content file is styled by the following CSS rules, which by default are generated by eCub and placed in its own style.css file:

.toc_heading { text-align: center; margin-top: 20pt; margin-bottom: 20pt; }
.p_toc { text-indent: 10mm; margin-top: 10pt; margin-bottom: 10pt;}

I usually incorporate (variants of) these rules into my own style sheet file, instead of using eCub’s generated style.css file; that way, there’s one fewer place to look when editing the CSS for a project. Also, I never call my style sheet file style.css; that way, there’s no risk that eCub will overwrite it because I forgot to clear the relevant options check box.

The TableOfContents.html file itself contains TOC entries as follows:

<h3 class="toc_heading">Table of Contents</h3>
<p class="p_toc" style = "margin-left: 20;"><a href="a001.html">Part 1: Orientation</a></p>
<p class="p_toc" style = "margin-left: 20;"><a href="a002.html">Terminology</a></p>
<p class="p_toc" style = "margin-left: 20;"><a href="a003.html">Basic Concepts</a></p>

eCub’s default table-of-contents comes with default formatting and with no indentation to reflect the various levels of information (so chapter headings are shown at the same level as section headings, for example). This isn’t such a problem where NavMap navigation is available, since eCub does support multiple navigational levels in the NavMap, but where users need to navigate directly from the Table of Contents file — as with a Kindle (Mobi) file — then it would be nice to offer them something that reflects the structure of the document better. If desired, it’s also quite easy to tweak the default CSS styling so that it fits the look-and-feel of the rest of your layout. I’m inclined to close up the margins between TOC entries, for example.

To create additional levels of content you can create corresponding new CSS rules, so you might end up with:

.toc_heading { text-align: center; margin-top: 20pt; margin-bottom: 20pt; }
.p_toc { text-indent: 10mm; margin-top: 10pt; margin-bottom: 10pt;}
.p_toc1 { text-indent: 20mm; margin-top: 10pt; margin-bottom: 10pt;}

Since it’s better to specify indents in ems rather than in mm, and with some other changes applied to tweak the margins and so on, we could end up with the following rules in our custom CSS file:

.toc_heading {font-weight:bold; text-align:center; margin:0 0 0.75em 0 !important;}
.p_toc {text-indent:0.5em !important; margin: 0 0 0.49em 0 !important;}
.p_toc1 {text-indent:1.5em !important; margin: 0 0 0.49em 0 !important;}

(Note that Kindle devices displaying Mobi format only have a resolution of 1em, so 0.5em and 0.75em will round up to 1em, while 0.49em rounds down to 0em).

Next, we need to edit the TableOfContents.html file to remove the hard-coded margins, and to apply the p_toc1 style to the content lines that we want to designate as being (indented) sub-headings. Since this is a job that will ideally only be done once, leave it until a fairly late stage in your project, when the structure of your ebook won’t be changing — the last thing you want is to have to re-generate a table of contents from scratch within eCub, because then you’d have to re-apply all your TOC edits.

With the new styling applied, the previous TableOfContents.html fragment becomes:

<h3 class="toc_heading">Table of Contents</h3>
<p class="p_toc" ><a href="a001.html">Part 1: Orientation</a></p>
<p class="p_toc1"><a href="a002.html">Terminology</a></p>
<p class="p_toc1"><a href="a003.html">Basic Concepts</a></p>

At this point, we’re in full control of the TableOfContents.html file, so we can modify it as we wish — there’s an opportunity to put ePub-compatible, Kindle (Mobi) friendly styling in, for example.

Important! The TableOfContents.html file in your build directory gets recreated every time you compile the ebook with eCub, so you’ll need to make a copy of your custom version somewhere safe (for example in your ebook’s project directory along with the rest of your source files).

The final piece of the puzzle is: how do you incorporate the modified file into your ePub, when you know that eCub will insert its own generated copy of the file during compilation? The answer is to re-create the ePub file outside of eCub, using manual commands. I automate the process with the following Windows batch file, which needs to be run from the corresponding ebook’s project directory (it should be easy to adapt this to other platforms):

del buildOPSTableOfContents.html
copy TableOfContents.html buildOPS
attrib -r buildOPSTableOfContents.html
del book.epub
cd build
zip -X0 ..book.epub mimetype
zip -r ..book.epub META-INF OPS
cd ..
kindlegen book.epub
kindlestrip.py book.mobi strippedbook.mobi
del book.mobi
rename strippedbook.mobi book.mobi

Obviously, the various tools such as zip, kindlegen and kindlestrip.py (if you wish to strip out the kindle bloat from your generated file) need to be on your command search path. Finally, note that it’s a small tragedy if you accidentally let eCub overwrite the most up-to-date copy of your tweaked TableOfContents.html — for example, by dragging-and-moving when you meant to drag-and-copy. One way to avoid this is to make the file read-only, changing that attribute when you need to edit the content, and changing it back afterward.

Amazon Announces Kindle Format 8

Amazon has announced the replacement for its existing Kindle (Mobi) format; the list of supported HTML and CSS tags is here. You can also sign up to be notified when the publishing tools and guidelines are released.

Plainly, Amazon is moving toward something that’s much closer to ePub, which lends further credence to the idea that the reason for the “Kindle Bloat” I discussed in a previous post, is that new generations of Kindle software and tools will make use of the ePub information that’s incorporated into the Kindle (Mobi) files.

What about the effect on creating ebook files that are portable between ePub and Kindle? On the face if it, the closer that Amazon gets to supporting the same features as ePub does, the easier the portability job should be — and the fewer compromises ebook designers will need to make, when creating content that will work on both platforms.

However, a possible fly in the ointment is the position of older Kindle devices, which apparently are not going to be upgraded with the new Kindle 8 capabilities…

“Kindle Fire is the first Kindle device to support KF8 – in the coming months we will roll out KF8 to our latest generation Kindle e-ink devices as well as our free Kindle reading apps.”

… which begs the question of the fate of previous-generation devices that aren’t in line for the upgrade (I guess because they are not capable enough). Will the Kindle 8 standard have the option to embed an old-fashioned Mobi file, for these older devices to use? If so, designers may still have the opportunity (and the headaches it will doubtless take!) to create ebooks that can adapt to the oldest Kindle devices — though clearly there comes a point with complex layouts that this must become impossible or impractical due to diminishing returns, and previous-generation Kindles must be left behind.

Ebook Covers: a Kindle Consideration

Book covers displayed on product pages in Amazon’s Kindle store are emblazoned with a special logo: the words “kindle edition” appear below the book cover, and a small image of a Kindle reader is superimposed onto bottom-right corner of the cover itself. This superimposed image obscures part of your cover, so when designing book covers that might some day be used for Kindle editions (including covers that are originally intended for use with paper editions or ePubs) you might want to keep important graphical elements away from this bottom-right area. Alternatively, you might prefer to create custom Kindle covers that take this issue into account.

You can probably judge the obscured area by eye, but if you want to set up guides showing its extent, you could always find a suitable cover image on the Kindle store — one that has the same aspect ratio as your book cover — and then crop it appropriately, enlarge it to match your cover, and paste it into a layer within Photoshop or whatever equivalent program you use. The pasted cover then becomes a template from which you can position guides to show exactly where the “unsafe” area is.

We generally create ebook covers at 600×800 pixels, and the unsafe area is then approximately 82×146 pixels.

Kindlegen Bloat: Strip it or Leave it?

If you’ve worked with many ePubs and converted them with Kindlegen while paying attention to file sizes, you might well have noticed that the Kindle files are much larger than the original ePubs — typically around twice as large. It turns out that Kindlegen stashes a copy of the original ePub sources inside its output file, which explains the doubling of size. Unfortunately, this can lead to super-sized Kindle files, particularly in heavily-illustrated works, since images get duplicated along with everything else.

To see how you can strip out this bloat, head over to the Mobileread forums, in particular to pdurrant’s post about his excellent Kindlestrip Python script and AppleScript wrapper. Note that if you don’t already have Python, you’ll need to download and install it before you can use this script.

For many people (me too!) the immediate instinct will be to run the above script on everything, in order to minimize file sizes, transfer/bandwidth requirements, and space on our customers’ Kindle devices. However … consider why Amazon might have designed their conversion tool to force the inclusion of this source information in its output file; they hardly did so by accident. Are they planning to use the stashed information in future versions of their Kindle hardware and software, to enable future Kindles to get closer to the layout of the original ePub? Will future generations of Kindle support ePub directly, and try to find ePub files inside Kindle files? If so, then clearly there’s a trade-off involved in the decision of whether to strip the file.

Personally, I’d consider heavily illustrated works as clear candidates for stripping, since the duplication of images is so costly. And, if you’ve designed your ePub to be fully “Kindle-friendly” then maybe there’s little benefit to leaving the extra information in place, since the basic Kindle version will already be fine. However, for Kindle files that suffer by comparison to their ePub originals, or where the overhead is negligible, you might want to consider leaving the bloat in place, in the hope that it might come in useful one day.

Kindle CSS Weirdness

Here are some Kindle CSS gotchas I’ve come across recently. I’ll update this post with more such oddities as (or if) I come across them.

  • text-align:center; fails if designated as !important, even if the left and right margins are set to zero.
  • text-indent:0; fails (ignored). It works if you specify the measurement: text-indent:0em;

These quirks are present in each of the reader programs I tried: Kindle Previewer, Kindle for PC, and Mobipocket Reader. This leads me to suspect that they are bugs in Kindlegen rather than in the Kindle reading software; I don’t know how Kindlegen works but my guess is that it contains a CSS translator that generates inline formatting, leading to possibilities of flawed HTML being generated if the translation code isn’t spot-on. If so, we can hope that these quirks will be fixed in a future Kindlegen release. In the meantime, the potential work-arounds/trade-offs are obvious — but note that Stanza on iPad requires !important in order to center body text; you might want to force body text centering on Kindle by using <div style="text-align:center;"><p class="MyCenteredClass">...</p></div> instead, in order to maximise the portability of your ePub.

ePub Validation, iTunes and Flightcrew

You might already be aware that iTunes modifies any ePub files that it transfers to a device, by adding its own metadata file (iTunesMetadata.plist) into the ePub container. Epubcheck version 1.1. issues warnings when validating such modified files, because the files present in the ePub no longer match the manifest in the content.opf file. While I think the iTunes developers were extraordinarily rude in silently modifying user files in this way, in practice I have to admit that it’s hardly a game-breaker. Still, you might consider it cleaner and more elegant to ship ebooks that have been freshly-generated and not exposed to iTunes.

On the subject of ePub validation, if you haven’t already done so it’s well-worth checking out Flightcrew, which is capable of finding many problems that epubcheck misses. The author has blogged about it here.

ePub-compatible Kindle Centering

Amazon’s current Kindle-formatting guidelines offer two ways of centering content. The recommended method is to enclose the element within <center>...</center> tags, and the alternative is to apply the formatting within the element’s tag: <p align="center" style="text-indent:0">...</p>.

Unfortunately, neither of those methods are ePub-compatible; they will cause the ePub version of the book to fail validation. In the meantime, using simple CSS centering that’s suitable for ePub formatting, such as h3 {text-align:center;} doesn’t work on Kindle.

Handcrafted Ebooks offers a general solution to such cases where the ePub and Kindle versions of a book require different formatting or content, based on text-processing tools that generate the appropriate coding for ePub and Kindle as needed. The advantage of this is that it’s possible to use advanced ePub formatting, while also creating (simplified) Kindle files from the same set of XHTML sources. The disadvantages are that it adds complexity to your workflow, and that your published ePub file can’t simply be turned into a Kindle file by running it through Amazon’s Kindlegen converter. (Or at least, such a conversion will not lead to professional-looking results).

To help get around these two problems, I’ve now found two ePub-compatible ways to center elements on Kindle. Firstly, you can code heading elements directly in CSS; you just have to force the left- and right-margins to be zero. For example: h3.title {font-weight:bold; text-align:center; margin:0 0 0.75em 0 !important; page-break-after:avoid;}. Secondly, you can wrap content in a <div style="text-align:center;">...</div> block. You can also apply a CSS class to the <div> tag, of course, so you can make it do the more usual kind of CSS centering used with ePubs as well.

In the version of Gerard’s Herbal that will be offered to retail stores, I used the first method to center titles, and the second method to center images. The second method also works on body text (update: I’ve found a case where it failed, while trying to center several lines of body text in a short file. Possibly Kindle makes a judgement about the proportion of body text you’re trying to center, much as iBooks seems to. In any case, I was able to center the text by applying style="text-align:center;" to each paragraph individually).

It’s important to note that the above centering methods are not documented in the current Amazon Kindle Formatting Guidelines, and therefore technically they are unsupported and might possibly stop working in future. On the other hand, if the different centering requirements of ePub and Kindle are the only things keeping you from having an ePub file that’s fully portable to Kindle, simply by running it through Kindlegen, then you might well decide that the downside of using an unsupported/undocumented feature is worthwhile.

iBooks v1.2 File Update Failures and Glitches

When you transfer a new version of an ePub file into iBooks, it can fail to recognise the new information. Generally I find this to be a problem when fine-tuning CSS in order to improve a layout, because iBooks refuses to show my changes, making the edit-debug cycle incredibly frustrating; the last thing you want to see is the previous version of the book you’re developing. In Handcrafted Ebooks I mentioned that exiting iBooks and running different software would fix this. Unfortunately, this no longer works reliably with iBooks v1.2 and IOS 4.2, both of which were recently rolled out by Apple. Maybe it’s something to do with IOS 4.2’s multi-tasking abilities, allowing iBooks to cling more tenaciously than ever to phantom data; for whatever reason this problem now seems harder to clear by loading other applications.

Happily, the IOS 4.2 Task Manager (aka the Multitasking App Tray) lets you work around this as follows: exit iBooks, double-tap the Home button, and you will see a list of recent applications that includes iBooks. In this list, press and hold the iBooks icon until the red-circled ‘-’ sign appears, then tap that sign. The iBooks application should close, and vanish from the list. Double-tap Home to exit the App Tray, then re-start iBooks and re-open the book you’re working on. So far, this has worked reliably for me — and saved a lot of hair-pulling when incrementally testing new ePub versions.

Update, February 2011: iBooks version 1.2.1 seems to have improved the above issue. I now find that the following sequence is usually sufficient: 1. close the book in iBooks, returning to the app’s Library view. 2. Delete the old version of the book from within iTunes. 3. Drag the new version of the book into iTunes and wait for it to sync. 4. Open the book in iBooks. However, the occasional glitch can still occur, so you might still need to resort to the old method.