Multicolored icons
The recommended way to implement multicolored icons is to use CSS variables in SVGs. This will:
-
Eliminate the need to update all images when only one color in the palette changes.
-
Allow designers and developers to work seamlessly and share the same icon sets without any additional manual modifications.
vite-awesome-svg-loader allows you to map a set of predefined colors (or any values for that matter) to a set of CSS
variables (or any other values) via
replaceColorsList option:
export default defineConfig({ plugins: [ viteAwesomeSvgLoader({ replaceColorsList: // Global map of color replacements. Key is an original color, value is its replacement. Both can be any values: // HEX, name, rgb() or arbitrary custom values. Applied to all files. { "#003147": "red", "rgb(0, 49, 71)": "#003147", "myCustomColor": "var(--some-color-var)", },
// Map of color replacements per files { files: ["vars.svg"], // File names or regexes
// Replacements, same format as above replacements: { red: "var(--primary-color)", green: "var(--secondary-color)", blue: "var(--tertiary-color)", },
// Default value for colors that are not in replacements map. Set an empty string to preserve original colors. // Default value is "currentColor", default: "currentColor" }, }), ],}); Rendered demo
Demo's source code
src
assets
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 24 24" xml:space="preserve"> <circle fill="red" cx="8.0524569" cy="8.1588478" r="7.8950858" />
<circle fill="blue" cx="15.9475431" cy="8.1588478" r="7.8950858" />
<circle fill="green" cx="12" cy="15.8411522" r="7.8950858" />
<style type="text/css"> circle { opacity: 0.5; } </style></svg>import imageSrc from "@/assets/image.svg";import { SvgImage } from "vite-awesome-svg-loader/vanilla-integration";
export function main() { document.getElementById("app")!.innerHTML += `<div id="images" class="images"></div>`;
// Create two images with different colors
const colorVars: Record<string, string>[] = [ { "--primary-color": "red", "--secondary-color": "green", "--tertiary-color": "blue", }, { "--primary-color": "magenta", "--secondary-color": "cyan", "--tertiary-color": "yellow", }, ];
const container = document.getElementById("images")!;
for (let i = 0; i < colorVars.length; i++) { const svgEl = new SvgImage(imageSrc, container).getSvgEl(); const vars = colorVars[i];
for (const cssVar in vars) { svgEl.style.setProperty(cssVar, vars[cssVar]); } }}<!doctype html><html lang="en"> <head> <meta charset="UTF-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1" /> </head> <body> <div id="app"></div>
<script type="module"> import { main } from "./src/main.ts"; main(); </script> </body></html>{ "name": "vanilla-multicolored-icons", "version": "0.0.0", "private": true, "type": "module", "scripts": { "dev": "npm run build -- --watch", "build": "npm run type-check && npm run build-only", "build-only": "vite build --config vite.config.lib.ts", "type-check": "tsc --noEmit" }, "dependencies": { "vite-awesome-svg-loader": "*", "vite-file-tree-builder": "*", "vite-astro-entry-generator": "*" }}{ "compilerOptions": { "target": "ES2020", "useDefineForClassFields": true, "module": "ESNext", "lib": ["ES2020", "DOM", "DOM.Iterable"], "skipLibCheck": true,
/* Bundler mode */ "moduleResolution": "bundler", "allowImportingTsExtensions": true, "resolveJsonModule": true, "isolatedModules": true, "noEmit": true,
/* Linting */ "strict": true, "noUnusedLocals": true, "noUnusedParameters": true, "noFallthroughCasesInSwitch": true,
"baseUrl": ".", "paths": { "@/*": ["./src/*"] },
"types": [ // Add types for query imports (for example, "@/some/file.svg?src"). // Unfortunately, it's impossible to fully type it. Use plugin configuration instead. "vite-awesome-svg-loader",
"vite/client", // Vite types "vite-file-tree-builder" // Internal types ] }, "include": ["src"]}import { fileURLToPath, URL } from "node:url";import { defineConfig } from "vite";
// Import vite-awesome-svg-loaderimport { viteAwesomeSvgLoader } from "vite-awesome-svg-loader";
export default defineConfig({ plugins: [ viteAwesomeSvgLoader({ replaceColorsList: [ { files: ["image.svg"], // File names or regexes
// Replacements, same format as above replacements: { red: "var(--primary-color)", green: "var(--secondary-color)", blue: "var(--tertiary-color)", },
// Default value for colors that are not in replacements map. Set an empty string to preserve original colors. // Default value is "currentColor", default: "currentColor", }, ],
urlImportsInLibraryMode: "emit-files", }), ], resolve: { alias: { "@": fileURLToPath(new URL("./src", import.meta.url)), }, },});
Please open file to view its content