Thursday, September 13, 2012

The Viewport in Safari and Fixed Layout EPUB in iBooks

I owe you all a really good EPUB related post! I've been working on some interesting concepts in Fixed Layout books (as well as about twelve other projects) and I wanted to share some of what I've learned. That Fixed Layout Miniguide is getting really long in the tooth, and I hope this helps to update it. I will be publishing a new Fixed Layout miniguide in the near future, based on the articles you're about to read on this blog, starting with this one. If you want to support this project, I invite you to subscribe to my site.

First, let's talk about viewport, perhaps the most widely misunderstood concept in webpage and ebook design. I'm not even sure I've got it totally clear. Which is why I take lots of screenshots.

What is a viewport? Very loosely, it's the area that you have to work with, the area where a web page or ebook will be displayed, on a mobile device (not a desktop computer whose windows are always variable). The trick is how to figure out how it relates to a given device size. And what happens if you can (or can't) change that device size, like when you make a window bigger and smaller. Let's look.

To begin, I created a very simple page with a bit of text, an image whose width I set to 500px and a 1px border around the body:

<meta http-equiv="content-type" content="application/xhtml+xml; charset=utf-8" />
<meta name="viewport" content="width=1000" />
<title>Test Viewport</title>
<style type="text/css">
body {margin:0;padding:0;border: 1px solid black; background:yellow}
p {margin:0;padding:0}
<p>Viewport measures 1000</p>
<p>And this image has width of 500px (actually 1100px wide)</p>
<p><img src="1100x1731.jpg" alt="1100x1731" width="500" /></p>

You can download it here.

And then I displayed it in Safari for iOS on my iPad 3:

viewport=1000, image=500

The important bits to notice are that the image whose width is set to 500px takes up half of the 1000px viewport in Safari iOS. (OK, almost half, since I've got a border on the background that takes up 1 px on the right and 1px on the left.)

Now what happens if we change the viewport size to 750px or 500px?

Viewport=750, image width=500

With the viewport equal to 750px, the 500px image takes up about 2/3 of the page. It's as if you said "now the area the browser has to work with is just 750px".

viewport=500, image=500

If we set the viewport to 500px, something strange happens: the image is actually bigger than the so-called viewport (because of the 1px border).

Now look at what happens if we change the viewport to 250px:

Viewport=250, Width image = 500

The image still fills the screen, it's the exact same size it was when the viewport measured 500px, but now we see that the body with the border around it measures about half of that screen (250px).

There's also one more very important thing to notice. The size of the text was different in each instance:

Overview viewports in iPad

(Note that it seems there's a minimum viewport size of 200px. Also, the text appears the same whether the viewport measures 500px or 250px. Not sure exactly what's going on there.)

What about the viewport in iBooks?

The idea is similar, but iBooks has its own quirks. Surprise!

You can download the 500px version of the Viewport test ebook here.

In iBooks, you not only have to specify the width of the viewport, but also the height. In these examples, I will change them proportionately so that we're not looking at too many changes at once.

First, here's an ebook, containing roughly the same page as above, with a viewport that measures 1000 pixels wide by 1574 pixels high. The width of the image is still set to 500px. (I've moved the text around in these examples so it's easier to read, but I didn't change its size from one book to the next.)

iBooks viewport=1000x1574, image=500px

Notice how the image takes up half of the page size (500 is 1/2 of 1000).

Let's try with a viewport size of 750px wide:

ibooks viewport=750x1180, image=500

There are three important things to notice here. First, the same 500px wide image now takes up 2/3 of the page. Second, the text is a bit bigger (since 4em depends on the viewport size), and third, and perhaps most surprising: the book itself didn't change size at all. There is exactly the same amount of letter boxing to the right and left and none above or below.

Let's look at a 500px viewport:

iBooks, Viewport=500x787, image=500px

In contrast with the 500px viewport on Safari, now our 500px image exactly fills the 500px viewport. (I moved the text and changed its color (but not its size) so you could read it.) Again, the book itself has not changed size.

Finally, here's a 250px viewport:

iBooks Viewport=250x394, width=500px

Again, this is different than what happened in Safari iOS. In iBooks, with a 250px viewport, you'll only see half of a 500px image. It makes more sense, frankly.

There are a couple of things I want you to take away from all this.

1. In iBooks, the pixel dimensions of the viewport determine a book's proportions, not its absolute size. A book whose viewport measures 1000 x 1574px will look exactly the same at full size as a book whose viewport measures 250 x 394px. If the proportion of the viewport does not match the proportion of the screen itself, iBooks will letterbox the book.

2. The size of the objects on a page is determined with respect to the specified viewport. If the viewport is 1000 px wide and the image's width is 500px, the image will take up half of the page. If you have text that is 1em high, the em is determined in proportion to the viewport size. If you are positioning elements on the page, do it with the viewport dimensions in mind.

3. In Safari, an image that is larger than a viewport will still be displayed in its entirety. The viewport will still have the specified size, but there will be an intermediate, sort of extra viewport to hold the image at full size. It's almost philosophical. In iBooks, an image that is larger than a viewport will be cut off. (In earlier versions of iBooks, if you had more info than fit in your viewport you'd get that weird pile of boxes in the middle of the screen. That thankfully is no longer the case.)

4. Monarch butterflies are beautiful. When they hatch, their shriveled wings only take up about half of their regular size. It takes just a few minutes to pump them up and dry out, before they fly away.

Tomorrow, I'll talk about Viewports and Zoom. Unless Catalonia declares independence, in which case it might have to wait until Monday. Stay tuned.


  1. I will be among the first to line up to get your new fixed layout miniguide. I've just about given up on doing fixed format....iBooks is well documented, so they're "easy." Kindle is so-so (and varies by device, KF8 may work on Kindle Fire, but Kindle for iPad won't open it), but Nook is a complete mystery. Have you seen any specs that explain how to build a Nook FF? Or even better, are we getting any closer to being able to build 1 file that will work on all (most) devices, like the Radium example you gave several months ago? That would be like heaven in comparison to building a different file for each different platform. Thanks, Liz, keep up the good work - you are amazing!

  2. yeah we are agree with you while you are deserve for it.

  3. Hi Liz, do you know if fixed layout is support on Android devices? Got it fine working on iBooks, but struggling to get it for Android especially since there are so many screen sizes...

  4. Hi Liz,

    I believe you are working with the wrong units here.

    You are taking device pixels on the new iPad as a reference for your minimum unit, ending up with a huge viewport and causing everything to render tinier than iBooks' defaults, so then needing to compensate everything that is not an image (font sizes, margins, etc.) using bogus huge CSS sizes. You already somehow revealed this effect yourself in this post, so I do not quite understand then why you choose those huge viewport sizes.

    I wonder if you may be missing the difference between device pixels and CSS pixels. With the availability of retina displays, browsers started differentiating between CSS pixels (or points, as only Apple likes to call them when creating apps) and the actual physical pixels on the device. If they had not, everything sized in pixels would become tiny on retina displays as their physical pixels are smaller. Instead, retina displays, be on an iOS device or the new MacBook Pro, have the CSS media property `device-pixel-ratio` (the prefixed syntax and expected value of which are sort of a chaos as of today) set to 2 (high PPI Android displays may have other values). Thus, instead of everything becoming physically smaller (due to smaller physical pixels), vector shapes (such as text) become crispier (i.e. rendered using twice the amount of pixels in each dimension) resulting in the same physical dimensions as when rendered on a non-retina display of the same physical size.

    So, no matter how crispier the new iPad looks when compared to the iPad 2, both display the same number of CSS pixels. The sensible thing to aim for, then, is defining a viewport (which is what determines the size of the CSS pixels, as a fraction of the display's length), so that 1 CSS pixel matches 1:1 a device pixel on a non-retina resolution of the target display that you are aiming to, no matter if the actual device is retina or not. In the case of the iPad (whatever version, then), that is 1024×768 minus the chrome, not twice that. Else, how sizes in your CSS render will not be predictable at all, and it will be rather difficult to know what resolution your images need to be so that you are not falling short and making them look blocky/blurry or using larger images than necessary.

    Having said that, images are not vector shapes whose resolution can be increased dynamically, so viewports sized this way will cause images to have their pixels doubled when displayed on a retina display (so that they maintain their physical size when compared to how big they get rendered on a non-retina counterpart). What you do is offer the image at twice the resolution that you will set its CSS dimensions to, effectively ending up with 1px in the image matching 1:1 a physical pixel on retina displays, and 2×2px in the image matching exactly 1px on a non-retina display.

    I am ignoring the fact that you may prefer using images with less resolution if this makes them humongously large, or a bit more if you want to provide zoomability.

    For more info just google about creating web content for high PPI displays, as just like other aspects of creating ebooks, this is little different from it.

    1. Thanks, but what I'm trying to explain is exactly the difference between device pixels and CSS pixels. I guess I just didn't call them that.

    2. Also, I would disagree that it's very similar to designing for the web, as I show in this article, iBooks doesn't work quite the same way.

    3. Liz, does this mean what you discussed above will be applicable to both the old and the new iPad? I made a lot of fixed layout before but now i'm researching about the effect of the retina display to our line of work...

  5. I specified as the URL tied to my identity in the previous comment, while it should have actually been

  6. hi liz,
    I have some problems with epub3 fixed layout on ibook .. I don't know why ibook doesn't allow to make text notes like flow layout version ?!!

  7. Hi Liz,

    Is it possible that an ePUB that display correctly on iBook is rendered at a smaller size on the new Kobo Arc. Like if Kobo app that read them is enable to use the small viewport and scale the view to fit the device dimensions?


More of my books