Closed robinwhittleton closed 4 years ago
Can you clarify what exactly is fixed in iBooks by removing this compatibility CSS?
How exactly does moving it break Readium?
The same problem in reverse. At the moment iBooks (latest version at least) has no page breaks after the element it’s applied to, but Readium does. Removing it means that iBooks gains page breaks, but Readium loses them.
This came up during the Wilfred Owen production - that has article { page-break-after: always; }
.
Hmmm... if you look in tools/compatibility.css
we specifically target iBooks a few times with the :root[__ibooks_internal_theme]
selector. So it's possible to target specific CSS for iBooks only. But can we target Readium only? I'm not sure. @danielweck any idea if that's possible?
Maybe we can do something fancy where if we detect page-break-*
, we get that selector and duplicate it into an iBooks-specific target?
For example if we find:
article{
page-break-after: avoid;
}
Then we generate:
article{
page-break-after: avoid;
-webkit-column-break-after: avoid; /* for Readium */
}
:root[__ibooks_internal_theme] article{
page-break-after: avoid; /* Override Readium fix to work on iBooks again */
}
In theory, that applies the -webkit-column-break-after
property for Readium, and then once again overrides it back to page-break-after
only for iBooks. Nasty but possibly workable.
Can you drop that CSS into an ebook and see if that does the trick?
@acabal I don't think it is possible to "sniff" Readium by matching a CSS selector on :root
/ html
or even body
, like with iBook's :root[__ibooks_internal_theme]
.
By the way, there are several versions and flavors of Readium, which one are you referring to? The latest web/cloud reader? https://readium.firebaseapp.com
Thanks for clarifying Daniel!
I assume Robin's referring to the web reader.
(Side note, allowing a special selector or media query to target Readium specifically might be a good feature to consider. Being able to target specific readers with CSS is very helpful for ebook producers. Could be as simple as adding a "readium" class to the root element, or something like that.)
Sorry, should have explained more. I hadn’t heard of Readium until I saw that source comment, and just installed it from the Chrome app store to test. I’m using Readium for Chrome 2.30.0.
@JayPanoz I thought this discussion would be "right up your street" :)
(not only the "page-break" stuff, but also the comment made by @acabal about making Readium detectable by content creators via CSS selectors, e.g. <html class="readium">
... perhaps something for Readium2?)
Yeah iBooks supports page-break-*
through the setPagination
API they designed at the time they created iBooks. There’s a paginationMode prop available for the now deprecated UIWebView and app developers can choose whether the -webkit-column-break-*
or page-break-*
CSS properties should be used through paginationBreakingMode.
This may be a private API on MacOS because you can’t find an equivalent in the Apple dev doc and we know it already is private for WKWebView, which replaces the UIWebView.
That being said, they’re still using hacks to respect page-breaks
, by appending invisible hr
s whenever needed in the DOM, especially on reflow e.g. font-size change, window resize, etc.; for instance, to trick a figure into page-break-inside: avoid
they will prepend an hr
element with page-break-before: always
.
Webkit per se only uses page-break-*
properties for print
media, and we must wait for CSS3 break-*
properties so that values can be applied to both print
and columns – note the mapping for aliasing page-break-*
where always
is mapped to page
so… we’re toast because we would need column
.
Support is currently a huge mess.
That being said, it’s a bug I reported to iBooks more than 2 years ago through their bugreport service and that should have been fixed. As far as I can tell, it should work if the page-break-*
prop comes last, and maybe -webkit-column-break-*
overrides the value which, given their API, would then be ignored at the paginationBreakingMode
level.
making Readium detectable by content creators via CSS selectors
That’s something we quickly put aside at the ReadiumCSS level because we can’t guarantee every app using the project would behave the same e.g. have the same colors for reading modes, have the same exact user settings, “page” config, etc. And as we’ve seen with the navigator.epubReadingSystem.name
, few apps bother customizing such hooks and you end up targeting a lot of apps in which things can differ greatly.
So if you add native APIs on top of that, it wouldn’t solve the issue. Let’s imagine we append a hook in the DOM so that authors can deal with page-break-*
.
We’ll have something like:
<html class="r2-reader">
And then, in the author’s stylesheet:
element {
page-break-inside: avoid;
}
.r2-reader element {
-webkit-column-break-inside: avoid;
}
What if the app is using the setPagination
API, which may well become public for the WKWebView we use, as Apple is now deprecating the UIWebView?
The .r2-reader element
declaration will override page-break-inside: avoid
, having the opposite effect of the expected outcome; it will in practice reset the previous one to auto
.
Mind you, I’m not implying this couldn’t help for other use cases, but it will sure backfire for some common cases as we can’t really control how people will implement on top of the R2 SDK.
R2 Desktop is different though, as this is a public-facing app, and not a test app like on iOS and Android.
Now, at the macro level, I won’t even dare imagine targeting specific apps; I must already do that occasionally for a significant codebase in JavaScript, and it’s a nightmare to maintain (“if app X and Z do that, if app Y do something else, etc.”)
Some frameworks are already doing that for device-specific styles e.g. ASCIIDoctor EPUB3 and as you can see, they implemented a really small subset of Reading Apps – I know a lot more implemented the navigator.epubReadingSystem
object, a handful are using a custom navigator.userAgent
to identify themselves and you can occasionally find app-specific objects in the global scope (window
).
Albeit hack-ish, this may work as a pure CSS solution though:
element {
page-break-inside: avoid;
break-inside: avoid;
}
@supports not ((page-break-inside: avoid) and (break-inside: avoid)) {
element {
-webkit-column-break-inside: avoid;
}
}
As far as I can remember, it worked at the time I reported the issue to iBooks for some reason.
Thanks for the comments @JayPanoz, that’s really helpful in explaining the complicated background behind this. Your suggested @supports
workaround looks hopeful, or at least the start of a potential solution for SE, so I’ll have a play around with that when I get a spare hour.
Thought I’d test Readium out again to see if there had been any progress, only to be met with a “Chrome is removing app support, please try another reader” message, something backed up by this press release. There seems to be a Readium Desktop application but I’m not sure of the current state or technology basis.
So do we want to continue adding compatibility fixes for a discontinued project?
IIRC Readium is the back-end rendering project, and the Chrome app was kind of a shell or proof of concept for the back-end. The idea is that the Readium back-end could be used by anyone putting together an ereader. So, we should still try to support it if possible, even if the Chrome app is deprecated.
I’ve been working on a patch to implement @JayPanoz’s suggestion in https://github.com/standardebooks/tools/issues/101#issuecomment-396538742, by changing the existing solution from a regex to a tinycss2 serilaisation that lets me insert a supports block after every qualified rule that needs it. I’ve been testing in Vivlio’s macOS application which seems to use Readium in some way, but it doesn’t seem to be working (and anyway seems to be an Electron app so I’d guess its CSS support mirrors Chromium’s?).
Can anyone suggest a macOS (or potentially Linux) app that uses Readium that I can use to test this patch compatibility with?
Any progress here Robin?
I’ve got an experimental branch (now rebased) that might fix this, but as I couldn’t work out how to test Readium I couldn’t proceed.
What about this https://github.com/readium/readium-desktop
Sorry, I see you suggested that earlier. But did it not work out?
Right, got back to where I was. The root problem is that I can’t find a CSS combination that satisfies both Readium and Books. Readium is ultra-picky with getting just the right setup, and unfortunately doesn’t seem to reflow with break rule changes in developer tools (which more than once has lead to me to believe that I’d found the magical combination).
The branch I pushed above doesn’t have a working combo, although the AST approach should be easier to manipulate if a working combination is found.
OK. Let's close this for now due to inactivity. If you find time to explore this further then we can reopen then.
https://github.com/standardebooks/tools/blob/4c2ff3163bff98ebf16ba241915eafb360c07fd9/build#L718
build adds a
-webkit-column-break-after: avoid
after the specifiedpage-break-after: avoid
. Removing this for iBooks fixes the lack of breaking (indicating that it’s overriding the page-break functionality, but not actually applying as it’s a page, not a column. Moving the-webkit-column-break-after
declaration to before thepage-break-after
declaration fixes the issue, but breaks Readium. It looks like Readium hasn’t got support forpage-break-*
yet: https://github.com/readium/readium-shared-js/issues/127I’m not sure what the fix is here. Potentially we could use a iBooks filter like we do for theming to add in a specific fix, but it feels like this is more a Readium problem?