UI colours

Colour-related issues are abundant in user interfaces: texts are frequently illegible due to low contrast, background lightness can't reliably match user's environment, customisations break colour coding, there's little consistency, colours seem to often be optimised for a pretty picture rather than a usable interface. While some of those issues can't be solved easily, others can, but frequently get ignored. Here is a compilation of my older notes on the topic.

Basic legibility

For a text to be legible, there must be sufficient contrast between lightness of its perceived background and foreground colours. Web Content Accessibility Guidelines describe a contrast ratio ensurance procedure, which works well.

WebAIM's contrast checker allows to quickly check those contrasts online, and so does another contrast checker. NASA recommends similar approaches for colour graphics and legibility in particular.

Background lightness

People work in differently lit environments, the eyes adjust to those. Computer screens commonly emit light rather than reflect it, and using a light background colour leads to effect similar to staring at a lamp when one is in a dark environment. Often it's the default, especially for web browsers (probably mimicking paper documents, but those don't emit light). Yet in a well-lit environment dark-on-light themes tend to look better.

Usually colour themes can't depend on environment, but in some cases they can depend on user preferences: for instance, Emacs lets packages to provide custom faces (including colours) dependent on whether dark-on-light or light-on-dark colour theme is currently in use (among other parameters). When such functionality isn't available, usually it's still possible to not change colours at all, hence not harming legibility, keeping colours consistent and standard (as used for GUIs), or pick those from a fixed set (as used for TUIs). Unfortunately most common web browsers would use black-on-white themes by default, which are often too bright even for a well-lit environment, and their standard interfaces are generally considered ugly. Apparently there's no good solution, I'm just defaulting to a light-on-dark theme (as seemingly least harmful), with an alternate stylesheet for a dark-on-light theme.


Colours are useful to reflect semantics. Unfortunately they are frequently used to hide semantics instead, by either relying only on colours to carry the semantics where they can change, or even making normally differently coloured elements to look the same (e.g., hyperlinks and plain texts on websites).

Sometimes a few standard colours are available and can be reused for semantic colouring (again, as it is with Emacs faces). They aren't always sufficient, but even additional ones can be distributed as a shared package for use by different applications.

Colour adjustments

Many documents are still composed with poorly chosen colours. A custom CSS (such as Midnight Surfing) helps to deal with HTML documents, and some document/PDF viewers provide colour overriding functionality. Generally it's better than reading original documents, but potentially important colour-coded information can get lost. Some systems and devices try to adjust brightness to match the environment (or just to avoid extremes), but that leads to loss of contrast and worse legibility.

The HCL colour space is handy for such colour adjustments: hue can be preserved to keep matching colours, while lightness simplifies both contrast checking and overall lightness tweaking. One of the HCL/HSV disadvantages Wikipedia mentions is lack of sophistication and unnecessary optimisation for computing speed, but they seem to be more appropriate for legibility measurements than CIELAB/CIE 1931 XYZ, and there are perceivable lags on modern hardware when web browser extensions attempting to use similar approaches are active (in addition to the lags that are always there, that is).

Random colour generation

Random foreground text colours are needed sometimes (e.g., for nickname colourisation in IRC clients), and they should have sufficient contrast ratio with the background. An approach I used to generate those is based on the contrast ratio ensurance procedure, generating suitable colours only. An illustration in Scheme is available in random-colour.scm; Elisp versions of that are (or at least were in 2014) available in Circe and rcirc-color. A somewhat simpler approach is just to filter a list of colours using the original procedure.

IWantHue and How To Avoid Equidistant HSV Colors provide more information on the topic, though rather focusing on random colours for diagrams.

Similar approaches are usable to generate whole themes out of reference colours or basic parameters. The LAB colour space is more suitable if colour difference is more important than hue preservation. An Elisp example is available in generated-colour-theme.el.

User settings

As mentioned above, common infrastructures make it hard to respect user settings, and apparently in most cases users would even prefer their defaults to be ignored. It's even worse when UIs make assumptions about user defaults, such as setting background or foreground colour, and not setting the other one, or use graphics (for diagrams, mathematical formulae, etc) with transparent backgrounds and fixed foregrounds (while there is currentColor for use with SVG).

Universal design

The previous sections are focused on making colour themes less painful to work with for people with relatively good vision, who can see those colours at all. But the coloured interfaces should also be usable by colour-blind users, and interfaces in general – by blind ones.


While the overall situation—particularly on the web—is rather bad, and there's no good way to solve it on per-website/application or per-user basis, it's still possible to do much better than average, even by checking the contrast alone or not defining colours at all.