How to hex swapping vs. css custom properties: which fits your svg?
- Step 1Ask whether colours change after shipping — If the colour is final once the file is exported (rebrand, print, email), use the Hex Swapper. If it must respond to dark mode or user choice, use the CSS Variable Injector.
- Step 2Check how the SVG is delivered — Inlined directly in HTML can use CSS variables. Loaded via
<img src>,<object>, or CSSbackground-imagecannot — those are isolated from the document cascade, so only baked hex (the swapper) will change their colours. - Step 3For a static rebrand, run the Hex Swapper — Set
from → topairs and process. The output has fixed hex values and works everywhere, including email clients that strip<style>and CSS variables. - Step 4For runtime theming, run the CSS Variable Injector — Map specific colours to variable names, or leave the map empty to auto-assign
--svg-color-1,--svg-color-2, … to every detected colour. Then control them from:rootin your stylesheet. - Step 5Mind the format-matching limits of both — Both tools find colours by literal hex string (3-digit hex is expanded first). Neither converts
rgb()/hsl()/named colours, so normalise your SVG to hex if it mixes formats before either tool will catch every instance. - Step 6Document the chosen approach — Pick one strategy per library and note it in your style guide so the next person doesn't ship half-baked, half-variable icons.
Hex Swapper vs. CSS Variable Injector
Two JAD tools, two opposite outcomes. Both find colours by literal hex string with short-hex expansion.
| Aspect | Hex Swapper | CSS Variable Injector |
|---|---|---|
| What it writes | A fixed hex value (your to) | var(--name) references |
| When colour is decided | At export time (baked) | At runtime (by CSS in scope) |
Works as <img src> / background-image | Yes — colours are inside the file | No — variables don't inherit into isolated SVGs |
| Works in email clients | Yes | Unreliable (many strip CSS / variables) |
| Auto-detect colours | No — you supply each from | Yes — empty map assigns --svg-color-N |
| Best for | Rebrands, print, served assets | Dark mode, themable inlined icons |
Pick by delivery method
How the SVG is embedded determines whether CSS variables can reach it at all.
| How the SVG is used | CSS variables reach it? | Recommended tool |
|---|---|---|
Inlined <svg> in HTML | Yes | Either — injector for theming |
<img src="icon.svg"> | No | Hex Swapper |
CSS background-image: url(icon.svg) | No | Hex Swapper |
<object> / <iframe> | Not from parent doc | Hex Swapper |
| Email HTML | Usually stripped | Hex Swapper |
Cookbook
Worked decisions for common situations. Each shows which tool to reach for and why.
Rebrand on icons served as <img>
Marketing icons are referenced as <img src> across the site. CSS variables would never reach them. Bake the new brand colour with the Hex Swapper.
Delivery: <img src="/icons/logo.svg">
Goal: brand blue #003082 -> #1a56db
Choice: Hex Swapper (variables can't reach <img>)
Pair: #003082 -> #1a56db
Result: a self-contained recoloured file that renders
identically in every browser and email.Dark mode toggle on inlined icons
Icons are inlined in React/HTML and must flip colour with a theme toggle. Inject variables, then drive them from CSS.
Delivery: inlined <svg> in the page
Goal: icon follows light/dark theme
Choice: CSS Variable Injector
fill="#1f2937" -> fill="var(--icon)"
CSS:
:root { --icon: #1f2937; }
.dark :root { --icon: #e5e7eb; }
Now one variable flips every icon's colour at runtime.Hybrid — bake brand, variable-ise accents
The brand mark colour never changes; the accent should follow user themes. Use both tools in sequence on an inlined icon.
Step 1 (Hex Swapper): lock the brand mark #888888 (legacy) -> #003082 (current brand) Step 2 (CSS Variable Injector): theme the accent only #f59e0b -> var(--accent) Brand stays fixed; accent responds to --accent at runtime.
Let the injector name variables for you
A complex multi-colour illustration would be tedious to map by hand. Leave the injector's map empty so it auto-assigns sequential variables.
CSS Variable Injector, empty map: #ff5757 -> var(--svg-color-1) #8c52ff -> var(--svg-color-2) #00bf63 -> var(--svg-color-3) Then set each --svg-color-N from your stylesheet. (The Hex Swapper has no auto-detect — you'd type every from.)
Why a hex pair missed an rgb() colour
Neither tool converts formats. If theming 'didn't work', the colour may be stored as rgb(). Normalise to hex first, then choose your tool.
File: <path fill="rgb(31,41,55)"/> Hex Swapper pair #1f2937 -> … : 0 swapped Injector mapping #1f2937 : nothing replaced Reason: both match the literal hex string, not rgb(). Fix: re-export with hex colours, then re-run.
Edge cases and what actually happens
CSS variables on an <img src> SVG
Won't applyAn SVG loaded via <img>, <object>, <iframe>, or CSS background-image is isolated from the host document's cascade. var(--…) inside it resolves to nothing (or the fallback). For these delivery methods only baked hex — the Hex Swapper — changes colours.
Expecting the Hex Swapper to theme at runtime
Wrong toolThe swapper writes fixed hex. There is no runtime behaviour in its output. If you need dark mode or user themes, the CSS Variable Injector is the correct tool.
Mixed colour formats in one file
PartialBoth tools match literal hex strings only. A file mixing #1f2937 and rgb(31,41,55) for the same colour will only have the hex instances handled. Normalise the SVG to hex before either tool to catch everything.
Injector auto-detect on a baked file
ExpectedIf you run the CSS Variable Injector with an empty map, it variable-ises every unique colour it finds — including ones you wanted left fixed. Provide an explicit map when you only want to theme some colours.
Email artwork with CSS variables
Unsupported in emailMany email clients strip <style> blocks and ignore CSS custom properties. Variable-based theming is unreliable here; bake colours with the Hex Swapper for predictable rendering in inboxes.
currentColor already in the file
By designIf the SVG already uses currentColor, its colour follows the CSS color property — a third theming mechanism. The Hex Swapper treats currentColor as a literal string (no special handling); the injector won't touch it unless you map it explicitly.
Half-baked, half-variable library
InconsistentMixing strategies across one icon set causes some icons to follow the theme and others to stay fixed. Pick one approach per library, or use the hybrid pattern deliberately and document it.
Need utility-class colours instead
Different bridgeIf your stack is Tailwind, the SVG-to-Tailwind tool is a third option — it can map colours to the nearest Tailwind class (palette mode) or blanket them to currentColor (default), which composes with text-* utilities.
Frequently asked questions
When should I bake colours with the Hex Swapper instead of using variables?
Whenever the colour is final at export time: one-time rebrands, print assets, email artwork, and any SVG delivered as <img src> or CSS background-image. In those cases CSS variables can't reach the SVG anyway, so baked hex is the only reliable option.
Why don't my CSS variables affect an SVG used as <img>?
An SVG referenced via <img>, <object>, <iframe>, or background-image is rendered in isolation from the host document's CSS cascade. Custom properties defined on :root don't propagate into it. Inline the SVG in your HTML for variables to work, or bake the colours with the Hex Swapper.
Can I use both approaches on the same icon?
Yes, on an inlined icon. Bake the rarely-changing brand colours with the Hex Swapper, then run the CSS Variable Injector to convert only the theme-specific colours to var(--…). The brand stays fixed; the accents respond to runtime CSS.
Does either tool convert rgb() or named colours to hex?
No. Both the Hex Swapper and the CSS Variable Injector match literal hex strings (with 3-digit hex expanded to 6-digit first). They don't normalise rgb(), hsl(), or names. If your file mixes formats, re-export to hex first so every instance is caught.
Can the CSS Variable Injector find colours automatically?
Yes. Leave its mapping empty and it scans the SVG, assigning sequential --svg-color-1, --svg-color-2, … to each unique colour. The Hex Swapper has no auto-detect — you supply each source colour yourself.
Which is better for a design-token pipeline?
CSS variables, for inlined SVGs, because they map naturally to design tokens (--color-primary). Use the injector to wire colours to variable names, then bind those variables to your token values. The Hex Swapper is for syncing static files to a token value at a point in time.
Will baked colours render in older browsers and email?
Yes. Baked hex is just attribute/style text — universally supported, including email clients that strip CSS. CSS custom properties are well-supported in modern browsers but unreliable in email.
Does the Hex Swapper output anything that changes at runtime?
No. Its output is a plain recoloured SVG with fixed values. There is no script, no variable, no media query — just new hex where the old hex was.
What about Tailwind projects?
Consider the SVG-to-Tailwind bridge. Its default mode blankets colours to currentColor (so text-* controls the icon), and its palette mode maps each colour to the nearest Tailwind class via CIE Lab distance. That's a class-based middle ground between baking and variables.
If I inject variables, where do I set the actual colours?
In your CSS, typically on :root or a theme class. For example :root{--icon:#1f2937} and .dark{--icon:#e5e7eb}. The injected SVG references var(--icon), so changing the variable re-colours every instance instantly.
Can I undo a baked swap?
Keep your original file. The Hex Swapper writes a new -recolored.svg; it doesn't modify the source on disk. To revert, re-run with the colours reversed, or restore from your version control / original.
Which approach is more SEO/performance friendly?
Both produce small text changes with negligible size impact. The real difference is maintainability: variables centralise theme control (one CSS edit re-colours everything), while baked hex is simplest for assets that ship and never change.
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.