How to Change the Color of Inline SVGs with CSS

Inline SVG gives you direct access to its shapes, so CSS can adapt an icon to a button, link, theme, or interaction state. The key is to style the SVG's fill or stroke—and to make sure the SVG is actually inline in the page.

The original article image below is retained. The embedded CodePen demo is also preserved; if an embed is unavailable in a feed reader, the examples in this guide show the same CSS techniques.

Diagram illustrating how CSS changes the color of inline SVG shapes

Use fill for solid shapes and stroke for outlines

SVG uses fill to paint the inside of a shape and stroke to draw its outline. A simple way to make a single-color outline icon follow the surrounding text is to set its stroke to the currentColor keyword:

<button class="done-button" type="button">
  <svg class="icon" viewBox="0 0 24 24" aria-hidden="true">
    <path d="M20 6 9 17l-5-5" />
  </svg>
  Done
</button>
.done-button {
  color: #176b4d;
}

.icon {
  width: 1em;
  height: 1em;
  fill: none;
  stroke: currentColor;
  stroke-width: 2;
  stroke-linecap: round;
  stroke-linejoin: round;
  vertical-align: -0.125em;
}

Because the icon uses currentColor, it follows the button's text color. You can change the button's color for hover, focus, or disabled states without maintaining a second icon color. The CSS fill property works the same way for solid shapes:

<svg class="icon icon--filled" viewBox="0 0 24 24" aria-hidden="true">
  <circle cx="12" cy="12" r="10" />
</svg>
.icon--filled {
  color: #176b4d;
  fill: currentColor;
}

For a fixed color, use a CSS class such as .icon--brand { fill: #176b4d; }. If an SVG has multiple colors, give its paths or groups classes and style only the parts that should change instead of applying one blanket fill.

Confirm the SVG is inline

Page CSS can select shapes inside SVG markup that is part of the HTML document:

<svg class="icon" viewBox="0 0 24 24" aria-hidden="true">
  <path d="M20 6 9 17l-5-5" />
</svg>

It cannot select the SVG's internal paths when the file is loaded as an image, for example with <img src="icon.svg"> or background-image: url("icon.svg"). Those are separate image resources, not inline page markup. If the color needs to change with CSS, inline the SVG or choose an asset designed for that use. See MDN's guide to SVG used as an image for the differences.

If a rule has no visible effect on inline markup, check that it targets the right element. A child path with its own fill or stroke value does not inherit the value from its parent. A style="fill: ..." declaration on the SVG or path can also take precedence over a normal stylesheet rule. Remove or update the conflicting value, or target that path deliberately.

Keep icons accessible

When an icon sits beside text that already explains the action, hide the duplicate graphic from assistive technology:

<svg class="icon" viewBox="0 0 24 24" aria-hidden="true">
  <path d="M20 6 9 17l-5-5" />
</svg>
<span>Save</span>

When the SVG itself communicates information, give it an accessible name. Use a unique ID if the page contains more than one named SVG:

<svg class="icon icon--filled" viewBox="0 0 24 24" role="img" aria-labelledby="status-icon-title">
  <title id="status-icon-title">Success</title>
  <circle cx="12" cy="12" r="10" />
</svg>

The SVG title element supplies the text referenced by aria-labelledby; MDN also explains the img role. For an SVG loaded through <img>, provide useful alt text on the <img> instead. Do not communicate a status with color alone—include visible text or another clear indicator.

Use currentColor where it makes the icon easier to see in the user's color scheme, and check it in Windows High Contrast or another forced-colors mode. Avoid disabling the browser's forced-color adjustments just to preserve a brand color; the forced-colors media feature can help you test a deliberate alternative.

If you get SVG markup from a user upload or an untrusted source, sanitize it before inserting it inline. Inline SVG becomes part of the document, so do not treat untrusted markup as a harmless image file; see MDN's reference for SVG scripts.

Creating and comparing SVG icons

Tools such as the IcoMoon app can help you create or export SVG icons. Check the exported markup and the icon's license, then use fill, stroke, or currentColor as appropriate. Inline SVG is useful when you need to style individual shapes, but it is not automatically smaller or faster than an icon font; compare the assets and delivery approach used by your project. For broader tradeoffs, see inline SVG vs. icon fonts.

See the Pen SVG shapes with fill using CSS by Kanishk Kunal on CodePen.

The CodePen embed may not load in every feed reader. The examples above work without it, and MDN's guide to SVG image behavior explains how inline markup differs from an SVG image.

Troubleshooting

  • The icon does not change color: Check whether it is inline SVG rather than an <img> or CSS background, and confirm your selector matches the SVG or its paths.
  • Only part of the icon changes: Some paths may have their own fill, stroke, or inline style. Assign classes to those shapes and style them individually.
  • An outline icon looks filled: Set fill: none and a visible stroke, as in the first example. For a solid icon, use fill: currentColor instead.
  • The icon disappears in a high-contrast theme: Test with forced colors enabled and make sure the icon remains distinguishable without relying only on its color.

Leave a Reply