How to Change SVG Icon Color with CSS: currentColor, Variables & Dark Mode
Learn how to control SVG icon colors using CSS. Fix hardcoded fills, use currentColor for inheritance, apply CSS custom properties for theming, and support dark mode — with practical code examples.
Why SVG Colors Can Be Tricky
SVG icons exported from design tools — or generated by AI — often come with hardcoded fill attributes directly on elements:
<svg viewBox="0 0 24 24">
<path fill="#1a1a1a" d="M12 2L2 7l10 5 10-5-10-5z"/>
<path fill="#1a1a1a" d="M2 17l10 5 10-5M2 12l10 5 10-5"/>
</svg>
When you try to change the color with CSS, nothing happens:
svg {
color: blue; /* doesn't work */
fill: blue; /* still doesn't work */
}
This is the most common SVG frustration developers encounter. The reason: inline fill attributes have higher specificity than CSS rules. The browser sees the inline fill="#1a1a1a" and ignores your stylesheet entirely.
There are three ways to solve this, each suited to different situations.
Solution 1: Remove Inline Fills and Use CSS
The simplest fix is to remove the hardcoded fill attributes from the SVG markup:
<svg viewBox="0 0 24 24">
<path d="M12 2L2 7l10 5 10-5-10-5z"/>
<path d="M2 17l10 5 10-5M2 12l10 5 10-5"/>
</svg>
Now CSS works as expected:
svg {
fill: blue;
}
Without an inline fill, SVG elements default to fill="black". Your CSS rule overrides this default with no specificity conflict.
When to use this: When you have full control over the SVG source and only need one color.
Solution 2: Use currentColor for Inherited Color
currentColor is the most powerful technique for making SVG icons flexible. It tells the SVG to use the text color value from its parent element:
<svg viewBox="0 0 24 24" fill="currentColor">
<path d="M12 2L2 7l10 5 10-5-10-5z"/>
<path d="M2 17l10 5 10-5M2 12l10 5 10-5"/>
</svg>
Now the icon color is controlled by the CSS color property:
.nav-link {
color: #333;
}
.nav-link:hover {
color: #0066cc;
}
.nav-link svg {
fill: currentColor; /* inherits color from .nav-link */
}
The icon automatically matches the text color and responds to state changes like :hover and :focus.
currentColor with Stroke Icons
For outline-style icons that use stroke instead of fill, apply currentColor to the stroke:
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
<circle cx="12" cy="12" r="10"/>
<path d="M12 8v4l3 3"/>
</svg>
.icon {
color: #666;
}
This is the pattern used by popular icon libraries like Lucide and Heroicons. Both set stroke="currentColor" so icons automatically match surrounding text.
Why currentColor Works
currentColor is a CSS keyword that resolves to the computed value of the color property on the same element. When used as an SVG attribute value, it creates a bridge between CSS color inheritance and SVG rendering. The icon becomes part of the document's color flow rather than an isolated graphic with its own colors.
When to use this: When icons should match adjacent text color. This is the recommended default for most icon use cases.
Solution 3: CSS Custom Properties for Multi-Theme Support
For more complex theming — where you need different colors for different contexts — CSS custom properties (variables) give you precise control:
:root {
--icon-primary: #1a1a1a;
--icon-secondary: #666666;
--icon-accent: #0066cc;
}
<svg viewBox="0 0 24 24">
<path fill="var(--icon-primary)" d="M12 2L2 7l10 5 10-5-10-5z"/>
<path fill="var(--icon-secondary)" d="M2 17l10 5 10-5M2 12l10 5 10-5"/>
</svg>
Now you can change multiple icon colors at once by updating the variables:
.dark-section {
--icon-primary: #ffffff;
--icon-secondary: #aaaaaa;
--icon-accent: #66aaff;
}
CSS Variables in SVG Attributes vs. Stylesheets
CSS custom properties work in both SVG attributes and stylesheets, but with a difference:
In attributes (inline):
<path fill="var(--icon-color)"/>
In stylesheets (CSS):
path {
fill: var(--icon-color);
}
Both work in modern browsers. The attribute approach is convenient when each element needs a different variable. The stylesheet approach is better when all paths share the same color.
When to use this: When you need different color themes across sections, or when icons have multiple colors that need independent control.
Dark Mode Support
Using prefers-color-scheme
The prefers-color-scheme media query lets icons automatically adapt to the user's system preference:
:root {
--icon-color: #1a1a1a;
}
@media (prefers-color-scheme: dark) {
:root {
--icon-color: #e0e0e0;
}
}
svg {
fill: var(--icon-color);
}
Class-Based Dark Mode (Tailwind CSS)
If your project uses a class-based dark mode toggle (common with Tailwind CSS), use the .dark class:
:root {
--icon-color: #1a1a1a;
}
.dark {
--icon-color: #e0e0e0;
}
With Tailwind's utility classes, you can apply dark mode inline:
<svg class="fill-gray-800 dark:fill-gray-200" viewBox="0 0 24 24">
<path d="M12 2L2 7l10 5 10-5-10-5z"/>
</svg>
currentColor + Dark Mode — The Best Combo
The most maintainable approach combines currentColor with dark mode text color:
body {
color: #1a1a1a;
}
@media (prefers-color-scheme: dark) {
body {
color: #e0e0e0;
}
}
<svg fill="currentColor" viewBox="0 0 24 24">
<path d="M12 2L2 7l10 5 10-5-10-5z"/>
</svg>
With this pattern, icons follow the text color into dark mode without any icon-specific CSS. No variables, no extra rules — just currentColor inheriting from the document's color scheme.
Fixing AI-Generated SVG Icons
AI-generated SVG icons (including those from our AI Icon Generator) typically output hardcoded fill values. Here's how to make them theme-ready:
Step 1: Generate your icon
Step 2: Remove hardcoded fills or replace them with currentColor
Before:
<svg viewBox="0 0 24 24">
<path fill="#000000" d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10..."/>
</svg>
After:
<svg viewBox="0 0 24 24" fill="currentColor">
<path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10..."/>
</svg>
Step 3: Optionally, run through our SVG Optimizer to clean up other redundant attributes
This three-step workflow — generate, update color handling, optimize — produces production-ready icons that work in any color context.
Quick Reference
| Technique | Use Case | Browser Support |
|---|---|---|
Remove inline fill + CSS | Single-color icons, simple styling | All browsers |
currentColor | Icons that match text color | All browsers |
| CSS custom properties | Multi-theme, multi-color icons | All modern browsers |
prefers-color-scheme | Automatic dark mode | All modern browsers |
Tailwind dark: utilities | Class-based dark mode | All modern browsers |
Related Tools
- AI Icon Generator — Generate SVG icons from text descriptions, then apply these color techniques
- SVG Viewer — Preview your color changes in real time
- SVG Optimizer — Clean up redundant fill attributes and other bloat after editing