Monochroming an SVG logo

Ji Pattison-Smith
4 min readJan 20, 2023
Photo by Stephen Kraakmo on Unsplash

So those creative folk in the design department have gone and requested that we use the full colour client logo in the header, but the all-white version in the footer. Or perhaps when the mobile menu is popped open. Or, if they’re being really thoughtful, when the user is in dark mode.

Not an unusual request, and maybe they’ve even kindly provided you with the alternate one as separate SVG. But wouldn’t it be nicer if we didn’t make the user download two different versions of the logo?

Enter: CSS filters.

Let’s start with the colourful logo of a well-known brand of search engine, and stick it in a simple HTML file. Try it out at home!

<!doctype html>
<html>
<head></head>
<body>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" height="60" width="120" viewBox="0 0 120 60">
<path d="M32.377 26.446h-12.52v3.715h8.88c-.44 5.2-4.773 7.432-8.865 7.432a9.76 9.76 0 0 1-9.802-9.891c0-5.624 4.354-9.954 9.814-9.954 4.212 0 6.694 2.685 6.694 2.685l2.6-2.694s-3.34-3.717-9.43-3.717c-7.755 0-13.754 6.545-13.754 13.614 0 6.927 5.643 13.682 13.95 13.682 7.307 0 12.656-5.006 12.656-12.408 0-1.562-.227-2.464-.227-2.464z" fill="#4885ed"/><use xlink:href="#A" fill="#db3236"/><use xlink:href="#A" x="19.181" fill="#f4c20d"/>
<path d="M80.628 23.765c-4.716 0-8.422 4.13-8.422 8.766 0 5.28 4.297 8.782 8.34 8.782 2.5 0 3.83-.993 4.8-2.132v1.73c0 3.027-1.838 4.84-4.612 4.84-2.68 0-4.024-1.993-4.5-3.123l-3.372 1.4c1.196 2.53 3.604 5.167 7.9 5.167 4.7 0 8.262-2.953 8.262-9.147V24.292H85.36v1.486c-1.13-1.22-2.678-2.013-4.73-2.013zm.34 3.44c2.312 0 4.686 1.974 4.686 5.345 0 3.427-2.37 5.315-4.737 5.315-2.514 0-4.853-2.04-4.853-5.283 0-3.368 2.43-5.378 4.904-5.378z" fill="#4885ed"/>
<path d="M105.4 23.744c-4.448 0-8.183 3.54-8.183 8.76 0 5.526 4.163 8.803 8.6 8.803 3.712 0 6-2.03 7.35-3.85l-3.033-2.018c-.787 1.22-2.103 2.415-4.298 2.415-2.466 0-3.6-1.35-4.303-2.66l11.763-4.88-.6-1.43c-1.136-2.8-3.787-5.14-7.295-5.14zm.153 3.374c1.603 0 2.756.852 3.246 1.874l-7.856 3.283c-.34-2.542 2.07-5.157 4.6-5.157z" fill="#db3236"/>
<path d="M91.6 40.787h3.864V14.93H91.6z" fill="#3cba54"/>
<defs>
<path id="A" d="M42.634 23.755c-5.138 0-8.82 4.017-8.82 8.7 0 4.754 3.57 8.845 8.88 8.845 4.806 0 8.743-3.673 8.743-8.743 0-5.8-4.58-8.803-8.803-8.803zm.05 3.446c2.526 0 4.92 2.043 4.92 5.334 0 3.22-2.384 5.322-4.932 5.322-2.8 0-5-2.242-5-5.348 0-3.04 2.18-5.308 5.02-5.308z"/>
</defs>
</svg>

<style>
body {
display: flex;
justify-content: center;
align-items: center;
min-height: 100vh;
margin: 0;
}

svg {
width: 480px;
height: 240px;
}

@media (prefers-color-scheme: dark) {
html {
background: #202124;
}
}
</style>
</body>
</html>

This will show you logo in all its glory, centralised in your browser.

In dark mode, we’ve set the background colour as (something very close to) black, and the logo’s colours just don’t “pop” the same. It’d be nice if we could use the all-white version instead.

One way of doing that would be to whack the alternate logo in there alongside the colourful one and just show/hide as appropriate. But that would mean potentially two files for the user to download. And we wanna show the user some love.

With CSS filters, we can transform the colourful logo by firstly removing all the colour from it, and then inverting it.

@media (prefers-color-scheme: dark) {
html {
background: #202124;
}

svg {
filter: brightness(0) invert(100%);
}
}

You’ll see we’re applying two filter functions by declaring them both in the one property, separated by a space:

  1. brightness(0) sets the brightness to minimum. That means no light emitted from the screen, i.e., black.
  2. invert(100%) swaps every colour for its opposite, so black becomes white.

Easy peasy. And it’s supported in >95% of browsers, as long as you’re OK leaving out IE and Opera Mini.

Bonus: make it a different colour

Maybe you don’t want it all-white, but a different colour. Good news — CSS filters can help you do that, too!

If you want an all-black version, just leave off the invert function.

If you’re going for one colour that’s not white or black, that’s trickier, but certainly not beyond your capabilities! You’ll need to play about with the other CSS filter functions. After setting the brightness to 0, invert it somewhere around 30–70% to turn it grey, add in some sepia for a bit of colour, and then play about with hue-rotate and saturation until you get the colour you want.

For example, this gives a nice lime green:

filter: brightness(0) invert(45%) sepia(100%) hue-rotate(55deg) contrast(300%);

--

--