Wednesday, February 8, 2012

Cross-platform multiple indents in ebooks

Sometimes I worry that I don't do enough real world work to know what the actual problems that ebook production people face. So when someone poses an interesting question on #eprdctn, I like to take a look.

Today, @ebookartisans was trying to get multiple indents to work on old Kindle, new Kindle, ADE, NOOK, and iBooks from a single EPUB file (obviously KindleGenned into a mobi for Kindles). She was using a combination of code from Joshua Tallent and myself. It turns out my code only works on first level indents on Kindle. Unfortunately, Rick Gordon (another #eprdctn regular) reports that the NOOK won't look at any code that comes after a media query, and so she was having trouble getting NOOK to do what she wanted.

Does this give you flashbacks of hacks for hiding CSS from IE? Well, it's the same show, so many years later. So, if you remember, you're getting old like me.

Thankfully, we have somewhat better tools this time around, in the form of media queries, which I started explaining a few weeks ago.

The problem with indents is that Kindle has some built-in funky behavior. So, if you were setting up the code just for old Kindle (e.g., not Fire) you might use the following:

<style type="text/css" media="amzn-mobi">
.level1 {text-align:left; text-indent: -30px; }
.level2 {text-align: left; text-indent: -60px; }
.level3 {text-align: left; text-indent: -90px; }
</style>


You'd also have to add extra spaces in front of each level2 and level3 (and successive levels) to give a left margin to the first line. This is Joshua Tallent's hack (actually he uses &#xa0;, but @ebookartisans says that doesn't work on NOOK):

<p class="level3"><span class="spaces">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span>•&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;The mean aunt had her own traumatic childhood, deserving of treatment in a Roald Dahl novel.</p>

Kindle- multiple indents

Though I salute Joshua's ingenuity, I admit I hate the spaces, and would only use such a hack in extreme need. Instead, I'd advise against using multiple indents. But in case the need arises, we'll forge on!

Since NOOK completely ignores the "not amzn-mobi" media query and any CSS that follows it, the trick is to put the NOOK (and other ereader code) in a stylesheet without a media query, and before the aforementioned old Kindle stylesheet. I'll also slip in some code that hides the extra spaces everywhere except in old Kindle.

<style type="text/css">
.level1 {margin:0 0 0 2em; text-indent: -2em;}
.level2 {margin:0 0 0 4em; text-indent: -2em;}
.level3 {margin:0 0 0 6em; text-indent: -2em;}
.spaces {display:none}

</style>


<style type="text/css" media="amzn-mobi">
.level1 {text-align:left; text-indent: -30px; }
.level2 {text-align: left; text-indent: -60px; }
.level3 {text-align: left; text-indent: -90px; }
.spaces {display:inline}
</style>


Here's where you have to keep track of CSS inheritance rules. Remember that later CSS overrides earlier CSS as long as it has equal importance. So, the text-indent in old Kindle will override the earlier CSS. That's what we want for text-indent but not for margin-left. So, just add in margin-left: 0; for each style in the Kindle stylesheet:

<style type="text/css">
.level1 {margin:0 0 0 2em; text-indent: -2em;}
.level2 {margin:0 0 0 4em; text-indent: -2em;}
.level3 {margin:0 0 0 6em; text-indent: -2em;}
.spaces {display:none}</style>


<style type="text/css" media="amzn-mobi">
.level1 {margin-left:0;text-align:left; text-indent: -30px; }
.level2 {margin-left:0;text-align: left; text-indent: -60px; }
.level3 {margin-left:0;text-align: left; text-indent: -90px; }
.spaces {display:inline}
</style>


That code works in old Kindle, Kindle Fire, NOOK, ADE, and iBooks:

Kindle-Multiple indentsKindleFire-Multiple Indents

NOOK-multiple indentsiPad-Multiple indents

ADE-multiple indents

It doesn't take a sharp eye to see that the words in the first line don't quite line up with the second and subsequent ones, AND differ from ereader to ereader. There is no tab in EPUB (or HTML), and each ereader seems to measure spaces its own way. If you want the lines perfectly aligned, you'll have to use a regular old list. It looks beautiful as long as you don't need to control what the bullet character looks like, as old Kindle will only give you a bullet:

Kindle-lists

Did someone say "EPUB in the Wild"?

Here are both the EPUB file as well as the Mobi file that I generated from it with Kindle Previewer 3.

10 comments:

  1. It works so beautifully, it's like art! Thanks, Liz!

    I think the biggest use I have for this is when songs or poetry occur in the middle of prose. In a print book, these are centered blocks with a margin-left. Clients super hate them flush against the left margin, but they need a hanging indent to look halfway decent when put on a phone-sized device.

    I think if it were a page or book of just poetry, it would look okay starting at the first level flush left, but...

    ReplyDelete
  2. "Since NOOK completely ignores the "not amzn-mobi" media query"

    Hi Liz - this can be a helpful way of targeting Nook. But do you think there's any danger of future updates to Nook supporting this query?

    ReplyDelete
    Replies
    1. Yes, I think that's a very real possibility, though probably less so for older NOOKs.

      I agree that this might be a good way to target NOOK, though any hack like this should be used extremely sparingly, IMO.

      Delete
  3. Hmmm, having trouble getting this to work.
    Do -ve values for text-indent work in KindleGen 2.4 any more?

    ReplyDelete
  4. Hi Liz, thanks for sharing your knowledge...
    I´m trying to use media query in my epubs and it works fine with some readers but ADE ignores it.
    I found that using 3 CSSs is enough to cover most used readers but ADE ignores them all.
    How do you set a CSS for AD and another CSS for iPad?

    ReplyDelete
    Replies
    1. I don't know that you can. I haven't figured out a good way to target iPad yet. So, I try to use code that works tolerably well on both.

      Delete
  5. Hello, you mention a version 3 of Kindle Previewer - was that correct or did you mean something else? I just checked Amazon's download for that and it's still 2.5.1....

    ReplyDelete
  6. Can you please tell me
    whether
    Nook color supports below feature:-
    "@media screen and (max-width: 480px) and (orientation:landscape)"

    ReplyDelete
  7. Hi Liz! Tried with Kindle Previewer 2.85 (the latest I could get), but to no avail. It looks like 'old mobi' refuses any attempt to make 2nd level indents. I avoided spaces altogether. Whenever I set margin-left to 0, text is actually moved all the way left. Would you have any suggestions?
    Thanks in advance.

    ReplyDelete
  8. Hi Liz,
    I tried doing this instead with a linked external style sheet using @media: "amzn-mobi", and legacy kindle failed to inherit the correct css (everything else looks fine). Can you please tell me whether this can be done, so that it looks good in ade, nook, amzn kf8, legacy kindles, nook, kobo. It would be extremely helpful in creating poetry and multiple indents for different readers (especially ones with a lot of separate html files).

    ReplyDelete

More of my books