Reading List
Making single color SVG icons work in dark mode from hiddedevries.nl Blog RSS feed.
Making single color SVG icons work in dark mode
In a project I work on, we had a couple of buttons that consisted of just icons (with visually hidden help text). The QA engineer I worked with, found some of those did not show up in dark mode, which rendered the buttons unusable for users of that mode. Using inline SVGs with currentColor
fixed the issue.
What’s dark mode?
Dark mode (similar-ish to high contrast mode) is a setting on platforms, browsers or devices that inverts a user’s colour scheme: from dark elements on a light background to light elements on a dark background.
This setting improves the experience for all sorts of users. For instance, people who work in the evening, those spend a lot of time behind their screens and users with low vision. It also saves energy on some types of screens.
Dark mode is available on the latest macOS and Windows 10, but also in the form of a browser plugin (Dark Background and Light Text add-on for Firefox, Dark Night Mode Chrome extension). In this post I’ll refer to Dark Modes as one thing that generally works the same across different implementations. In reality, there can be inconsistencies, of course. They can be tricky to test remotely, as testing platforms like Browserstack don’t support dark modes for security reasons.
Some dark modes will flip colors on existing websites, turning your white colours black. In our project, we try to make our interface work with that kind of dark mode, as some of our users use these settings and it lets them have a much better experience. This is a relatively cheap accessibility win.
Inline SVGs to the rescue
Let’s assume our site has a light background with black icons. One way to include an SVG icon is to use an <img>
tag pointing to the SVG. Here’s an example of a chevron icon:
<img src="chevron-right.svg" alt="" aria-hidden="true" role="presentation" />
In Windows High Contrast, Dark Background and Light Text and Dark Night Mode, the icon simply did not show. I believe the reason is that Dark Modes generally parse style sheets only, they ignore the contents of markup (including SVG files). In those cases, they will not replace black with white.
If we could only set the color for these SVGs in our stylesheets! Well, currentColor
allows for that, and, it turns out, that actually works with Dark Modes:
<svg
xmlns="http://www.w3.org/2000/svg"
width="24"
height="24"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="2"
stroke-linecap="round"
stroke-linejoin="round"
>
<polyline points="9 18 15 12 9 6" />
</svg>
For those new to currentColor
: it resolves to whatever the CSS color
is (as set or inherited) of the element the svg
is used in. So if a tool updates all color
s in the page, the SVGs automagically change colour too. It is also popular because it works great with states like hovers: for icons with text, icon colours will change whenever you change the text colour.
Declaring supported color schemes
After I posted this, Amelia Bellamy-Royds helpfully pointed me at a proposal for declaring color schemes preference. It is proposed to be a property you can set at root level (supported-color-schemes: light || dark
) or as a meta tag, so that browsers can be in the know before they start parsing CSS. The property basically lets you tell a browser that your CSS supports dark modes and will not break in them. Safari has experimental support for the property in Technology Preview 71.
The supported-color-schemes
property is meant to be used in conjunction with the prefers-color-scheme
media query.
Conclusion
So, if you use currentColor
for the only (or primary) colour in your SVG icons, they will work better in dark modes. I’ve not done much more research than this, but hope it helps others who try to make their icons work in dark mode. Feedback more than welcome!
Originally posted as Making single color SVG icons work in dark mode on Hidde's blog.