Video hosted by Apple at devstreaming-cdn.apple.com

Configure player

Close

WWDC Index does not host video files

If you have access to video files, you can configure a URL pattern to be used in a video player.

URL pattern

preview

Use any of these variables in your URL pattern, the pattern is stored in your browsers' local storage.

$id
ID of session: wwdc2012-515
$eventId
ID of event: wwdc2012
$eventContentId
ID of session without event part: 515
$eventShortId
Shortened ID of event: wwdc12
$year
Year of session: 2012
$extension
Extension of original filename: mov
$filenameAlmostEvery
Filename from "(Almost) Every..." gist: [2012] [Session 515] HTML, CSS a...

WWDC12 • Session 515

HTML, CSS, and DOM for Book Authors

Graphics, Media, and Games • iOS • 38:35

If you want to bring your creativity, passion, and technical expertise to the iBookstore, it may seem like there's a vast array of web technologies to master. Gain a solid understanding of the HTML, CSS, and DOM technologies that are most relevant to book development, whether you're creating a book with EPUB or building a custom widget for iBooks Author. See how to create beautiful text that is always laid out perfectly, gain a deep understanding of CSS positioning to create exceptional fixed-layout books, find out how to enrich your content with CSS animations, and learn which DOM operations are critical to adding enhancements with ease.

Speakers: Edward O'Connor, Adele Peterson

Unlisted on Apple Developer site

Downloads from Apple

HD Video (171.2 MB)

Transcript

This transcript was generated using Whisper, it has known transcription errors. We are working on an improved version.

Good afternoon, everybody. Is everyone having a great WWDC thus far? That's what I like to hear. If you'd like to make a digital book, you've come to the right place. This is session 515, HTML, CSS, and DOM for Book Authors. I'm Edward O'Connor, a web technology engineer on the Safari and WebKit team here at Apple. So iBooks. iBooks supports three kinds of books. First, flowing books, like novels, which consist primarily of text and images, fixed-layout books.

which allow the book designer precise control over the placement and position of everything on the page. And MultiTouch Books, exceptionally easy to author with iBooks Author. So rich, beautiful books your readers will love. So three formats, one core set of technologies for all three. It's web technology. In MultiTouch Books, you can build rich, interactive widgets with HTML for flowing and fixed-layout books.

EPUB provides the structure of your book, but the contents are HTML, CSS, and JavaScript, the core web technologies. So if you're not a web developer, or if the last time you looked at HTML, the blink tag was the new hotness, you're in the right place. We're going to take a look at the key parts, the core bits of web technology that are essential to building a book. technology for making great digital books.

So let's get started. I thought we could take a look at a document that hopefully you've all heard of. So I took a copy of the US Constitution, exported it to HTML, and dropped it into an EPUB. And this is what it looks like. We've got a little bit of work to do to make this be a really great-looking book.

So in a few minutes, you'll know everything you'll need to make it look like this instead, something far more compelling for your readers. We'll start by looking at the basic structure of your document. So the tool I used basically just gave me automatic line breaks. This is the BR tag in HTML. For iBooks to format your book nicely, we first need to tell it what each part of our content is.

HTML provides a variety of elements. For basic page elements, so you have the P element for your paragraphs, various heading elements for your headings and subheadings, and so on. And there are many great tutorials and references online that you can use to look up the basic structural HTML elements. And as you can see, we've immediately gotten from iBooks much better formatting by default. So as I flip through this book, I'm seeing that each of my paragraphs has this extra space in between, and the first lines aren't indented.

This is the default presentation of text on the web, but it's not what you expect in a book. In a book, you typically have your paragraphs right next to each other, and you indent those first lines. To do this in web technology, we're going to use what's called a style sheet.

CSS stands for Cascading Style Sheets, is the language we use to describe what our content should look like. So first, we'll link to our style sheet from our HTML. So what goes in the style sheet? Well, you need to identify the parts of the content you'd like to alter and then provide iBooks with commands that will describe how you'd like it to look.

In this case, we want to affect the indentation of every paragraph. So we use what's called an element name selector. In this case, I've named the P element. This will match every paragraph in our book. And as you can see, we've got this nice indentation on our first lines.

But one of the key differences between digital books and print is that your reader can change the font size they use to read your book. So if we do that, we'll find our nice-looking indent from before doesn't look so nice now. Well, what happened? We've used a unit of length, the pixel, that's relative to the screen, not to the size of the font. You really want to express things like indentation in terms that are relative to the font size, so that when your user changes the font, it still looks great.

There are several such thought-relative units available in CSS. One of them is the M, or EM. The name comes to us from print typography. It used to refer to the width of the uppercase M. And now it's a little more complicated, but that'll do. So once we've done this, we change the font size, our indentation looks great.

So now that we've taken care of that, we still have these spaces between our paragraphs. To fix this, we need to learn about how elements have space around them in CSS. There are two kinds of space that you need to worry about: margin and padding. And this is because all elements can have a border put around them. Margins are the space around the border, whereas padding is the space inside the border.

By default, paragraphs in HTML get a top-and-bottom margin. So to remove that, we simply set margin zero in our CSS. So this is already looking a lot more like a book and a lot less like a web page. It's common in print for the first paragraph after a heading or subheading to not be indented, that only subsequent paragraphs should be indented. We can achieve this in CSS, by using what's called a sibling selector. So remember, our element name selector picked out every paragraph in the document.

The sibling selector says, "Give me all the elements that follow this other element." So here we've said, "I'd like only the paragraphs that follow another paragraph directly in the document." So now our indentation is only applied where we'd like it. Something else you may have noticed is that iBooks is automatically hyphenating your content. This is really great.

And it's dynamic. When the user changes the font size or orientation, The hyphenation will update automatically, and your text will continue looking great. Automatic hyphenation is wonderful, but sometimes you need to override it. Maybe you're writing a technical manual and you're using a technical word that's not in the default hyphenation dictionary. You can use what's called the soft hyphen character, shy, to manually specify each hyphenation point.

Conversely, you might want to disable hyphenation. This is very common with headings. You can use the epub-css property to disable hyphenation. Another common structural element of flowing books are quotes. Unfortunately, there aren't any quotes in the Constitution, but I'm sure you can imagine in the hot Philadelphia summer, People scribbled various notes in the margin, and via extensive historical research, I found one such note.

So as you can see, the element we use in HTML for quotes is called blockquote. And it gets, by default, a little bit of margin on the left and right to distinguish it from the surrounding text. One thing you might want to do here is restrict the width of a quote or many other elements. This is very easy to do in CSS. You simply use the width property.

Here I've chosen to use a percentage. This allows for the element to take up the same amount of space on the screen on an iPad, an iPhone, or an iPod Touch. Once you've restricted the width of an element like this, you might want to center it on the page. And we can do this with a special kind of margin called an auto margin. So before we had one value that we were giving to a margin. When you give it two values, the first specifies the vertical margin and the second the horizontal.

So here, we've given it auto for our horizontal margin. iBooks knows that the element takes up 75% of the width, so it automatically allocates the remaining 25% on either side. This quote still appears to be part of the main document, but really we want it to be off to the side as a pull quote or margin quote. We do this in CSS by floating an element. The float property does several things.

It removes the element from the main flow and moves it off to either the left or the right. So as you can see, the Article 1 heading is following immediately after the preamble as if there weren't anything in between. Floating an element also causes the rest of the content to flow around it automatically, so you don't have any ugly overlaps.

Now that we have our quote off to the side, we could use a variety of CSS properties to make it visually distinct from the main text. And there are many great tutorials and references online for the various CSS properties at your disposal. One very common thing to do is to use a different font. So let's take a look a little bit at how to work with fonts in your books.

So the first thing to think about here is that your reader can use a different font than you specified. iBooks supplies a font menu with several great options. So if you're looking for a font to specify for your book, you might first look at iBooks List. These are all fonts that are designed for readability on the screen.

But you're not limited to these fonts. iOS comes with many other fonts. One of my favorites is... Charter is very readable, but even better would be Markerfelt. I'm pretty sure this is exactly what the Founding Fathers had in mind. So this brings up a good point. If you want to change a font, you should always have your readers in mind. Readability is the goal here. In this case, marker felt might not be a suitable font for your body text. Maybe it's better just for headings or other runs of large text.

You're not limited to the fonts available on the system. You can include a custom font that you have a license for in your book. You simply include the font file in your EPUB, and then you tell iBooks about this font by using what's called an @fontface rule. This looks a little more complicated than the CSS we've seen already, but it's pretty straightforward. It contains two parts. We use the font family property to name the font, and then the source property to specify the font file.

And then in our CSS, we just refer to it like any other system font. So in this case, I've loaded what's called FelEnglish, which is a revival of an 18th century manual typeface, because I thought it's a historical document, and an appropriate historical typeface might fit with it. But I'm using Charter for my body for better readability.

Custom fonts typically come in multiple files, so your italic will be in a separate file from the bold, et cetera. To load multiple files for the same font, you just use multiple @fontface rules. And you use the font style and font weight properties to specify which is which.

Now remember, your reader can change the font they're using to read your book. If you specify a custom font, how do you make sure that your user can get back to that custom font if they've chosen a different one? In your Apple Display Options file inside your EPUB, you include the specified fonts option, and this enables the original item in the font menu. When I think about custom fonts and the Constitution, I think of this sort of iconic first page with this ginormous "We the People," a very bold statement. So I'd like to bling up our preamble a bit.

Now, before, in our CSS, we've selected whole classes of elements, all of the paragraphs, et cetera. To select just the preamble, I can give it a class in my markup and then refer to that class from CSS using a class selector, which is just the class name with a dot prepended. So I've made it a lot bigger, made it italic. It's starting to look kind of nice. It's very, very common in books to want to style a line, or the first line or the first letter of a paragraph.

But if the user changes the font size, what's included on that first line will change. Fortunately, we have a first line and a first letter pseudo-element in CSS. And this will dynamically update and always match what's in that first line as orientation changes and font size changes. I still want that "We the People" to really kind of pop out, though. There wasn't any element just surrounding "We the People," so I added one. And I'm using a similar class selector like before. Now unlike print, you're not going to get charged extra for using different colored ink. So just don't make it really ugly. Think about it.

So that's looking pretty nice. Flowing books are more than just text. The judicious use of excellent images can really improve the look of your book. Working with images in iBooks is really, really easy. So here's a portrait of the signing of the Constitution. Let's pop that right in there. We use the image element in HTML.

to put an image in our markup. Takes two attributes. Source attribute specifies the image file, and the alt attribute specifies alternative text that will be used instead of the image. Remember, many of your readers cannot see the images you've included in your book. And if an image is worth a thousand words, you can probably spare 20 or 30 to describe each of your images appropriately.

One thing I haven't done here, I haven't told iBooks anything about how to size or place this image. That's because iBooks goes to great lengths to figure out an appropriate size for your image, to make sure it won't break across pages, and that sort of thing. It does this across devices. This looks great on the iPhone, too. And it didn't have to do anything.

You might want to control the width or placement of your image. The best way to do this in iBooks is to put the image in a container and then style that container. So here I've used the same width and auto margins from before to center and give a little space around my image. At this point, we can start to have fun.

I decided to put a little bit of a shadow behind my image. In CSS, there's a box shadow property. Which takes four arguments. The first two are the offset from the image, then a bit of a blur, and finally the color of the shadow. Another thing to keep in mind when working with images and books is that your reader can change the theme they use to read your book in iBooks. I do this all the time. My favorite is the night theme.

Actually, my wife's favorite is the night theme because I can't put the book down. I've been in bed for an hour, and the light's off, and I'm keeping her up. So I turn on the night theme, and hopefully the book still looks great. In this case, though, Something's not right. This image has a white background. And in normal theme, it looked great. In the night theme, not so much.

This is an easy problem to avoid. Simply use an image with a transparent background. This will continue to look great in normal mode and in the night theme as well. So now we've looked at dealing with the basic structure of our documents and how to work with custom fonts and how to include images in them. But digital books are so much more than a static recreation of print onto the screen. So let's go beyond print and look at some of the things that you can only do in a digital book. We'll start by looking at animating content in a fixed-layout book.

A fixed-layout book is almost like a sequence of web pages. Each page is its own HTML document. So for each page, we have to tell iBooks how big the page expects to be. We do this by defining a viewport in our HTML, and then we set our body dimensions to match that in CSS. Be sure to set zero margins on your body so that the dimensions will actually match. So now we have this blank page, a blank canvas. We can tell any story we want. So I thought we could create a story about a sheep.

But not just any sheep. This sheep has an overriding goal in life, to help children sleep by jumping fences. Over and over and over again, as many times as it takes. So we'll need a fence. In fixed-layout books, you'll typically have a background image on each page. To set a background image in CSS, you use the background property. You point to the image, and that's it. Make sure the dimensions of your image match the viewport dimensions that you've set.

Okay, so we've got our field, our fence. Let's put our sheep on there. This is just like before. You use the image element in your markup, and there we have our sheet. There's a bit of a problem, though. It looks like our sheet might be falling from a great height. And I'm a little worried. We need to put them on the ground.

So to position elements like this on the page, we can use absolute positioning. In CSS, you set your position property to absolute, and then you use the top, right, bottom, and left properties to position the element wherever you'd like. So there he is, safe on the ground. Let's give him some friends.

So I have an image of a flock of sheep, positioned exactly like the first sheep. But where did the sheep go? The flock is sitting on top of them. When you use absolute positioning to position elements on the page, they can overlap. So to control the stacking of your elements, you can use the z-index property.

It's very simple. The bigger z-index value wins. So by setting the sheep z-index higher than my flock's z-index, I've put it back on top. This is all you need to know to position and stack every element on your page, but we still haven't made the move. To do this, we'll use what's called keyframe animations. A keyframe animation is a series of steps. Each step is a keyframe. You say, "I'm going to create a keyframe. This far through, this is how things should look. This much farther, this is how things should look. And so on.

So I thought we could start by defining an animation Let's have our sheep just walk across the screen. We'll get to what goes in our keyframes in a bit. To tell our sheep to animate, we use the animation name property, and name -- we give it the same name that we gave our keyframes. We have to tell iBooks how long the animation should go. We do this with the animation duration property. In this case, I've said one second.

And you can control the timing of your animation with the animation timing function. "Well, what does that mean?" This is the scariest slide. So the easiest one is a linear timing function. And this simply says-- You know, at 50% of the way through our animation, we should be 50% through our keyframes. So in a one-second animation, a half a second will be at 50%. Another common timing function is called ease, and this provides a gentle acceleration at the beginning and a deceleration at the end, which will make your animation look really smooth.

There are several other predefined timing functions in CSS, but you might want to describe your own custom timing function. You can also do this. Okay. So we've wired up our animation. We've told it how long it will take. But what goes in those keyframes? Well, if you think about it, When you want to animate things, you typically want to move them around on the canvas. You can make them bigger or smaller, maybe rotate them.

We can do all of these things with one CSS property, the transform property. To use the transform property to move something around, you can use the translate function, which takes an X and a Y offset and scoots your element along that offset. To make something bigger or smaller, you use the scale transform. In this case, a scale of two doubles the size.

And to spin or rotate things, you guessed it, the rotate transform, which takes an angle And does the rest. So to cause our sheep to walk across the screen, we'll use the translate transform. We'll just need two keyframes at the start. We don't want to translate it all. And at the end, we will have fully translated to our destination. And there you have it. To show you how to use keyframe animations and CSS transforms to cause our sheep to actually jump that fence, I'd like to invite up Adele Peterson.

Thanks, Ted. Hi, I'm Adele Peterson. We're going to start with an animation very similar to the one that Ted just showed you guys in the slides, and then I'll show you how to make it fancier and then eventually get the sheep to jump the fence. So you guys see the beginning wiggle there? There he goes. And then he kind of scoots. OK. So let's go back to our machine.

We're going to drop in a few more keyframes. Okay, so now I added a few more. Again, we're continuing to translate along the x-axis, and we're doing that wiggle back and forth. Look at him go. All right, all right. Okay. And finally, we're going to jump the fence.

Okay, so here we now have an extra parameter in our translate function. So by 80%, we're going to translate in the Y direction 200 pixels up. And we've straightened our rotation back out to zero so that the sheep is on firm footing as he makes his jump. Okay. Come on, Brucie, you can do it. And there he goes. All right. Back to you, Ted.

So we've seen how to animate elements on the page. One of the other things we can do in digital books is make use of multimedia like audio and video. I don't have much to tell you about this because there isn't much to say. It's very easy. Just like we use the image element to include an image, we can use the audio or video element to include audio or video.

They both take a source attribute just like the image element. The video element also takes a poster attribute which specifies an image to be used as a placeholder like so until the user has hit play. You specify the controls attribute so that the user has controls to play and pause and scrub your media. And just like that, you've got... Great sound and video in your book.

Sometimes you'd like your book to do something that you can't express in an animation alone. You'd like to change the content on the page dynamically. One way we could do this, or one reason we might want to do this, is to count the number of times Bruce the Sheep has jumped the fence already. This thing can get outrageously large and somewhat depressing. Why isn't Iris asleep yet? Well, how would we achieve this with web technology? JavaScript is the programming language of the web, and we can use it in our books as well.

Everything in your HTML is exposed to JavaScript in what's called the Document Object Model, or DOM. So all of your elements have some kind of corresponding JavaScript object that you can manipulate from a program. You can add or remove elements, modify their contents. So if we want to count each time the sheep jumps the fence, we're going to need to get some kind of message about when this happens. And in the DOM, we have what are called DOM events. And these are just messages that happen as something changes. Keyframe animations cause several different kinds of events to happen.

The animation start event happens when the animation initially kicks off. The animation iteration event happens at the end of every iteration of that animation. And finally, the animation end event happens when the animation stops. Sadly for Bruce, this animation is never going to stop. So what we want to do is we is used the DOM first to get a reference to the image that represents our sheep. The getElementById method does this very straightforwardly.

You just pass it the ID of that element. Next, we'll try to listen for the animation iteration event. And each time we get it, we'll update that count by using some DOM manipulation. So the next iteration, our count goes up. It was kind of ugly that it said zero. The Romans didn't even have a concept of zero.

So maybe that's a bit too much for a children's book. So we could hide the zero and wait until the first iteration happens to then display our count. To hide and show elements in CSS, you use the display property. So in this case, I've put a class on my count. I've used that class to hide the elements.

And then from the DOM, I can remove that class to cause the count to appear. HTML5 provides a very convenient classless API for the manipulation of classes on elements. You can add or remove classes. You can check to see if a class is there or toggle the presence of one. By using classes like this, we can describe different states of our animation and the dynamic behavior of our book with meaningful names which makes it much easier to work with for you as the book author.

So in this case, we can simply call classless.remove and give it our class to cause-- Our count to be shown. So I'm going to invite Adele back up, and she's going to have a little bit of fun with making our sheep do a bit more. Here's Adele. Thanks, Ted. So I'm going to quickly walk you through adding the counter that Ted just showed you, and then we're going to add a super realistic sound effect. OK.

So-- Let's take a look at our JavaScript here. So here we've added an event listener to our window to listen for the DOM content-loaded event. So when the web page, or in this case, the page of the book, first loads, we'll end up calling this init function. We'll do our initialization. So here is where we have our sheep element. So actually, before I go farther, Let's add in our HTML for the counter.

Okay, so pretty simple. We have our paragraph and our counter, and here's that class that Ted mentioned, and that's how we're going to control the appearance of this class. Okay, so back to the JavaScript. All right, so we have this initialization function, and the first thing that we're going to do is to add that event listener for the WebKit animation iteration event.

So this fires at the end of each iteration of our animation. When that happens, we're going to call this updateCount function. So updateCount... is fairly simple as well. We increment our jumped sheep, we grab our counter element, and we set the text content property of the counter to the number of jumped sheep.

Okay, now we're going to go and hide the counter. Let's see, where's my... Okay, so... We're just going to drop in some really basic CSS to set that zero class to display none to hide it. And then in our JavaScript, in update count, when we have reached the first iteration, We're going to use the class list API to remove that class. Okay, so let's switch over and see how that looks.

We're continuing to count, so that's good. Okay, so now let's add our super realistic sound effect. So this may defeat the purpose of trying to get your kid to go to sleep, but it's kind of cool anyway. So you may have to learn how to build a mute button into this later. Okay, so again, let's go back to our XHTML, and we'll add our audio element.

Now, this is a little different from the example that Ted showed you on his slides because it doesn't have a controls attribute. And the reason for that is we don't want the user to control this media. We want to control ourselves in JavaScript. So I'm going to show you how to do that.

So we are going to add a little more code to our initialization function. We're getting the audio element by ID, using getElementByID, and we're calling load on that audio element. This is just so the audio file actually gets loaded and is ready to play when it's time to play. We're going to add our function to actually play the audio.

And here, when we actually play the sound effect, we're going to play it on a slight delay. So this is so if it starts playing at the beginning of an iteration, we can actually play it a little bit later, maybe around the time that the sheep is jumping the fence. And then every time we iterate, I'm sorry, let's see. Every time we iterate, we'll call play sound effect.

Okay, so there's actually a problem with this code. Every time you iterate, you're going to play the sound effect, which happens on a delay. This actually means that the first time the sheep jumps the fence, you're going to miss getting the sound effect. That's because this event, this animation iteration event, happens at the end of each iteration. So we're going to also add an event listener for WebKit animation start and also start playing the sound effect then. Okay, so I think we are set up to make this work. Let's switch over. Bah-ha-ha-ha. Bah-ha-ha-ha. All right, back to you, Ted.

Well, what have we learned today? First off, it's exceptionally easy to make a great-looking, flowable book using just a couple of CSS properties and some very basic markup. Secondly, you have very fine-grained control over layout and the appearance of things in a fixed-layout book using, again, just a little bit of CSS, And it's also very easy to add some fairly complex enhancements, such as animation and multimedia. Remember, This is all just web technology. And there's an amazing amount of material out there. It's all very applicable to making great books.

There have been many related sessions here at WWDC this year, several of which have already occurred. If you missed them, the videos will be posted very soon. Tomorrow morning, there's a session on accessibility in books, which is going to be awesome. I'm really looking forward to it. And then on Friday, there's actually a repeat of the Building Books with iBooks Author session. It should be a great session if you miss it. I think it was Monday. No, sorry, Tuesday. And of course, for more information, you can contact Vicki Murley, our Safari Technologies Evangelist. You can participate in our developer forums at [email protected]. Thank you so much.