so

DocBook themes

Volume 4, Issue 38; 03 Aug 2020

Adding support for dark mode as an aid to accessibility.

Once upon a time, browsers made it (relatively) easy to specify custom (CSS) stylesheets. That meant users could decide what colors and contrasts made reading easiest for them. Not so anymore. I expect that advertisers objected to users’ ability to “change their brand”, but perhaps I’m just being cynical.

Dark mode (which I don’t personally use) is more than just a preference, it’s an accessibility feature. On that basis, I wanted to explore whether or not I could make the DocBook xslTNG Stylesheets support dark mode.

Step one was rolling up my sleeves and trying to do something rational with the color selection. I’m no graphic designer, but I did what I could. I searched around a fair bit for resources to help me understand how to design a color theme. Eventually, I arrived at the documentation for Material Design.I make no assertions about the relative merits of the material design approach over other approaches. I’d welcome suggestions for other styles to investigate. It was simply the first set of guidelines that I found that seemed both reasonably comprehensive and accessible to someone with my small amount of design and color sense. I reworked the CSS so that all the colors are based on a palette:

  /* The default theme. */
  --background-color: #fffff8;
  --surface-color: #fffff8;
  --primary-color: #7f7f7f;
  --primary-variant-color: #5f5f5f;
  --secondary-color: #ffbc42;
  --error-color: #ffafaf;
  --error-border-color: #b00020;
  --on-background-color: #000000;
  --on-surface-color: #000000;
  --on-primary-color: #ffffff;
  --on-primary-variant-color: #ffffff;
  --on-secondary-color: #000000;
  --on-error-color: #000000;
  --enabled-color: rgb(240,240,240);
  --hovered-color: rgb(235,235,235);
  --focused-color: rgb(221,221,221);
  --modal-overlay-color: rgba(255,255,255,0.85);

That’s mostly the same as the previous colors. I’ve substituted primary and secondary colors for the previously ad hoc “green” and “yellow” colors used in a few places.

Next, I did my best to code up the “dark” material design:

  /* Dark */
  --background-color: #121212;
  --surface-color: #121212;
  --primary-color: #bb86fc;
  --primary-variant-color: #3700b3;
  --secondary-color: #03dac6;
  --error-color: #cf6679;
  --error-border-color: #b00020;
  --on-background-color: #ffffff;
  --on-surface-color: #ffffff;
  --on-primary-color: #000000;
  --on-primary-variant-color: #ffffff;
  --on-secondary-color: #000000;
  --on-error-color: #000000;
  --enabled-color: rgb(44,33,56);
  --hovered-color: rgb(49,38,63);
  --focused-color: rgb(63,51,74);
  --modal-overlay-color: rgba(18,18,18,0.85);
  --keycap-box-shadow: 1px 1px 1px 0px rgba(255,255,255,0.75);

and the “light” material design:

  /* Light */
  --background-color: #ffffff;
  --surface-color: #ffffff;
  --primary-color: #6200ee;
  --primary-variant-color: #3700b3;
  --secondary-color: #03dac6;
  --error-color: #b00020;
  --error-border-color: #cf6679;
  --on-background-color: #000000;
  --on-surface-color: #000000;
  --on-primary-color: #ffffff;
  --on-primary-variant-color: #ffffff;
  --on-secondary-color: #000000;
  --on-error-color: #ffffff;
  --enabled-color: rgb(240,240,240);
  --hovered-color: rgb(235,235,235);
  --focused-color: rgb(221,221,221);
  --modal-overlay-color: rgba(255,255,255,0.85);

Finally, I added some JavaScript to allow a user to switch between them. That’s kind of bogus from an accessibility point of view, but I haven’t thought up a better answer.

The JavaScript uses the HTML “local storage” feature to make the users choice persistent. It’s possible that there will be a single “flash” on large pages as I haven’t worked out how to make the user style active from the very beginning of rendering.

The whole thing is very much experimental. You can try it out by building the main branch yourself or downloading the docbook-xslTNG-1.3.0a1-SNAPSHOT release. The relevant settings are $v:theme-list to enumerate the themes (you’ll have to update the CSS as well to add more), $theme-picker to enable the theme selection JavaScript controls, and $default-theme to select a default theme. Note that selecting a default theme without enabling theme selection forces the selected theme on all your readers. (All your readers not willing to hack the class attribute on the html element, anyway.)

If you just want to see what it looks like, there’s a sample documentIf you have dark mode selected in your operating system and if your browser makes that information available to JavaScript (and if you have JavaScript enabled, naturally), then that sample document should come up in dark mode by default. Otherwise, it should come up in the new default color scheme. online. The theme selector is the “hamburger menu” in the upper left. (It’s two pages so that the “persistent ToC” coloring can be seen on the second page.)

Comments, suggestions, and more aesthetically pleasing (light and dark) color themes most humbly solicited.