Centering in ebooks involves CSS, the box model, inheritance, and ereader inconsistencies. The main problem with centering lies in not understanding how these aspects relate to each other.
The text-align property
I'll start with the simple. There is a CSS property calledtext-align whose possible values are left, right, justify, and center. But there is one very important caveat: text-align only affects inline-level objects within the block-level objects to which text-align has been applied. Let's look at that closely, since it is the source of many misunderstandings and thus errors.Here is a simple
p element that contains text.<body>
<p class="center">Here is some text that should be centered</p>
</body>And here is the CSS:
.center {text-align:center}And here is what it looks like:
You may think that it is the
p element that has been centered, but you'd be wrong. It's actually the inline contents of the p element, an anonymous inline block, if you can stand the CSS parlance, or simply the text itself (if you can't), that is being centered. The p element itself is not centered. How can you tell? We'll set the width of the
p element to 60%, and then set the background color to yellow, so you can actually see it..center {text-align:center; width: 60%; background: yellow}You can now clearly see that the
p element is still aligned left (which is the default in most browsers and ereaders) even while the inline text that it contains is aligned center within the p element.Centering block-level elements
So how do you center a block-level element? The canonical way is to set the right and left margins toauto. According to the CSS spec, when both left and right margins are auto, they should be equal, and thus the item will be centered. And don't forget that unless your block element has a width that is smaller than the window size, you won't be able to tell if it's centered or not.So, to center our
p element, we'd have this:.center {text-align:center; width: 60%; background: yellow; margin-right: auto; margin-left:auto}And we would get this:
This works on most major browsers and ereaders:
And is converted properly for Kindle Fire:
(Regular Kindle doesn't support width and thus can't center a block-level element at all.)
CSS bug in ADE, NOOK, etc.
Unfortunately, ADE, and the ereaders based on it (like NOOK, NOOK Color, and presumably Sony Reader though I didn't test this last one), don't properly interpret the auto value for left and right margins, and the result is that the blocks are not centered:Independence of alignment of contents and of the block that contains them
Before we get to the solution, I just want to underline how thetext-align properties and centering of the block level elements using automatic right and left margins are independent of each other. That is, the alignment of the inline-level elements within a block-level element need not match the alignment of the block-level element. That is, we can center the
p element within the window and then left-align the contents of the p element:.mismatch {text-align: left; width: 40%; background: red;margin-right: auto; margin-left:auto }And that should look like this:
Notice how the image and the text are aligned to the left within a box that is centered on the page.
Again, ADE, NOOK, and presumably Sony Reader, don't properly interpret the right and left margins set to auto:
The Solution
The solution hinges on the fact thattext-align only affects inline elements. (This is why simply enclosing an inner div in an outer div whose text-align property is set to center will not work.) We'll enclose the p elements in a wrapper div, whose text-align property we'll set to center, and then we'll set the display property for the p elements themselves to inline-block. The inline-block value is sort of a hybrid between inline and block, that for our purposes keeps the p elements starting their own paragraphs (like regular block-level elements) but allows them to be affected by text-align (like inline-level elements).Here's the CSS with the new bits in bold:
.wrap {text-align:center}
.center {text-align:center; width: 60%; background: yellow; display:inline-block}
.mismatch {text-align: left; width: 40%; background: red;display:inline-block }And here's our new HTML:
<div class="wrap">
<p class="center">Here is some text that should be centered</p>
<p class="mismatch"><img src="momo.jpg" alt="momo" width="200" height="150" /><br />This image and text will be aligned to the left within the centered block that contains them.</p>
</div>Let's look first at iBooks on iPhone: (I've put it in landscape orientation just so it's easier to see, it looks the same in portrait.)
Everything is as it should be. Our boxes are centered, but the contents within them are centered and left-aligned respectively.
How about NOOK Color?
NOOK Color also likes this solution, even when Publisher Defaults are turned off (although then you have other margin issues).
And Kindle Previewer converts the file just fine for KF8 and the Kindle Fire ("old" Kindle can't center divs but maintains the text-alignment for the inline level elements):
But what happens when you view the ebook in iBooks on iPad?
The boxes are centered as desired. But the text and image that should be left aligned in the lower box are now justified! Look at those ugly spaces between the words. What happened?
Now we've bumped up against iPad's default overrides. Remember that by default, Full Justification is set to ON, hidden away in the iBooks area of the Settings panel. I don't think most people who use iBooks will ever know this setting exists so ebook designers have to plan for it. You used to be able to add a
span tag around the text that you wish to have aligned to the left, but that hack no longer works.Thankfully, there is still a workaround. If you add the com.apple.ibooks.display-options.xml file to the META-INF folder, with the
<option name="specified-fonts">true</option>, the justification that you choose in your CSS will be maintained, regardless of the Full Justification setting chosen. The user can still override your choices by choosing a different font in the Fonts menu, but at least the book will start out the way you want it:To resume:
Thetext-align property only applies to inline elements within the block-level element to which the property is applied. It is inherited by block level elements that may be enclosed in the outer block-level element and in turn applied to the inline elements that the inner block level elements contain. If you need more info on block level vs inline, see the CSS spec or my my HTML/CSS book.The canonical way to center a block-level element is by setting both
margin-right and margin-left to auto. The fact that this is not supported by ADE or NOOK (and presumably not by Sony Reader or other ereaders based on ADE) is a serious bug.You can center block-level elements by wrapping them in another block level element (a
div), setting the text-align to the outer div to center, and then setting the display property of the inner div (or p or whatever) to inline-block.iBooks on iPad has a default setting of Full Justification for text, which you can override by adding the com file to the META-INF folder. This has ramifications with respect to font choice, of course, as well.
iBooks on iPhone has the Full Justification setting, but by default it is set to OFF (presumably because of the narrow screen).
This should be much simpler.
And yes, it's true that I have no AT&T coverage in my office!