View Cart

How To Create Fixed-Layout iBooks, Part 7

Adding Text

Now that you have a working fixed-layout ebook filled with pretty images you'll probably want to add some text (assuming you haven't added it as part of the image). After all, what's a story without words? In this installment of the iBooks tutorial we'll look at how to add live text as a layer over or “around” your art.

Why would you want to do that, when you could just taken to easy way out and put it in the image? Well, I won't go into my diatribe here, except to say that you may as well just make a pdf if all you're going to do is stick a bunch of images together. Making a pdf is vastly easier, and accomplishes the same goal. Moreover, virtually every e-reading device can read pdf's, either natively or with a third party app, regardless of the platform.

What makes ebooks unique - and in many ways superior - to print or images, is the ability to interact with the text to bring up dictionary definitions, copy sections of text for reference, search for words or references, and follow links within the book or externally out on the Web. Moreover, live text layers allow for text-to-speech functionality, which is critically important for visually impaired readers, or just for those who enjoy audio books or Read Aloud features. You can also highlight and add notes in most ebooks, although these features are not active in fixed layouts for iBooks, which is a shame, since many non-fiction manuals, cookbooks, and travel guides with complex layouts using fixed layout would benefit from this.

At any rate, if you're interested in adding text layers to your iBooks file, then read on. I suppose if you've already read this far, then you probably are, so let's get to it.


While you can rely on any of the fifty or so fonts and variations already included on the iPad, you will likely want to use others at times to create a certain look or feel. To do so you must include the font in your ebook package.

Bear in mind, however, that many commercial fonts don't allow embedding, so be sure to look at the font's properties to see if embedding rights have been restricted. You'll want to do this before you spend a lot of time creating your ebook file, only to discover that you have to replace your chosen font with something else that's only moderately close.

First, create a folder in your OEBPS directory named "fonts" and put your chosen font file there. This isn't necessary, and you can put your files anywhere you like, but it's always good practice to keep things neat and orderly so that you can find what you're after when you need to. If you only have a single font to embed you can just as easily add it at the root level, but if you're building something fairly complex it's best to organize each set of elements in their own location.

Next, you need to list this new addition in your manifest, so open up your content.opf and add a line that references the font. Here's the sample template entry:

<item id="Storybook" href="fonts/Storybook.ttf" media-type="font/truetype"></item>

The item id can be anything you like, so long as it makes sense to you, as you'll reference it later in the css. Enter your href as a relative location from the content.opf itself, as it is in this example with the folder/file name provided. The media-type defines what kind of font it is, and for the iPad this can be TrueType, OpenType or SVG. The EPUB3 spec officially supports OpenType and WOFF fonts, so it's probably best to go with OpenType, though as mentioned, SVG and TTF are supported by iBooks, which is what we're building here. If using OTF, however, the media-type you'll want to use is the rather unobvious media-type="font/". I mean, why makes things easy, right?

Finally, before we begin formatting our text, we need to specify that we're using embedded fonts in the metadata section of the OPF:

<meta property="ibooks:specified-fonts">true</meta>

This is the new replacement for the entry previously found in the superceded file. Without this entry system fonts will be used to render your text instead of the one you want. For more on the new EPUB3 additions, see the next section of this tutorial.


Before you can format your text you'll need to add some, of course. If you take a look inside the sample template at the html for pages 1, 3, or 4 you'll find some lines of text that have been added using fairly simple and standard HTML div and paragraph tags. You'll also see that in the <head> section an additional css stylesheet for each specific page has been referenced along with the global styles so that the reading system knows where to find the formatting data for the text on that page. Here's what it looks like for page 1:

<link href="css/page1styles.css" type="text/css" rel="stylesheet"/>

The template includes three pages with live text over a background image, each with their own css file, and one page with text included in the image (page 2), just to show the difference, and provide a reference for those who only want to do that. Page 4 has both live text and an image with text in it, which we'll look at shortly. But first things first.

Page 1 contains a simple, centered, block of text, with just one div and and handful of paragraphs. I've broken up each line of the paragraphs here using <br> tags at the end where I want the lines to break, but you don't have to do that. Since the text content is centered all you really need to do is adjust the margin widths to make the block of text as wide or narrow as you want. And the way you do that is in the CSS for this page. But using <br> tags gives you more control over where small words end up, whether at the end of one line or the beginning of another.

Notice that the <div> that contains the text has both an id and a class appended to it, like this:

<div id="copyright" class="copyright">

Looking at the related css you'll see the following:

#copyright {
margin-top: 25%;

.copyright {
text-align: center;
font-family: Serif;
font-size: 24px;

The id value is reference here using the # symbol before the name, while the class just as a dot (or period) in front. Because they're referenced in different ways like this you can use the same name for each, and give them different values. Why do you need two, you might ask logically. In such a simple book as this the answer is, you don't. But technically the difference is that id values can only be referenced once, while class values can be used as often as you like. So you use id's for things like positioning that apply to only one instance, and classes for styles that might be applied to many different things, like text styles. You would probably want to put those classes in the "global" style sheet, but here we're only using it once.

The id here is used to position the text block 1/4th of the way down the page, by setting the top margin to 25%. You could also put your left and right margin widths here to control how wide the centered text block is, but I used the <br> tags instead, so I didn't need to add them. You might instead just add a 15 or 20% margin-left and margin-right value to achieve the same thing. In that case the text edges would be more consistent than mine, but I like the shape and flow that the more controlled breaks allows.

Our class here provides the centering using the text-align property, but you can also right-align and justify test as well. Left-aligned is the default, so for that you don't need to add anything. I've added generic "Serif" font here, which just tells the reading system to use whatever its default serif-style font is, rather than a sans-serif or embedded font. We'll look at embedded fonts in just a minute. I also gave it a size that I liked, which just takes a bit of trial and error to find what looks and fits the best. I used a pixel value, but you can also use ems. But since I haven't established a base size for 1em, it doesn't really help to use em values in this case. Usually you would set your default text size in the global styles and then use a decimal value of that, like 1.5em or .75em or some multiple of the default value.

You can get as complex and creative with your content as you like, and have the time to learn. This isn't a course in HTML or CSS, so I'm only showing you the very basics needed here. There are endless resources on the Web for how to use CSS, but be aware that only a small subset of what can be done is really possible in ebooks so far, which lag behind the Internet in terms of adoption and feature support. Shadows, for example, are supported, but only one on each object, whereas on the Web most browsers now support multiple shadows, which allows you to create very complex text effects like neon and 3D that can be quite astounding. In an ebook, however, you'll usually just want simple, black and white text, except perhaps for some titles or other special elements. We'll look at how to rotate text when we get to Page 4.

If you download the free 10-page iBooks Fixed Layout Sample file from the Formatting Services page on my website, you'll see a great many more examples of how to style and position text and other elements, including drop shadows, text balloons in comics, simple image animations, draggable elements and a canvas you can paint on, embedded audio and video with a background soundtrack, as well as Read Aloud with text that changes color when each word is read. There is also a Table of Contents with internal page links, and several examples of pop-up footnotes work in iBooks.

But back to our current work in progress. Notice that I have included an active hyperlink here, with a reference to the Creative Commons website that details the ShareAlike 3.0 license used. You can tap on the link and it will open up the default browser and take you to that site. Because I broke the line in half, I actually had to add it twice, once to each line, but you wouldn't normally need to do that. This, of course, is something that can only be done if you include live text on its own layer, as done here. But we'll look at how to add a link to an image in a minute.

Recall, too, that in the styles assigned to the img tag in the global-styles.css file we set the full page image to a z-index of -1, so that by default it's underneath the text. That's why we don't have to do anything else here to make the text float over the top. It's already on an upper layer. And because it's live text, you can tap and hold to bring up the menu of options to copy, define, or search on the word or phrase selected. The "Speak" option will also appear if enabled in the Accessibility features under General settings on the device. Additionally, you can double-tap a section of text to zoom the lines to page width (if in landscape orientation you sometimes have to do this twice; also, a quirk in iBooks makes this not work for the last paragraph of a page when in landscape mode, although it works correctly in portrait orientation).

If you try to interact with any text on Page 2 you'll find you can't. That's because it's just an image with the text included, and there's nothing whatsoever that can be done with it, except to read the page and move on.

Page 3, however, which looks almost identical in terms of style and layout, is all live text. And it's very simple to do. We've already seen centered text, so the first two paragraphs are nothing new, except that they're in a unique font! This is our "embedded" font, which we talked about above, and which you'll find in the "fonts" folder, and referenced in the manifest. To use it, however, you must "call" the font, which requires just a bit more code.


All your major text formatting should be done with CSS rather than in the HTML file itself (aside from specific instances such as italics or bold and the like). Therefore, if you're using embedded fonts to format your text it's in the CSS that you must reference them. You do this using the @font-face entity. Looking in the page3styles.css file you'll see the following:

@font-face {
font-family: "Storybook";
font-style: normal;
font-weight: normal;
src: url(../fonts/Storybook.ttf);

This tells the reading system where to find this font when we decide to use it for our styling on this page. It doesn't provide any actual styling itself (aside from having a few defaults applied so we don't have to do it every time), it only gives the location and font name for reference. The font-family name can be anything you want, since it's just a reference like an id, as we'll see, but it should be something obvious so you know what it is. Normally, of course, you would just use the font name itself, as done here. But you might call it "Header Style" or something if that makes more sense.

Also, you would probably want to put this in the global css file if you were going to call this font on more than one page, so you don't have to add it to every style sheet for each page where you use it. So long as you reference the global css within the HTML page header it will be called on that page. The src: url(../fonts/Storybook.ttf); line at the bottom of the @font-face rule gives the location of the font file itself, using a location relative to the style sheet itself. So in this case, since the page3styles.css file and the Storybook.ttf font are each in their own folders, you need to use the root file reference (../) to tell the system to start at the top when looking for the font file, which is in the neighboring fonts folder next door.

To style an element with your embedded font, now that you've called it, you only need to add it as a property of that element, such as for our primary paragraph style on Page 3:

p { font-family: "Storybook";
font-size: 48px;
color: black;
position: absolute;
text-indent: 0;
margin: 0px;
padding: 0px;

You simply enter the font-family and the name you gave it, exactly as its given in the @font-face rule above. You don't need to add the font's location again, because the referenced rule already has it. You can then add whatever other styling you want applied to the font for this element. For the paragraph style here we've got a font-size of 48 pixels entered, since I didn't specify one in the rule above, although I could have, and then used an em value here to make it larger or smaller than the default. You can change its base style and weight to override the defaults for just this paragraph (i.e. italics and bold, as done in the .fineprint class seen in the page3styles.css file for the third section of text on that page), and change the color if you like, although I've stuck with basic black here. Any of the general default settings can be overridden at the class level for individual elements, as the elements are applied in sequential order from general to specific, so a paragraph style overrides the div that contains it, for example, and a div trumps a universal style applied to the whole page or document. There are exceptions to this that can get quite complex, but by the time you get that far you'll understand a lot more about what's going on. It would take a lifetime to learn it all, and by then it will have changed anyway.

Incidentally, you never actually have to add the color black, since it's the default, unless you've made your default color something else. I just put it in here for reference, so you know how to add it. You can put nearly any named color you can think of - literally, there are crazy color names like MistyRose and Fuchsia that are recognized (and if they're not you'll see another color when you test it) - or you can use a HEX code to call up a specific color, which means pretty much any color can be used, since the HEX code is just a RGB value that nearly any processor can recognize. For a nice visual list of common (and some fairly uncommon) colors, along with their HEX values, see the w3schools CSS Color Names page.

Our paragraph contains some overall positioning information as well that tells the system we want to place our elements using absolute positioning with no added pixels for margins, etc., and no indents, which is a default for paragraph styles in many ebook readers, so it's always good to zero that out. Even if you want a text indent applied, it usually best to zero it in the CSS Reset and then add your own so that you know exactly what you'll get.

I won't get in depth into CSS specifics here, as that's a subject of its own, but iBooks supports a fairly large range of elements, including line height, spacing between both words and letters, text-transforms for uppercase or superscript, and font-variants such as small caps. is the place to go for all the low-down on how to code text and other elements.


Because we're creating fixed layout ebooks here, the exact number of pixels is...well...fixed. This allows us to position elements precisely where we want them by specifying their location vertically and horizontally in pixels. This can be done from any edge, although the default is to place the upper left corner of an element using its distance from the top and left edges. However, it's often easier to use the nearest edge, for example, if you have a small image or a line of text near the bottom that you want to align with a right margin.

You can also use relative positioning to align blocks of text using right-align, center, or justify with margin settings to control the distance from the edges. But just be aware that when you use relative position, the location is relative to the item above and/or next to it on the same layer. This can get quite confusing, as the behavior is not always what you would expect, since relative positions take into consideration things like overall margins and padding, which again is a good reason to set them to zero.

But we're only using absolute positioning in this example, so we declare that for each of our elements that require it. As mentioned, we use individual id references for each element we want to position, since they each need to be positioned separately. For a simple example such as Page 3 we could really just use relative positioning, since it's just three blocks of text that follow one another, with an image underneath which has already been dealt with. All the text here could be relative to the top left margin. But in order to show you how to place text where you want it - such as in a specific location over a portion of the background image, as in many children's books, or so that it shows up in a text balloon as the examples in the Sample file mentioned above - we'll use absolute positioned blocks of text here, as well as on the next page.

Notice that we don't need to put our paragraphs into separate <div> containers in order to position them when using absolute positioning, since each paragraph acts as its own container. The positioning information itself is given for each and every separate element in its own id, which for the first section here - cleverly named section1 - begins 12% from the top edge of the page. Here I've also done what I talked about before and given it a left and right margin of 15% each, leaving 70% down the middle for the text. You don't need to add a width value, since for all practical purposes we just did. We also add our text-align: center here since it's not in the default. Again, we assign some positioning to our second paragraph using its own #section2 reference (make sure to add the # symbol before an id reference!), this time giving it a top position of 35% and left/right margins of only 8% to make the text a bit wider.

Finally, for #section3 we have the same 8% left/right margins, but a position that is 8% from the bottom of the page rather than the top, since I want to control the height of the bottom margin, and this is the easiest way to do it. No matter how much text I put in this section, the last line will always be 8% from the bottom of the page: the text will flow up rather than down! We also have a class appended to the last paragraph that overrides the Storybook font with the standard system Serif font at a size of 36 pixels that closely matches our Page 2 image text. It also has the bold italic styles applied as well.


Page 4 contains a few examples of some more complex positioning that might be useful in fixed layouts comics and children's books. Most of the content on this page, as well as the castle logo at the bottom, is actually included in the background image. Only the sections of rotated text and the live email link at the bottom are on separate layers.

However, if you tap the castle in the image you will see that even though it's part of the background, it actually "contains" an active link. This is done by creating an empty <div> container above it and giving that an active link. Since there's nothing actually in this div, it takes a bit of tricky coding to make it work, but here is how it's done:

<div id="imagelink" class="emptylink">
    <a href=""></a>

First, of course, we need to put something on the page in which to add the link. So we add a div (you could do this with a <p> tag just as well, it doesn't really matter), give it an id and a class to add our styling to, and insert an empty hyperlink. Notice that there's nothing in the place where you would usually add some text, or even an image if you have one on a separate layer. It's just a link, but there's nothing there to add the link to, or even to give the div container some height or width. So far it does not exist in space, since it occupies no pixels. For that we need to add some css:

#imagelink {
position: absolute;
left: 25%;
width: 50%;
height: 25%;
bottom: 14%;
margin-bottom: 0;
display: block;

In the #imagelink id reference we add our absolute positioning and give the div some positioning information. A width of 50% and a left margin of 25% centers it on the page, with the other 25% left over as the right margin. A height of 25% gives it just enough to cover the image, with a bottom position set to 14% with zero margin, just to be safe.

How did I come up with those numbers you ask? If you're really good with math you could work it out by calculating all the heights and widths of both the page size and the portion of the image that you want to cover with the link. But I find that tedious, and hate math. So what I do is guess. You can get it pretty close just by estimating how much of the width and height the div you want to make takes up. The castle is about half as wide as the page, so that's easy enough. The height was just a rough guess and it was close enough. Since you can't see the link anyway, it only has to cover up the part that anyone is bound to tap on.

But there's a better way to be sure. What I do while working all this out is add an additional temporary property to my link container:

opacity: 0.5;
background-color: blue;

What this does is add a semi-transparent color fill to the container so you can see exactly where it is. Use whatever color and however much transparency you like, so long as you can see both the div and what's underneath. When creating comic panels I use a different color fill for each panel, so I can make sure they're all lined up with their borders. You can even create very complex SVG paths for panels with unusual shapes and curves, although I won't go into how to do that here. There's an example SVG path in the Sample File mentioned above, on the page where you can draw on the artist's easel, the area for which is defined by an SVG path. You cannot draw outside those bounds.

At any rate, once you have your div positioned just deleted the color fill and you're all set.

But wait, it doesn't work, you say! That's because even though the div now has some height and width, the link itself does not. For that you need to add some class:

.emptylink a {
display: block;
width : 100%;
height: 100%;

This applies the .emptylink class values to the a anchored link inside it, and tells the render engine to make the link fill up whatever container it's in 100% in both height and width. The display:block property on both the class and id tags makes them display in a square or rectangle like a text box does, so that they act as if there's something in there, when there really isn't. It's now just an empty both with an active link layered on top of our background image. If you tap on it you will open up the default browser. You can use this for internal links as well, incidentally, or to activate non-linear pages containing hidden content, such as test answers, for example.

Looking at the HTML for Page 4 you'll see there is actually a second div and an empty link positioned just below the first one, containing the same link. This is because I wanted the words below the image to be active as well, but didn't want the image part to be that wide, where it would cover up the rotated text to either side, which is active text, and which we'll look at in a minute.

One other link is also added, just below the other, but this one is an email link while opens up the device's default email server so the reader can contact whoever's address is given (in this case, mine). It also contains an automatically added subject for the email so that the recipient knows where it comes from and what it refers to. Since there is some actual content in the container, which in this case is a paragraph, you don't need to use the empty link trick; it's just a standard active text link on its own layer, which you can style and position wherever you want to in the standard manner. You could also remove the default underline using text-decoration="none" and changing the color of the active link to black so that it looks like normal text, but still has a link, just in case you don't like the aesthetic of the usual blue hyperlink. But I left that as a visual cue here that the link was live.

Finally, there are two additional live text layers on this page, one on either side of the castle logo, and each rotated using CSS. If you look in the style sheet for this page you'll see a new property has been added to the usual business:

-webkit-transform: rotate(-30deg);

With this bit of code you can rotate any element in any amount you want, using positive or negative values. You can also animate these values to make a rotating image - and even make them rotate when tapped! But again, we won't get into CSS animations here, as that is well beyond the scope of this tutorial.

Positioning individual layered elements such as this can be a very tedious and time-consuming process, filled with much frustration and endless trial and error, but it helps to think in terms of the total page size. A page 1024 pixels wide, for example would have a center point at 512, and ten divisions of roughly a hundred pixels each. Some simple math proves very useful in determining such things as line spacing and margins, even for the mathematically challenged. One efficient trick is to pull a final page layout into Photoshop, resize it to the your chosen iBooks dimensions, and set the rulers to show pixels. You can then simply place your crosshairs over the point you want to position, note the location in pixels on the horizontal and vertical rulers, and enter those into your CSS file for that element. It's often just as easy to adjust it bit by bit until it's where you want it, particularly if you're using rotated text like these examples.

However, since you may wish to create multiple layers, either of art or text (or both) for one reason or another, where the layers must be precisely aligned, using some math is often very helpful. This is particularly useful for overlapping individual image elements, like comic panels and dialogue balloons, but you can also create complex text layers this way as well, such as those that simulate text wrapped around an image, or use multiple text shadows to produce multi-color glow effects on live text.

Unfortunately, unlike html for websites, both iBooks and Kindle allow only one text shadow element to be applied to each text layer. But you can get around this and create complex shadows and glow effects by stacking duplicate text layers and blurring or changing the color of each one. For example, 0px 0px 30px #ffffff would create a white glow completely surrounding your text. Then a second copied layer of the same text above that with a text-shadow having the values 0px 0px 10px #ff0000 (pure red) would add a bright pink glow surround the text, slowing fading out to white. Use your imagination.

Bear in mind, however, that when you enter duplicate layers of the same text, any users of the text-to-speech features will be treated to a repetition of the content when it's read aloud, so it's probably best to use an image with the empty link trick we just discussed. Of course, then the text-to-speech won't read anything, unless you add a hidden text box, but there again we're just complicating matters needlessly. Incidentally, this does not apply to the Read Aloud feature in iBooks, in which you assign an audio narration track to a given set of text, but rather to the automatic computer-read feature, which in iOS is available via the Speech section of the Accessibility features in the General settings of the device.

This all just goes to show that even though ebooks are still in their infancy, relatively primitive by comparison to the robust HTML5 and CSS3 now implemented on the Web, there still is much that you can do if you just use a little creative coding. For now just focus on getting a basic ebook built, and make that work. Then you can start to mess around with the code and see what you can do.

Join Me
On Google+

View My Vids
On YouTube

envelopeSubscribe To
My Newsletter