Closed JayPanoz closed 6 years ago
While testing user settings yesterday, I was quite concerned with an UX issue related to font size.
Font size will probably be a global setting i.e. when the users set a specific font size, they very likely want it to apply to all publications they’re reading. At least this is what happens with a lot of (existing) Reading Systems.
We have quite a significant amount of samples for which the base font size is really small: 12px
(unsurprisingly, they tend to have the same origin).
12px
happens to be our smallest font size setting. For reference, here is our current values for this setting:
400%
used as a reference in a11y testing…)(Of course, sizes are relative since 100%
may not be 16px
in all browsers.)
What’s worse is that, in that case, we’ve got useless settings (the smallest one), especially as there is a floor for font-size
(which is like 8px
in Safari for instance).
As an aside, this is incredibly painful as a user (and bad practice as an author). I don’t have vision problems but 12px
makes my reading experience super uncomfortable.
Map every publication relative to our settings, which means for instance:
12px
will be level 1;16px
will be level 3;18px
will be level 4.This process would be completely transparent to the user. If level 3 is set, then all books will have a base font size of 16px
. It won’t be 12px
for the first one, 16px
for the second one, and 18px
for the last one.
computedStyle
, in a representative HTML file (say a chapter). font-size
.font-size
mapped to our settings, which implies some ebooks will open with setting at level 3 while others will open at level 1. We’re probably pretty safe here since we can check the computedStyle
and define the level in the shadows (menu is hidden by default).window.getComputedStyle(document.querySelector("p").getPropertyValue("font-size")
might not be the most reliable way to get the base font-size
for the publication. Think of complex publications in which the first paragraph may be a lede, or an unsemantic heading, etc.
window.getComputedStyle(document.body).getPropertyValue("font-size")
may be a little bit better but doesn’t deal with CSS authoring like
p {
font-size: 0.875em;
}
Turns out we can get a pretty good average by checking the base font-size
and a heading, be it h1
, h2
or h3
.
In that case, getting the type scale is a one-two punch:
parseInt
of the two computed font-sizes (result)*Math.pow(result, 1/n)
, in which n
is 3
for h1
and 2
for h2
.* h3
stops here.
Of course this is related to our specific CSS normalize.
I’ve been able to retrieve a good-enough author’s type-scale for 90% of our samples. For other publications, we could still change the type-scale on a per-heading basis.
Useful analysis, thanks! Just to record my thoughts on this:
As a user, I would expect the "200%" option to result in the document's text (including interline spacing) to be proportionally scaled by a factor of 2, relative to the original publication's styles. I would also expect (or learn to tolerate) slight discrepancies in the visual output of different publications, because of text size variations in the original documents (as defined at authoring time by content creators via CSS). On the whole though, my user experience would be pretty consistent and satisfactory. There may be uncommon instances whereby scaled documents would look unreasonably smaller / larger (compared with the rest of my ebook library), in which case I would be forced to adjust the system-wide option (and restore my favourite setting when switching to other, more regular publications). I wouldn't expect reading systems to be particularly "smart" in this area (such as attempting to automatically detect unreasonable size discrepancies), because I would recognise that modern interactive multimedia publications ; just like gazillions of existing web pages ; can offer significant stylistic variations. However ; just like with web browsers ; as a user I might expect the reading system to provide a "enhance readability" mode that would present a minimalist and normalised view of rendered documents. Irrespective of how this special "reader mode" would operate under the hood, the "dumb" text sizing method based on a simple scale factor is in fact (based on previous implementation experience) not as easy to nail-down as it sounds. For instance, using CSS alone was not sufficient, and we had to programmatically walk the structure of loaded documents (HTML DOM) in order to apply the scale factor to individual nodes, based on their computed font-size (expressed in absolute points or pixels).
Thanks for your thoughts, @danielweck, this indeed is a complex issue and I must admit I have mixed feelings about the proposal, especially because of edge cases.
So, as usual, I've taken a look at other RSs—“In case of doubt, check interop.”
First and foremost, authors can opt-in using the ibooks:specified-fonts true
meta in the OPF (or the older com.apple.ibooks.display-options.xml
file in the META-INF folder).
When this metadata is set to true, iBooks will respect:
font-family
font-size
line-height
text-align
hyphens
set in the authors’ CSS.
What’s interesting is their “FontsPresets.plist”.
Basically, the authors’ explicit font-family is the first <dict>
they’re using, and 1em
is the smallest setting available (unlike our current list of values for this setting). They don’t set a line-height
.
When the user sets another font, then they customize per font (font-size
+ line-height
, the later depending on the former).
It’s also noteworthy that the user preferences for text-align
and hyphens
(to be found in iOS global prefs) are then enforced.
In other words, the user picking another font is the signal for some kind of normalization.
According to the guidelines, the following font fixes are applied during the upload process (KFX):
Source: Kindle Publishing Guidelines Version 2017.3, page 26.
In other words, they automatically normalize for Enhanced Typesetting. There is neither an opt-in nor opt-out mechanism. But they can obviously do that during conversion.
EPUB files are processed, this is clearly visible when side loading a file in the app. Their pagination is quite different from iBooks/Kobo/Readium and at some point, you could find EPUB files were actually transformed into fragments (by using Android File Transfer for instance).
Looks Like they’re managing font-size
via JS though. But what’s interesting is that, on processing, they “normalize” keywords, which are one part of our problem (they won’t resize).
If you take a look at this stylesheet, which is the one I can retrieve for one of my files, you can see font-size
are set in pixels. In the original file, they are set using keywords
, for Kindle Mobi.
The author’s CSS is a theme, with an extra checkbox the user can check to normalize font-sizes.
Applying any other theme than the publisher’s automatically normalizes this text scale.
Custom if for more targeted settings (font-family, line-height, etc.).
Looks like the setting is relative to the publication base font-size
in the mobile and desktop apps. Couldn’t check eReaders.
We don’t have the luxury of a specific metadata or the processing/conversion of EPUB files so we basically find ourselves in the Overdrive/Kobo situation.
As far as I’m concerned, I still have mixed feelings about this issue: Overdrive’s approach seems the most sensible at first sight, iBooks mapping level 1 to 1em is probably a good idea as well (the 100% font-size
in the R2-navigator is indeed quite small at the moment), but some other RSs deal with other preferences as well so it’s also a scoping issue (themes, opt-in checkbox, which styles are normalized, etc.).
And we must of course anticipate User Agent Properties (const
), which have just been proposed by Apple for the CSS-Variables spec. Cf. our issue #5.
It is my understanding that in iOS for instance, the UA prop is very likely to retrieve the value set in a11y settings:
[Edit] As a clarification, I guess we’d better at least be in sync with the OS/UA setting e.g. if the user sets a bigger system font-size, it maps to our level automagically so that our settings are not relative to this global setting, especially as those properties will be exposed to authors.
For the record, other styling related to font-size
:
float
elements.When the user font-size
is a lot larger (relative to the screen size), one might wonder if we’d better disable this type of styling.
Kindle Enhanced Typesetting is doing this already, I could manage most cases using CSS so it’s up to implementers. Would those normalizes be useful to you?
We’ve been discussing line-height
lately, since some publications don’t have one set in their CSS. We’ll also probably need an explicit line-height
for when the user changes the font-family
.
If we don’t provide a base line-height
, the normal
value will be applied, and that’s quite an issue. On average, it is less than 1.2
, which makes leading quite solid. The exception being Iowan Old Style for some reason, with a normal
value you would mostly expect (1.375
).
As a consequence I moved line-height
to ReadiumCSS-base.css
so that we can fix this issue in the prototype. The current value is 1.5
, which is more or less the “good enough value for most typefaces and configs.”
It would probably be a lot better to adjust line-height
to each typeface, and the current user font-size
(@ 300%, 1.5
is not a really good value anymore).
So I explored dynamic leading, using a calc()
function which purpose is:
line-height
to the current typeface;line-height
to the current user font-size
.The calc()
function is the following:
line-height: calc(1em + (2ex - 1ch) - ((1rem - 16px) * 0.1667));
To sum things up, the line-height
is:
1em
= the size of the font-size
;2ex - 1ch
= 2 x-height - 1 character width
, in order to take the typeface’s proportions into account e.g. if the font has a small x-height, leading will be less, and vice versa;1rem - 16px
= the current user font-size
minus the 100% one (base font-size
);0.1667
= a scale which has been defined from an optimal range.I can get pretty solid results for our font-stacks.
Here is the calc()
function with Iowan Old Style.
I’ve checked our other font-stacks and the computed value @ 100% would probably be the one I could deem “optimal” for each typeface (in terms of typographic color).
The major benefit is that it could help us avoid defining an optimal line-height
for each typeface in every font-size
.
font-size
is not 16px
(and it bothers me a little bit to have an arbitrary value in there but we can’t use anything else, 1em
being computed from the :root
one)0.1667
feels like a magic number, or at least a weird number as it was retrofitted in there.@danielweck I know you managed that in Readium, can you see other benefits or points of failure and caveats? My quick and dirty test webpage is available as a gist if needed.
After further testing (±150 typefaces), I can report this works well except for a handful of typefaces e.g. American Typewriter, Libre Baskerville, Bitter, Lexia, Roboto Slab, FF Tisa Pro, etc.
In other words, mainly slabs with a large x-height, thick stroke and medium character width. We’ve got nothing in CSS to check the stroke for instance, so the only solution would be factoring in a thickness factor to make it perfect…
I’m pretty sure this “algorithm” could be improved though, and I’d really like someone to review it because confirmation bias is a thing.
very useful analytical approach, thanks!
We had a quick (private) discussion about tables yesterday, before the call, and we didn't have time to talk about it so I guess it’s worth listing it in this UX issue since it isn’t entirely in Readium CSS scope.
So, tables, the worst e-production nightmare nobody knows how to turn into a happy-end.
@camill-a has encountered a really long table (4 “pages”) during user settings implementation in the iOS testing app and it’s just vain to try managing that in pure CSS.
Tables are notoriously difficult to manage in a responsive context but well, publications can have a lot of them. For inspiration, here is a recap and listing of solutions by CSS-tricks.
@HadrienGardeur and I agreed that limiting the table size (if needed) and opening it into an external view (like non-linear contents) wouldn’t necessarily be a bad option to improve readability. But there’s probably other options which can be discussed.
As an author, I wouldn’t mind if the Reading System did that. To be honest, it would even suit me fine for various reasons*.
* The major reason being that I’m often being forced to fit super complex tables for which there is no chance at all they will display correctly, even in a 27" screen.
As always, how does a reading system know whether it is adequate to "take over" the presentation and interaction behaviours for table (or any other large / complex content fragment, likely to be problematic on smaller displays). For example, content creators may decide to include their own handling, like a clickable thumbnail preview which enlarges the full content in a "smart" / responsive way => how can the reading system interpret such cases as "leave me alone"?
Jiminy, you created a fine prototype of "responsive tables" for the OECD this year, presented at the EPUB Summit. Would it be acceptable for authors to follow some design pattern promoted by the EPUB production community, based on this work?
@danielweck Yeah I know, this is the main issue.
At least I can say people expect iBooks to open the table in a modal (double-click/double-tap) so if there are scripts out there, they would probably hijack this event.
@llemeurfr I doubt it if there is no “plug-n-play” script out there. And even if there were, you still have to deal with Reading Systems which don’t support javascript (per EPUB 3.1 spec, I saw that it would be expected only in scroll view by the way, not in paged view).
And it gets even worse with ePub 2 backwards compatibility as overflow won’t work in a lot of devices and apps so you can’t even use that as a fallback.
So, complex tables often end up being images, which was a Kindle recommendation at some point.
I also hit performance issues pretty quickly with javascript at the time (tables have a lot of nodes) and it doesn’t scale at all, you have to create an html file for each table at some point.
So I wouldn't hold my breath about someone finding a solution that can work everywhere, with stellar performance when JS kicks in—and nobody seems really interested in tackling this issue, at least that was the case when I did research for the OECD proto.
Just recording a thought here, as I discussed this this morning: <abbr title="something">
will only have the tooltip on :hover
, which means there won’t be any tooltip on mobile. And it looks like this is not necessarily common knowledge by the way.
Once again, the main issue is we don’t know what the author is doing. On the other hand, if we don’t find scripted
in the OPF – for EPUB –, wouldn't it be sufficient to at least offer an option to the user so that he/she can improve table
, abbr
, etc.?
I know this might be naïve reasoning but on the other hand, the more I’m looking at feedback, the more it feels like a significant part of authors are expecting the RS to do such stuff because they can’t find an interoperable solution anyway.
Is this issue still useful considering we now have apps and the UX discussion should probably happened at the app level? Or can we close this issue?
So let’s close this one since those things belong to apps.
I re-read the discussion and only the handling of tables could be re-issued in the apps’ tracker i.e. we may not want to do a lot there but maybe at least open them in a dedicated web view on double-click/double-tap, as some apps have been doing for a while. This would also allow for overflow
, should the table
be very huge – the whole web view would overflow
, something we can’t do in the paged and scrolled views.
So maybe let’s open a dedicated issue for each app if we did not reach consensus yet.
@HadrienGardeur Can you recall reaching a consensus on this one, when we discussed linear="no"
. I can’t.
Although I do think this repo might not be the best place to discuss User Experience—it’s more implementation-centric—, it is worth having a general issue imho. Indeed, we can’t have a clear separation of concerns there, the CSS design impacting UX and vice versa.
While discussing Readium CSS during the Readium 2 conference call yesterday, UX has been one of our major concerns. And I do believe @DanielWeck and @HadrienGardeur are right about that: defaults, themes, user settings are not just styles we add and remove, they are tools we offer to users. Now, one of our top priorities is building a good experience so that users can focus on, and enjoy reading electronic publications.
UX in general, and user research in particular, are by no means easy. They also require quite a budget—please note there has been some DIY tips and tricks lately though. Minimal (DIY) usability testing is I guess critical because very little user research on Reading Systems and ebooks has actually been published so far.
Anyways, Readium CSS design is pretty modular, with a lot of user settings. It doesn’t mean developers have to implement all those settings, obviously. What we want to offer is flexibility, so that implementers can do as they wish:
There are small details we must take into account. For instance, what we discussed yesterday:
px
orpt
and the user setting won’t work). Do we normalize as soon as the user sets a different font-size or do we ask them to opt-in via a checkbox?Of course, there are a lot of other UX issues we’ll have to deal with as we go along. So please feel free to use this issue to report and discuss them. We will then be able to make recommandations related to UX in docs.