Skip to content

Instantly share code, notes, and snippets.

@JayPanoz
Last active January 30, 2021 16:05
Show Gist options
  • Save JayPanoz/db894a8983779e3b152816e6a53ab962 to your computer and use it in GitHub Desktop.
Save JayPanoz/db894a8983779e3b152816e6a53ab962 to your computer and use it in GitHub Desktop.
Here’s a list of fundamentals which are broken in eBooks’ Reading Systems

Broken in eBooks

I hate being ”that guy” but someone must do the dirty work and list all the basic stuff which eBooks’ Reading Systems break in reflow.

So, here’s the stuff you can’t rely upon… Brace yourself, nightmares are coming!

Important advice: make sure your demos/test-case files span several “pages” and don’t rely neither on the results you get on “document ready” nor on the results which are displayed in the first column, usually at the top of your xhtml file. I’ve checked a certain amount of demos for which those issues didn’t show up because of that. Problem is if you publish a tutorial/article and people don’t double-check by themselves, it may lead to catastrophes.

For your information…

⭕ = has been reported to dev team

❌ = has not been reported to dev team yet

details

Once at risk of being dropped, <details> has been saved by web browser developers (webkit and Blink support it, Firefox is currently implementing it).

Problem is nobody has taken details into account when designing pagination algorithms… which means when you open it, pagination won’t update and the last children in the XHTML file will overflow (and disappear).

Fixing this issue will open the door to tabs, accordions, pop-ins, etc. in JavaScript as the main problem here is just about updating pagination when contents (display: none) are added—something that already works in scroll config.

Notes

  • adding insult to injury, iBooks iOS doesn’t even preventDefault() when clicking details so it will both turn the page and display its UI. ⭕

Picture element

Although picture is an experimental technology, it is well-supported by web browsers and could help us deal with responsive images (and backwards compatibility since legacy RMSDK has quite a few restrictions when it comes to images).

But… iBooks for instance won’t “update” the corresponding image (source / srcet), displaying whitespace in place of the image. ❌

Viewport

You can’t rely on the fundamental concept of viewport because eBooks’ Reading Systems have broken that pretty badly (hooray for pagination-using-CSS3-columns-or-iframes).

To sum things up:

  • the viewport’s width in iBooks OS X is the document’s width (e.g. 23 000 pixels), it is updated milliseconds after document is ready†; ⭕
  • the viewport’s width in iBooks iOS is different for a single page and a spread. The single page can be a very short xhtml file, an xhtml file which starts on the right or ends on the left; ⭕
  • Readium.js (at least ADE 4.5 + Chrome extension) has a default viewport of 300 × 150, it is updated milliseconds after document is ready†; ❌
  • the viewport’s height in Readium.extension—scroll is the default viewport (figure in its own xhtml file) or the document’s height (else). ❌

† So you must set a timeout or track changes, which might impact perf heavily.

This obviously triggers many issues…

Viewport width (vw unit)

Of course since the viewport width is the document’s in iBooks on OS X you can’t rely upon it. ❌

Let’s say you do the following:

h1 {
  font-size: 6vw;
}

Then 1vw is document width * 0.01 e.g. 2031 * 0.01 = 20.31px. In other words, your h1 will be 121.86px. Moreover, it triggers a huge bug in iBooks OS X: the contents of the xhtml file will overflow and simply disappear. Sometimes half the contents overflow in a relatively short chapter if your h1 is 6vw.

And oh yeah, it means we can’t use more advanced stuff like viewport unit based typography.

Icing on the cake! Units vmin and vmax are obviously unreliable too. While the result for vmax is expected (viewport width = document’s), it looks like 1vmin actually reflows with font-size.

[update] Worse… vw is not computed in a consistent manner in every app supporting fixed-layout, where the viewport is explicit. You’ll get different results if using it to style elements.

Viewport height (vh unit)

This unit is broken in Readium.extension-scroll because the viewport is messed up. ❌

So if you’ve got

img {
  height: 80vh;
}

It will be 80vh of the document’s height (e.g. 20 000 pixels).

Another (smaller) issue is when you’ve got a fixed panel at the bottom of the screen like “Google Play Books Cloud Reader”: height > [number]vh will trigger an overflow: scroll on the page the element is displayed because the panel hides a significant part of the viewport.

Icing on the cake! Units vh and vw are unreliable in iBooks OS X when used with font-size. While the result for vw is expected (viewport width = document’s), it looks like 1vh actually reflows with font-size. The difference is not as huge as vmin but there’s still a visible difference.

[update] Worse… vh is not computed in a consistent manner in every app supporting fixed-layout, where the viewport is explicit. You’ll get different results if using it to style elements.

Viewport units (vw, vh, vmin, vmax) + font-size

iBooks scales viewport units when you’re using it with font-size, even if you’re using calc(). ⭕

Root em (rem value)

To sum up:

  1. Google Play Books can’t cope with that and the user won’t be able to increase font-size; ⭕ (via epub-revision)
  2. a lot of Reading Systems override the font-size value of html so you’d better design this for 100% and not 62.5% as a lot of people do on the web;
  3. legacy RMSDK treats rem as em. ⭕

CSS positioning

Since viewports are broken in some configurations, position: absolute and position: fixed can’t fundamentally work.

Say you want an overlay and a modal. If you’ve got:

.overlay {
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  height: 100vh;
}

The overlay will cover the entire document in iBooks OS X since the viewport width (100%) is the document’s width.

As for position: absolute, if you doesn’t have position: relative on the parent element, left: 0 will be the first column in your xhtml file.

Worse still, offset, position, etc. you can get using JavaScript are also confusing because viewport and CSS 3 columns (the columns issue also applies to the web so it’s a broader problem). In other words, you must test the RS and execute JS code accordingly, which makes up for crappy perf and maintenance.

Media queries

A viewport issue again, on which you might add CSS 3 columns when they are being used to achieve a “fake spread.”

If you’ve got

@media screen and (max-width: 35em) { }

iBooks OS X won’t apply those styles because it considers the viewport is the document’s width. ⭕

If you want to make a simple JS-polyfill to check the real container’s width when columns are being used and apply styles based on the dimension you get, good luck.

Styles might update (depends on the RS) but… pagination won’t—so you must find a way to force that. Why? Because you must set a freaking timeout to get the real value in some RS. So it’s a dead-end until it is fixed. Please someone call for a moratorium so that we can pause addition of new specs (after EPUB 3.1) and fix all the issues we’ve currently got in reflow (because pagination).

navigator.epubReadingSystem

I wished it was a joke but it isn’t. Even that doesn’t work reliably. Once again, you must set a freaking timeout to get it everywhere, which limits its usefulness (see Media Query polyfill issues).

Worse still, version and layout are not reliable because RS devs don’t give a duck about it. For instance, you’ll get paginated for scroll mode in a shitload of RS. No wonder the pieces of javascript you may explore in the wild are using a bazillion conditionals to check the app and its configuration… (oh look, crappy performance -> shit UX).

preventDefault()

You’d think this fairly basic JavaScript method is not fucked up but it actually is big time.

Even if using it in combination with stopPropagation(), an awful lot of apps, especially on mobile, will fire their UI every time you interact with a button or shit. Needless to say the result is a crappy UX… UI displayed, UI hidden, UI displayed, UI hidden, UI displayed and so on and so forth.

Debugging

Yes, debugging is broken too. This is how bad the current situation is.

Sure you can enable the web inspector in iBooks using a command prompt (see iBooks Asset Guide) but you don’t get the related dev entry in the menu bar—that would be too much for peasants like us—and if your xhtml file consists of an image, you can’t access the web inspector so you must add a chunk of text so that right-click works. But yeah, sure, Apple is all about UX and caring about the small details you don’t notice.

And that’s pretty much what we’ve got right now…

For the record, I had to file a feature request for debug tools in Adobe Digital Editions forums because they weren’t planning to provide them at all. And it’s unlikely others will suddenly implement debug tools because “who cares?”

Well, my CSS and JS do care. And as a matter of fact, my clients do care too because… guess why… that’s extra hours I must bill. So please stop believing we are idiots who don’t know what they’re doing because we’re making eBooks. Thanks!


To be continued…

Flipping some tables right now. Why do you all RS devs hate us so much? WHY?
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment