| Atom feed

Rarely-discussed web dev color issues


Lots has already been written about contrast, color palettes, and so on, but I find most of the discussion misses a few things.

Dark mode vs light mode isn’t a pure dichotomy

Especially within dark modes, there’s a lot of room to bias lighter or darker while keeping good contrast. A #000000 background and #DDDDDD foreground feels very different from a #333333 background and #FFFFFF foreground. A light mode user will probably be much more comfortable with the latter than the former, and as a dark mode user I’m much more comfortable with slightly dimmed light designs (like Hacker News) than full-white light designs.

If you only have one color scheme and it’s on the lighter side of dark mode or the darker side of light mode, you’re probably good. If it’s all the way at one extreme or the other, you’re liable to annoy some people.

Dark modes and light modes don’t work well with the same accent colors

Green has a disproportionate effect on percieved brightness; #00FF00 is way brighter than #0000FF. If you put #00FF00 on #EEEEEE or #0000FF on #222222, your effective contrast is garbage, while #0000FF on #EEEEEE and #00FF00 on #222222 are completely fine.

You can use any hue you want with any background brightness you want, but with some it’s not going to be as punchy. If you really want to use green on white, you could drop to something like #007700 on #EEEEEE to make it readable, but then the green-ness of it doesn’t pop out at you in the way you might like. The same works with blue on black like #8888FF on #222222; it works, but it loses a lot of its intensity.

It’s tougher to make hues through the yellow-green-cyan range work well on light backgrounds and tougher to make reds, purples, and blues work well on dark backgrounds. Magentas, some oranges, and a very narrow slice of sky blue are fairly good for either.

This is one reason you might want to use a very dark dark mode: it gives you room to make a wider variety of colors punchy without losing contrast.

Flicker at #FFFFFF

Full white (or any color with a maxed out channel) isn’t just harsh for contrast reasons, but also because a lot of monitors overcook it a bit in the interest of maximum contrast and end up flickering. Usually this is easy to miss or just mild discomfort, but it varies a lot; on some monitors (or around other sources of flickery light) this makes my left eye hurt and go slightly nearsighted. Something like #F8F8F8 is often quite a bit more comfortable without much loss of contrast.

Ideally we would name and shame monitors until they quit doing this instead of considering it at all on this side, but even the most careful monitor reviewers didn’t touch this last I looked. It’s not easy to test, and even if it were easy it’s not clear that any industry-wide changes could happen anytime soon.

Warm white is less harsh

Neutral white is unnecessarily tough on the eyes in many contexts. It can be tougher to make something look appealing using a warmer color (all else equal cooler-biased designs feel more fresh and modern), but if you have to look at it for a while warm colors are less harsh. This applies to both dark mode foregrounds and light mode backgrounds.

Color effects on font rendering

Font rendering has to make tradeoffs between sharpness, color fringing, and being true to the font’s intended shapes. Your color choices affect which subpixels are lit and therefore what the font rendering can do with those subpixels.

Having only one subpixel differ from the background (like green on black or magenta on white) maximizes sharpness and eliminates color fringing entirely, at the cost of less accurate shaping. Magenta on black or green on white (not just differing in multiple subpixels but also in subpixels far apart from each other) behave more like greyscale text, blurrier and more prone to fringing but with more accurate shapes.

This is niche, but since you don’t always have much control over font rendering, if you’re particular about how your text looks it might be relevant at some point.