Menu

Making single color SVG icons work in dark mode

Published on by Hidde de Vries in tutorials .

In a project I work on, we had a couple of buttons that consisted of just icons (with visually hidden help text). The awesome 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" />

(examples on CodePen)

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 colors 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!

Update 25-12-2018: added section about declaring color schemes.

Thanks Šime Vidas, Amelia Bellamy-Royds and Timothy Hatcher for their feedback and suggestions.

Comments & mentions (38)

Rik Schennink likes this
Koen Kivits likes this
jalbertbowdenii likes this
replied: @hdv heb jij wel eens meegemaakt dat je een font alleen voor 1 header gebruikt (bijv een logo)? wat is de beste oplossing? converteren naar svg en embedden? of is dat niet echt accessible?
replied: cool! is it possible to determine whether the user's machine is currently in dark mode in css or js? that'd be rad
Hidde replied: yes! with `@media(prefers-color-scheme:dark)` developer.mozilla.org/en-US/docs/Web…
replied: sweeeeet!
Ruud Steltenpool reposted this
Ruud Steltenpool likes this
likes this
Paul Grenier likes this
Šime Vidas replied: Using currentColor makes sense in general, but is this really related to dark mode in macOS? I use it, but it doesn’t seem to affect the currentColor value in Safari (which remains black):

https://output.jsbin . com/vumedoc/quiet
Peet Sneekes likes this
Hidde replied: I think it is specifically the best bet when dealing with systems that automatically make websites dark, I think Safari doesn't do that yet. Maybe I should clarify in my post
Amelia Bellamy-Royds replied: By the way, for color overrides that truly operate at the browser level (like Windows high contrast mode), the `currentColor` approach will work in stand-alone SVG in <img>, too, since the default `color` will have changed.

But no guarantees with JS/extension-based dark modes.
Chris O'Brien likes this
David Hund ✌ likes this
Jeffrey Bennett likes this
ZZnidar likes this
Miles reposted this
Joseph Kohlmann likes this
CSS-Tricks replied: > if you use currentColor for the only (or primary) colour in your SVG icons, they will work better in dark modes.

hiddedevries.nl/en/blog/2018-1…
Andrea Giammarchi replied: ... and Linux (GNOME) for the last 5 years ... but people gotta ignore it, 'cause it's still cool in (soon) 2019 to ignore Linux, same cool as it's been ignoring Firefox, or MS Edge, 'till now ...

hiddedevries.nl/en/blog/2018-1…
Roberto Iriondo replied: > if you use currentColor for the only (or primary) colour in your SVG icons, they will work better in dark modes.

hiddedevries.nl/en/blog/2018-1…
DAI Builds - Digital Agency replied: @robiriondo: > if you use currentColor for the only (or primary) colour in your SVG icons, they will work better in dark modes.

hiddedevries.nl/en/blog/2018-1…
Jeremy Keith replied:

Making single color SVG icons work in dark mode

Another good reason to use the currentColor value in SVGs.

Adactio Links replied: Making single color SVG icons work in dark mode hiddedevries.nl/en/blog/2018-1…
Resoource replied: Making single color SVG icons work in dark mode hiddedevries.nl/en/blog/2018-1…

#CSS #SVG #webdev #code #FrontEnd
Dominik Schwind likes this
Dominik Schwind likes this
Stéphanie Walter replied: "Making single color SVG icons work in dark mode" in-line SVG + currentColor +
supported-color-schemes in conjunction with prefers-color-scheme
hiddedevries.nl/en/blog/2018-1…
David liu replied: RT WalterStephanie: "Making single color SVG icons work in dark mode" in-line SVG + currentColor +
supported-color-schemes in conjunction with prefers-color-scheme
hiddedevries.nl/en/blog/2018-1…
Front-End Front replied: Making single color SVG icons work in dark mode hiddedevries.nl/en/blog/2018-1…
julzmon replied: Making single color SVG icons work in dark mode hiddedevries.nl/en/blog/2018-1…
Timothy Martin replied: Making single color SVG icons work in dark mode
hiddedevries.nl/en/blog/2018-1…

#webdev #webdesign #ux #uxdesign #ui #uidesign #design #coding #programming #html #css #javascript #code #tutorial #freelancer #freelancing #fullstack #frontend #web #website #tech #technology
Sean Goresht replied: Making single colour #SVG icons work in dark mode - hiddedevries.nl/en/blog/2018-1…
Sean Goresht replied: Making single colour #SVG icons work in dark mode - hiddedevries.nl/en/blog/2018-1…
Dany replied: Making single color SVG icons work in dark mode hiddedevries.nl/en/blog/2018-1…
Leave a comment
Posted a response to this?

This website uses Webmentions. You can manually notify me if you have posted a response, by entering the URL below.