Home > Blog > E-Books & Readers > Fancy Free: Some Fun CSS Tricks for Ebooks

Fancy Free: Some Fun CSS Tricks for Ebooks

by | Apr 26, 2017

By David Kudler

Since some readers asked for practical examples of CSS tricks for ebooks, I thought I’d share some of my favorites.

These examples presume that you’ve got a working understanding of how to use Cascading Style Sheets to make beautiful ebooks. If you haven’t read the previous posts on the anatomy of an ebook, on HTML, and on CSS (1, 2, and 3), now would be a good time. Or you can check out my new ebook on ebooks, Inside the Box: An Introduction to ePub, HTML & CSS for the Independent Author/Publisher.

Drop Caps

A favorite way to start off the body text of a chapter or of a new section is to use drop caps. The practice goes back to medieval illuminated manuscripts, which used beautifully illustrated drawings around an enlarged version of the first letter in a chapter to make it easier to find the section you were looking for.

In modern book design, this means setting the first letter so that it’s two or three times the size of the body text (sometimes more), sometimes in a decorative font, and (when cost permits) in a contrasting color. And instead of rising from the baseline of the text, the capital letter drops down into the body of the paragraph — ergo, a drop cap.

Well, ebooks make cost a non-factor, so color is a fun thing to play with here!

There are a few ways to make sure that the first letter (or two, if there are quote marks) of the first paragraph in a section/chapter are drop caps.

The Standard Way: <span>

The easiest is to mark the letter you want to be drop caps using <span class=”drop-caps”> tags, like this:

Then, in the CSS stylesheet, place the following rules:

Let’s look at those rules line by line.

p.Body-First and span.drop-caps are the selectors. So any <span> with the class drop-caps or paragraph with the class Body-First will follow the rule.

Why do I need a separate Body-First paragraph style? Well, drop caps should start flush against the left margin. If I’m indenting the first line of my paragraphs, I need to make an exception in the case of the first body paragraph: text-indent: 0;

float:left; tells the ereader to push the whole span container over to the left margin of the enclosing container, and tells it to flow the rest of the text around the span.

font-family: Zapfino, cursive, serif; tells the ereader to apply the decorative handwriting font Zapfino to the letter. If the ereader doesn’t have that font, it will display its default cursive font. If it doesn’t have one of those, it will display a serif font. [1]

color:darkred; tells the ereader to display the drop cap in, you know, dark red.

font-size:3em; tells the ereader to display the drop cap at three times the size of a standard capital letter.

The remaining rules all control the position of the drop cap relative to the body text. Those happen to be the measurements that I came up with for this example. Please feel free to play around with them until you’re happy with how they look.

By the way, here’s how that paragraph would display:

Not bad! The full justification and short line-width makes the paragraph a little loose. But the drop cap looks nice!

The Easy Way: Combinators

Now, if I didn’t want to have to place a span around every drop cap (because, come on, that’s a pain), I can use something called a pseudo-element selector. Pseudo-elements allow me to tell the ereader, for example, to select just the first letter (or first punctuation mark and letter) within a paragraph with the class Body-First.

What would that look like?

The pseudo-element is ::first-letter. It selects… the first letter within the selector element. :-) There are lots more that you can play with (see the IDPF page for a basic rundown).

Except for the selector, that’s exactly the same rule as before — but now, every time we set a body paragraph to the class Body-First, it will automatically gain a drop cap! No setting the span element around the first letter. Very nice!

But say we want to be REALLY lazy, and don’t even want to set a separate class for the paragraph — we want all the body paragraphs to be the same, but we want the first one after the chapter head or a section break to have a drop cap.

That’s where the awfully named CSS combinators come to the rescue.

Basically, combinators (blech) allow you to apply CSS rules to certain combinations of selectors.

If you put one selector after another, separated by a space, that tells the ereader that any time you have the second selector inside the first, you should apply the rule:

Here’s what that might look like:

That rule means that any paragraph text (<p>) inside of a blockquote element will be smaller than the standard text, and will be inset from both right and left margins.

Now, often you want to add a line of whitespace before and after a quote. If I add a top and bottom margin in the rule above, however, that would add two full spaces between every paragraph in the quote—one above and one below. Definitely not what you want:

So let’s turn to another of the combinators (blech), the plus sign (+). Adding + between two selectors means that if the first element is followed by the second element, the ereader should apply the rule to the second element.

So rather than add a top margin to every blockquote element, we could apply the following rule:

The pair of selectors (p + blockquote, blockquote + p) mean that if you have a paragraph followed by a blockquote or a blockquote followed by a paragraph, the ereader will add a line of whitespace:


Now, let’s get back to our drop caps.

So say we have applied the <h1> tag to every chapter head, and the <h2 class=”section-break”> tag to every… section break.

Here are our new style rules:

And here’s the code:

Thanks to our friends the pseudo-elements and combinators (blech), here’s how that looks:

The advantage here is that all I need to do to get that nice drop cap at the beginning of every chapter is to set the chapter head to <h1> — something I can do without even having to HTML code view in a lot of text editors.

Now, a lot of older ereaders (old MOBI7 Kindles, old Nooks, etc.) won’t display those drop caps at all. But having the code in there shouldn’t hurt anything—it will just display as standard text.

Simulated Text

In one of my earlier articles, I showed an example where I used CSS to emulate the iPhone Message app (which is itself styled by displaying CSS — just saying).

A couple of people asked how I did that; here’s the HTML:

You’ll notice that the speaker on the left side of the screen (Jordan) has her paragraphs set to one class (Jordan), while the speaker one the right side (Allison), has another class (Allison). I tried to figure out a way to do that with combinators (blech), but that didn’t allow me to have the same person speak twice in a row, as Jordan does here.

So here’s the CSS that makes the magic:

Everything I did there should be pretty easy to figure out. The one bit I didn’t look at in my discussion of CSS properties is the border-radius property. Quite simply, that rounds the corners of the boxes — exactly like the ones that Apple uses.

I used the same font that Apple uses as well, and as close to the same colors as I could manage. I also set the margins proportional to the screen size of the ereader.

If I had wanted to get really fancy I could have created a whole iPhone-like box with cell bars and…

But I thought that this was enough.

By the way, this will display fine on most current ereaders; on many older ones, it just displays as plain text. I thought about using @media queries to create a different rule for old Kindles, but realized that for those clunkers, plain text was about as good as I could get.

[1]And if it’s a Kindle, it either won’t display anything different at all (if it’s an older, MOBI7 Kindle) or it will display it in Bookerly. Congratulations!

Photo: Pixabay.com.

tbd advanced publishing starter kit