---
title: CSS versus personalization
date: 2017-12-28
tags: [code, css, a11y]
description: The W3C's Cognitive Accessibility Roadmap and Gap Analysis talks quite a bit about personalization of UI. But what does this mean for frontend development practices?
---

The W3C's [Cognitive Accessibility Roadmap and Gap
Analysis](https://www.w3.org/TR/coga-gap-analysis/) talks quite a bit about
personalization of UI. This means that users should be able to choose how key
elements like links and buttons are rendered. But what does this mean for
frontend development practices?

My thesis in this article is that CSS and the web as a whole put too much
power in the hands of authors and too little power in the hands of users to
allow effective personalization. Still, I will try to find some practical
guidelines that may facilitate better personalization on the web.

## What exactly is meant by "personalization"

> Personalization involves tailoring aspects of the user experience to meet the
> preferences or needs of the user. Technology holds the promise of being
> extremely flexible and the design of many systems includes the expectation
> that users will be able to optimize their interaction experience according to
> their personal preferences or accessibility requirements (needs).
>
> — [Cognitive Accessibility Roadmap and Gap
> Analysis](https://www.w3.org/TR/coga-gap-analysis/#personalization-and-user-preferences)

What is essential here is that different people have different needs. So while
some people may need additional hints on how to use an UI, other people might
be distracted or annoyed by those same hints.

There are different ways to do personalization. You can have completely
different renderings (e.g. visual browser vs screen reader). But you can also
provide options for an existing rendering (e.g. font settings in a visual
browser).

You might think now that it should be up to the web applications to provide
personalization settings. But that would actually be really bad for privacy.
Instead, personalization should ideally happen completely in the user agent
without the application even noticing.

## Why do we have CSS?

Imagine a world where the rendering of a webpage was completely controlled by
the browser.  In that world, personalization would be easy. It would probably
have been around for decades. Maybe a browser would come with some
pre-installed stylesheets you could choose from. You could even add your own
if you wanted to.

I think the main reason we ended up with author-defined stylesheets is
branding. People just wanted to communicate their own visual identity (even if
it was orange text on green background with unicorns). Maybe the long history
of WYSIWYG editors also played into it.

Whatever it was, once we had author-defined stylesheets, the browser's [default
styling](https://www.w3.org/TR/html52/rendering.html) was part of its public
interface and could not be easily changed anymore. So today we have basically
the same awful default styles as 20 years ago. [It would not take much to fix
that](http://bettermotherfuckingwebsite.com/). But as of now, it is not a
practical option to not write CSS for a page.

I believe these two reasons are merely mistakes of history. But there are
actually cases where author-defined stylesheets make a lot of sense:

You can express a lot of semantics in HTML, but it still is limited. So there
are [low-level interfaces](https://extensiblewebmanifesto.org/) like
JavaScript, ARIA, and CSS to extend these semantics.  Every UI component is an
extension of HTML semantics. Just think of `.alert-success` and `.alert-danger`
in bootstrap: The HTML/ARIA semantics just say that these are alerts, nothing
about severity.

In the alert case, the additional distinction between success and danger is
probably implicit from the content. But in other cases, the additional
semantics may be essential.

## Overwriting CSS

Now that we are stuck with CSS, the only option to enable personalization is to
overwrite it. This is also why the [User Agent Accessibility
Guidelines](https://www.w3.org/TR/UAAG20/#gl-style-sheets-config) require some
degree of support for overwriting author-defined styling.

There are some cases where changing the CSS actually works pretty well: Many
browsers today contain a "reader mode" where all inessential content is
stripped and some default styling is applied. This works really well to strip
away the branding from articles. But it would not work for rich web
applications with a lot of custom semantics.

This gets even harder if you want to change only parts of the styling, e.g.
links and buttons. Using the [`CSSStyleSheet`
API](https://developer.mozilla.org/en-US/docs/Web/API/Document/styleSheets) to
modify loaded stylesheets works pretty well, but only for same-origin
stylesheets. Another option might be the [`revert`
keyword](https://developer.mozilla.org/en-US/docs/Web/CSS/revert) that is
currently in draft state and not yet available in browsers. Imagine some code
like this:

	a,
	a:hover,
	a:focus,
	a:visited {
		all: revert !important;
	}

This would revert the link styling to the browser default. However, this might
break all kinds of things like layout (if links are used with `display: block`)
or color contrast.

But the truth is that overwriting CSS is essentially monkey-patching. I do not
know of any site that has a stable and documented CSS API. There is just no way
to do this in a non-hackish way. This may be part of the reason why [chrome
removed support for user level
stylesheets](https://bugs.chromium.org/p/chromium/issues/detail?id=347016) in
2014.

## Conclusion

The web is the most accessible medium we have ever had. But still, it is far
from perfect. Semantic HTML enables us to use a wide range of representations –
be it desktop, mobile, or screen readers. However, personalization is an area
that does not integrate well with the current approach to styling.

Adding additional CSS to a page is just not viable on a larger scale. So we
need to anticipate that replacing the complete CSS will be a common technique.
We should keep custom semantics to a minimum, especially if it is essential.

We should also embrace the customization hooks we already have: Most browsers
include features to select fonts and maybe even colors. We should honor these
settings whenever possible. Taking this a step further: Maybe just generally
write less CSS. Use more browser defaults. Why do you need to have branded
links and buttons in the first place?

Finally, it is important to craft your HTML and CSS in a way so that it does
not break, even if users do crazy things with it. Expect colors to change.
Expect font-sizes to change. Expect the unexpected. Be prepared.
