Skip to content

How to change the colour of an SVG icon with CSS

CSS can recolour an SVG only when the SVG is inline in the page. How to do it with currentColor, why fill sometimes does nothing, fill or stroke for outline icons, and the mask trick for an SVG in an img tag or a background.

Short answer: Put the SVG inline in your HTML, set fill="currentColor" (or stroke="currentColor" for an outline icon), and change the colour with the CSS color property. An SVG loaded through <img src="icon.svg"> or background-image cannot be recoloured by your CSS; for those, use the file as a mask on an element and set its background-color.

You write svg { fill: red; }, reload, and the icon stays black. Or it turns into a solid red blob. Both happen for simple reasons, and once you know which case you are in, the fix is one line.

Why does fill: red do nothing?

Three usual causes:

What you seeWhyFix
No change at allThe SVG is in an <img> or a CSS background: it is a separate image, and the page's CSS does not reach inside itPaste the SVG inline, or use the mask trick below
No change at allThe paths inside have their own fill="#000", which wins over a colour inherited from the <svg>Set fill="currentColor" on the paths, or target them: svg path { fill: currentColor; }
A solid blobIt is an outline icon, drawn with stroke; filling it paints the inside of every shapeSet stroke, not fill, and keep fill="none"

How do you recolour an inline SVG?

Use currentColor in the SVG and the colour in CSS. currentColor takes the value of the element's color property, so the icon follows the text around it:

<button class="btn">
  <svg width="20" height="20" viewBox="0 0 24 24" fill="none"
       stroke="currentColor" stroke-width="2" aria-hidden="true">
    <path d="M6 8a6 6 0 0 1 12 0c0 7 3 9 3 9H3s3-2 3-9"/>
    <path d="M10.3 21a1.94 1.94 0 0 0 3.4 0"/>
  </svg>
  Notifications
</button>
.btn { color: #1f2937; }
.btn:hover { color: #2563eb; }
@media (prefers-color-scheme: dark) {
  .btn { color: #e5e7eb; }
}

The text and the icon change together on hover and in dark mode, with no second icon file. A disabled button that greys its text greys its icon too.

Fill or stroke?

Open the SVG and look at its attributes:

  • Outline icons (lines of even width) are drawn with stroke: the <svg> has fill="none" and stroke="...". Recolour the stroke.
  • Filled icons (solid shapes) are drawn with fill. Recolour the fill.
  • Two-tone icons use both, or a second shape with lower opacity. Give each part its own colour with a CSS variable: fill="var(--icon-accent, currentColor)", then set --icon-accent where you want it.

How do you recolour an SVG in an img tag or a background?

You cannot change the colours inside the file, but you can use its shape. Make the SVG a mask on an empty element and paint the element:

<span class="icon icon-bell" aria-hidden="true"></span>
.icon {
  display: inline-block;
  width: 1.25em;
  height: 1.25em;
  background-color: currentColor;
  mask: center / contain no-repeat;
}
.icon-bell { mask-image: url("/icons/bell.svg"); }

The visible part of the SVG becomes the shape, and background-color: currentColor fills it, so it follows color like an inline icon. mask-image has worked across browsers since December 2023, per MDN.

Two catches: the mask uses only the shape, so a multi-colour icon turns into one colour; and the file must come from your own site (or one that allows it), served over http or https. A page opened straight from disk shows nothing, so test on a local server.

What about CSS filters?

You will find recipes like filter: invert(37%) sepia(93%) hue-rotate(190deg) saturate(500%) that tint a black icon in an <img>. They only approximate a colour, every colour needs its own recipe, and they tint everything in the image. Use them only when you can change neither the HTML nor the CSS around the image.

Should you make the icon accessible too?

If the icon sits next to text that says the same thing, hide it from screen readers with aria-hidden="true", as above. If the icon is the only thing in a button, the button needs a name: Accessible icon buttons: aria-label and aria-hidden shows both.

Where can you check this?

Where do you get icons to recolour?

Icon Studio searches more than 49,000 free icons from eight open-source sets, outline and filled. Copy an icon as SVG and set its fill or stroke to currentColor to colour it with CSS, or pick a colour, background and shadow in the studio and export it ready-made as SVG, PNG, React, CSS or a Power BI measure. Every set is free for commercial use under the MIT, ISC or Apache 2.0 licence.

The tool

Do it in your browser.

Design

Icon Studio

Search nearly 50,000 free icons from eight open-source sets, style them with colour, backgrounds, shadows and motion, and export SVG, PNG, React, CSS or a Power BI measure.

Keep reading

More from the blog.

Every post

Contact