How to tailwind svg icon classes: compatibility reference and troubleshooting
- Step 1Confirm the paint is currentColor — Open the SVG source. For
fill-currentto do anything, the shapes you want themed must readfill="currentColor"(orstroke="currentColor"). A leftoverfill="#hex"on a nested<path>overrides the inheritance. Run svg-to-tailwind if any hardcoded colours remain. - Step 2Confirm the SVG is inline — Inheritance only works for inline
<svg>in the document. If you're using<img src="icon.svg">orbackground-image,text-*can't reach it. Inline the markup (directly or via a component). - Step 3Smoke-test with a parent text colour — Wrap the icon:
<span class="text-red-500"><svg…/></span>. If it turns red, the inheritance path is sound and any remaining problem is a specific shape with its own fill. If not, the class is being purged or the SVG isn't inline. - Step 4Check for purge of dynamic classes — If colour classes come from a variable (e.g.
text-${color}-500), Tailwind's static scanner can't see them and purges them. Use full literal class names, a class map, or add asafelistentry/pattern. - Step 5Verify dark mode is enabled and wired to the parent —
dark:text-whiteonly works when Tailwind dark mode is configured and thedarkclass/selector is active. The icon follows the parent — put thedark:text-*on a wrapper, not the SVG paths. - Step 6Route non-Tailwind cases to the right tool — Gradients,
stop-color, or per-colour control aren't Tailwind-class problems. Use svg-hex-swapper for gradient stops and fixed hexes, or svg-css-variable-injector for variable-driven theming.
Tailwind utilities on SVG: what works
Effect of common utilities applied to an SVG element or its parent, assuming the relevant paint is currentColor.
| Utility | Effect on SVG | Notes |
|---|---|---|
text-{color} | Sets CSS color, inherited by currentColor | Apply on the SVG or any ancestor |
fill-current | fill: currentColor | Added to the root by svg-to-tailwind |
stroke-current | stroke: currentColor | Use for outline icons |
fill-{color} / stroke-{color} | Sets a specific palette colour | Bypasses inheritance — fixed colour |
w-* / h-* | Sizes the SVG box | Needs viewBox, no fixed width/height |
opacity-* | Element opacity | Applies to the whole <svg> |
rotate-* / scale-* / translate-* | CSS transforms | Applied to the <svg> element |
dark:text-* | Dark-mode colour via the cascade | Requires Tailwind dark mode enabled |
Why an icon won't recolour — decision table
The four causes, in the order you should check them.
| Symptom | Likely cause | Fix |
|---|---|---|
| One shape stays its old colour | Hardcoded fill/stroke on that element | Convert with svg-to-tailwind so it's currentColor |
Whole icon ignores text-* | Class purged in production build | Use literal class or add to safelist |
| Icon never themes anywhere | Loaded via <img> / background-image | Inline the SVG instead |
| Outline icon goes solid | Source had a real fill instead of none | Set fill="none"; keep stroke themed |
| Dark mode does nothing | Dark mode not enabled / dark: on wrong element | Enable dark mode; put dark:text-* on a parent |
What svg-to-tailwind rewrites vs. preserves
Pin your expectations to the tool's real behaviour (default current mode).
| Input | Result |
|---|---|
fill="#hex" / stroke="#hex" | → currentColor |
style="fill:#…;stroke:#…" | → fill:currentColor;stroke:currentColor |
fill="none" / stroke="none" | Preserved |
fill="url(#grad)" | Preserved (gradient ref untouched) |
<stop stop-color> | Preserved (not fill/stroke) |
Root <svg> | Gains class="fill-current" |
Cookbook
Copy-paste fragments for the common Tailwind-on-SVG situations and fixes.
The smoke test
Fastest way to prove the inheritance chain. If the icon turns red, fill-current + currentColor are wired correctly.
<span class="text-red-500">
<svg class="fill-current" viewBox="0 0 24 24">
<path d="..." fill="currentColor"/>
</svg>
</span>
Red icon → working. Not red → purge, or not inline, or
a nested hardcoded fill.One stubborn shape with a leftover fill
If a single path keeps its old colour, it still has a hardcoded fill that overrides currentColor. Convert the file so every paint is currentColor.
<svg class="fill-current"> <path d="A" fill="currentColor"/> <!-- themes --> <path d="B" fill="#ef4444"/> <!-- stuck red --> </svg> Fix: run svg-to-tailwind → path B becomes fill="currentColor".
Safelisting dynamic colour classes
Classes built from variables aren't seen by Tailwind's scanner and get purged. Safelist a pattern that covers the combinations you generate.
// breaks (purged): className={`text-${c}-500`}
// tailwind.config.js
safelist: [
'fill-current', 'stroke-current',
{ pattern: /text-(red|blue|green|gray)-(400|500|600)/ },
]Outline icon themed correctly
fill='none' stays; stroke follows the parent color. Use stroke-current to be explicit.
<span class="text-blue-500">
<svg viewBox="0 0 24 24" fill="none"
stroke="currentColor" class="stroke-current">
<path d="M5 12h14"/>
</svg>
</span>When Tailwind classes aren't the tool
Gradient stops and per-colour control aren't fill-current problems. Route them to the right sibling tool.
Gradient stops stay #hex after svg-to-tailwind: → svg-hex-swapper to recolour stop-color values Need each colour independently themeable in plain CSS: → svg-css-variable-injector (fill="var(--x)")
Edge cases and what actually happens
Hardcoded fill on a nested element overrides currentColor
Watch closelyfill-current on the root doesn't override a child's own fill="#hex" — the element's explicit attribute wins. That's the #1 'partly themed' cause. Run svg-to-tailwind so every shape reads currentColor, then the root colour propagates.
Class purged by Tailwind's content scanner
Watch closelyTailwind only generates classes it finds as literal strings in scanned files. A dynamically-built text-${c}-500 (or palette-mode fill-*) won't exist at runtime. Use full class names, a static map, or safelist.
SVG embedded as `<img>` or background-image
Not supportedExternal SVGs are isolated documents and can't inherit the page's color, so text-*/fill-current do nothing. currentColor inside resolves to the SVG's own root colour (usually black). Inline the SVG to theme it.
Gradient fills can't be themed by a class
Not supportedfill="url(#grad)" references a gradient; no fill-* class can recolour it, and svg-to-tailwind leaves url(...) paints alone. Theme the gradient's stops with svg-hex-swapper or bind stop-color to a CSS variable.
stop-color stays hardcoded after conversion
PreservedGradient stops use stop-color, which svg-to-tailwind does not match — so they keep their original hex. Don't expect the conversion to theme gradients; that's a known, correct limitation, not a bug.
Outline icon turns solid
Watch closelyOutline icons rely on fill="none". If a source mistakenly has a real fill, conversion turns it into currentColor and the shape fills in. svg-to-tailwind preserves none — so this means the source itself wasn't none. Set fill="none" explicitly.
Dark mode appears to do nothing
Watch closelydark:text-* requires Tailwind dark mode to be configured and the dark class/media state active, and it must be on a parent (the cascade source), not on a child path. Verify all three before suspecting the icon.
fill-current on root but you wanted stroke themed
Expectedfill-current only sets fill. For outline icons whose colour lives in the stroke, also use stroke-current (and ensure stroke="currentColor"). svg-to-tailwind converts stroke colours too, but the utility you apply must match the property you're theming.
Arbitrary brand colour not in the palette
SupportedTailwind can't theme to a non-palette hex via a named class — but you can use an arbitrary-value class like fill-[#4361ee] on the element by hand. svg-to-tailwind won't generate arbitrary classes; it only does currentColor (current) or nearest-palette (palette).
Frequently asked questions
Why doesn't fill-current change my icon's colour?
Three usual causes, in order: (1) a shape still has a hardcoded fill="#hex" that overrides currentColor — convert it with svg-to-tailwind; (2) the class was purged from the production build — make it literal or safelist it; (3) the SVG is embedded as an <img> and can't inherit color — inline it.
Which Tailwind classes actually work on SVG?
text-* (sets the color that currentColor inherits), fill-current/stroke-current, explicit fill-*/stroke-*, w-*/h-* (sizing, needs a viewBox and no fixed dimensions), opacity-*, and transforms like rotate-*/scale-*/translate-*. dark:text-* works when dark mode is enabled.
Does stroke-current work like fill-current?
Yes — stroke-current sets stroke: currentColor, so the stroke follows the inherited color. Use it for outline icons (alongside fill="none"). svg-to-tailwind converts stroke colours to currentColor too.
How do I theme an icon that has fill='none' and a stroke?
Keep fill="none", set stroke="currentColor", and colour it with a parent text-* (optionally add stroke-current to be explicit). svg-to-tailwind preserves fill="none" and converts the stroke colour automatically.
Why do my classes work in dev but disappear in production?
Production builds purge classes Tailwind doesn't find in scanned source. Dynamically-constructed class names (text-${color}-500) and palette-mode fill-* classes are invisible to the scanner. Use literal class names or add a safelist pattern.
Can I theme an SVG used in CSS background-image?
No. Like <img>, a background-image SVG is an isolated resource that can't read the page's color or custom properties. Only inline <svg> is themeable with text-*/fill-current.
Exactly what does svg-to-tailwind change?
In default current mode it rewrites every coloured fill/stroke (attribute and inline-style) to currentColor, skips none, leaves url(...) and stop-color alone, and adds class="fill-current" to the root <svg>. It does not strip dimensions, generate components, or do per-colour mapping in the browser.
My brand colour isn't in Tailwind's palette — what do I do?
Use Tailwind's arbitrary value syntax on that element, e.g. fill-[#4361ee], written by hand. svg-to-tailwind won't emit arbitrary classes — its palette mode snaps to the *nearest* palette class instead, which may not be your exact brand colour.
Does the website tool let me pick a Tailwind class per colour?
No. The website runs only the current mode (one shared currentColor, no options panel). Per-colour Tailwind classes come from the palette mode, available via the API/runner only.
How do I size an SVG with w-* / h-*?
The icon needs a viewBox and must not have fixed width/height on the root — those attributes override utilities. svg-to-tailwind doesn't touch dimensions, so remove them in your source or use svg-viewbox-fixer to establish a clean viewBox.
Why is one path themed and another isn't after conversion?
If conversion ran, both should be currentColor. If one isn't, that element likely had its colour in a form the regex didn't match (e.g. a presentation attribute on a <use> target in <defs>, or a stop-color). Inspect the source; route gradient stops to svg-hex-swapper.
Can I recolour gradient stops with a Tailwind class?
No — there's no Tailwind class for stop-color, and svg-to-tailwind leaves stops untouched. Recolour them with svg-hex-swapper, or bind stop-color="var(--x)" via svg-css-variable-injector for CSS-driven gradient theming.
Privacy first
Every JAD SVG tool runs entirely in your browser using the DOM API and Canvas. Your SVG files never leave your device — verified by zero outbound network requests during processing.