π¨ SVG Color Changer
Intelligently detect and batch replace colors in SVG files Β· Pure frontend, no server uploads
Updated: 2026-07-11
π SVG Code
ποΈ Preview
Preview will appear here
π― Detected Colors
Colors detected in your SVG will appear here. Click to change.
π Frequently Asked Questions (FAQ)
β Which SVG style properties can the color changer modify?
This tool supports modifying all color-related properties in SVG elements: fill, stroke, stop-color (gradient color stops), flood-color, and lighting-color. It also recognizes stroke-width and opacity. The tool automatically detects all color values used in the SVG and displays them as hexadecimal (#rrggbb) for easy identification and modification.
β Is my SVG file uploaded to a server?
No. All processing happens entirely in your browser locally. When you upload an SVG file, it stays in your browser's memory β we never send it to any server. The modified SVG is also downloaded directly from your browser. This ensures complete privacy and security for your SVG design files.
β What color formats does SVG support and how does the tool handle them?
SVG supports multiple color formats: hexadecimal (#ff0000), RGB (rgb(255,0,0)), RGBA (rgba(255,0,0,0.5)), HSL (hsl(0,100%,50%)), and named colors (red, blue, etc.). The tool automatically normalizes all colors to hexadecimal format for display and editing. When you apply changes, the new color replaces all matching values regardless of the original format.
β Can I batch replace the same color across the entire SVG?
Yes. The tool intelligently lists all colors used in the SVG. Simply click on a color swatch, pick a new color, and all elements using that color are updated instantly. If you need to recolor only specific elements, we recommend extracting those elements in a text editor first.
β Does the modified SVG preserve gradients and transparency?
Absolutely. When modifying colors, all other properties remain unchanged: gradient definitions (linearGradient, radialGradient), opacity values (opacity, fill-opacity, stroke-opacity), stroke widths, dash patterns, and all other style properties are preserved. Only the color values themselves are replaced.
β
Copied to clipboard
let currentSVG = '';
let colorMap = {}; // { '#ff0000': count, ... }
let pickerCallback = null;
function parseSVGColors() {
const input = document.getElementById('svgInput').value;
if (!input.trim()) {
document.getElementById('previewArea').innerHTML = '\x3Cdiv class="placeholder">Enter SVG code to preview automatically\x3C/div>';
document.getElementById('colorGrid').innerHTML = '\x3Cdiv class="empty-colors">The color list appears after loading SVG\x3C/div>';
document.getElementById('colorCount').textContent = '';
return;
}
// Try to parse SVG
const parser = new DOMParser();
const doc = parser.parseFromString(input, 'image/svg+xml');
const svgEl = doc.querySelector('svg');
if (!svgEl) {
document.getElementById('previewArea').innerHTML = '\x3Cdiv class="placeholder">β οΈ Invalid SVG format\x3C/div>';
return;
}
currentSVG = input;
// Render preview
const preview = document.getElementById('previewArea');
preview.innerHTML = svgEl.outerHTML;
// Extract colors
colorMap = {};
const colorAttrs = ['fill', 'stroke', 'stop-color', 'flood-color', 'lighting-color'];
const allElements = doc.querySelectorAll('*');
allElements.forEach(el => {
colorAttrs.forEach(attr => {
const val = el.getAttribute(attr);
if (val && val !== 'none' && val !== 'inherit' && val !== 'currentColor') {
const hex = normalizeColor(val);
if (hex) colorMap[hex] = (colorMap[hex] || 0) + 1;
}
});
// Also check inline style
const style = el.getAttribute('style');
if (style) {
colorAttrs.forEach(attr => {
const regex = new RegExp(attr + '\\s*:\\s*([^;]+)', 'i');
const m = style.match(regex);
if (m) {
const val = m[1].trim();
if (val && val !== 'none' && val !== 'inherit' && val !== 'currentColor') {
const hex = normalizeColor(val);
if (hex) colorMap[hex] = (colorMap[hex] || 0) + 1;
}
}
});
}
});
renderColorList();
}
function normalizeColor(color) {
if (!color) return null;
color = color.trim();
// Named colors (simplified)
const namedColors = {
'red': '#ff0000', 'blue': '#0000ff', 'green': '#008000', 'yellow': '#ffff00',
'white': '#ffffff', 'black': '#000000', 'gray': '#808080', 'grey': '#808080',
'purple': '#800080', 'orange': '#ffa500', 'pink': '#ffc0cb', 'brown': '#a52a2a',
'navy': '#000080', 'teal': '#008080', 'aqua': '#00ffff', 'lime': '#00ff00',
'fuchsia': '#ff00ff', 'silver': '#c0c0c0', 'maroon': '#800000', 'olive': '#808000'
};
if (namedColors[color.toLowerCase()]) {
return namedColors[color.toLowerCase()];
}
// Already hex
if (/^#[0-9a-f]{6}$/i.test(color)) return color.toLowerCase();
if (/^#[0-9a-f]{3}$/i.test(color)) {
return '#' + color[1]+color[1]+color[2]+color[2]+color[3]+color[3];
}
// rgb/rgba
const rgbMatch = color.match(/rgb\s*\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*(?:,\s*[\d.]+\s*)?\)/i);
if (rgbMatch) {
return '#' +
parseInt(rgbMatch[1]).toString(16).padStart(2,'0') +
parseInt(rgbMatch[2]).toString(16).padStart(2,'0') +
parseInt(rgbMatch[3]).toString(16).padStart(2,'0');
}
// hsl (simplified - just return a placeholder)
const hslMatch = color.match(/hsl\s*\(/i);
if (hslMatch) return null;
return null;
}
function renderColorList() {
const keys = Object.keys(colorMap);
const container = document.getElementById('colorGrid');
const count = document.getElementById('colorCount');
count.textContent = `(${keys.length} colors)`;
if (keys.length === 0) {
container.innerHTML = '\x3Cdiv class="empty-colors">No colors detected, or all colors are none/currentColor\x3C/div>';
return;
}
let html = '';
keys.forEach(color => {
html += `\x3Cdiv class="color-item" onclick="openPicker('${color}')">
\x3Cdiv class="color-swatch" style="background:${color}">\x3C/div>
\x3Cspan class="color-label">${color}\x3C/span>
\x3Cspan class="color-count">Γ${colorMap[color]}\x3C/span>
\x3C/div>`;
});
container.innerHTML = html;
}
function openPicker(oldColor) {
document.getElementById('pickerTitle').textContent = `Replace Color ${oldColor}`;
document.getElementById('pickerInput').value = oldColor;
document.getElementById('colorPickerPopup').style.display = 'flex';
pickerCallback = (newColor) => {
replaceColor(oldColor, newColor);
closePicker();
};
}
function closePicker() {
document.getElementById('colorPickerPopup').style.display = 'none';
pickerCallback = null;
}
document.getElementById('pickerApply').onclick = () => {
if (pickerCallback) {
pickerCallback(document.getElementById('pickerInput').value);
}
};
function replaceColor(oldColor, newColor) {
if (oldColor === newColor) return;
let svg = currentSVG;
// Replace in fill/stroke/stop-color attributes
const colorAttrs = ['fill', 'stroke', 'stop-color', 'flood-color', 'lighting-color'];
colorAttrs.forEach(attr => {
const regex = new RegExp(`(${attr}=")([^"]*)(")`, 'gi');
svg = svg.replace(regex, (match, prefix, val, suffix) => {
const normalized = normalizeColor(val);
if (normalized === oldColor) {
return prefix + newColor + suffix;
}
return match;
});
});
// Replace in style attributes
colorAttrs.forEach(attr => {
const regex = new RegExp(`(${attr}\\s*:\\s*)([^;]+)`, 'gi');
svg = svg.replace(regex, (match, prefix, val) => {
const normalized = normalizeColor(val.trim());
if (normalized === oldColor) {
return prefix + newColor;
}
return match;
});
});
document.getElementById('svgInput').value = svg;
parseSVGColors();
showToast(`β
Replaced ${oldColor} with ${newColor}`);
}
function loadSampleSVG() {
document.getElementById('svgInput').value = `\x3Csvg viewBox="0 0 200 200" xmlns="http://www.w3.org/2000/svg">
\x3Cdefs>
\x3ClinearGradient id="grad1" x1="0%" y1="0%" x2="100%" y2="100%">
\x3Cstop offset="0%" stop-color="#667eea"/>
\x3Cstop offset="100%" stop-color="#764ba2"/>
\x3C/linearGradient>
\x3C/defs>
\x3Ccircle cx="100" cy="100" r="90" fill="#f0f4ff" stroke="#d0d8e8" stroke-width="2"/>
\x3Cpolygon points="100,30 110,75 160,75 120,105 135,155 100,125 65,155 80,105 40,75 90,75" fill="#ffd700" stroke="#e6b800" stroke-width="1.5"/>
\x3Ccircle cx="70" cy="140" r="12" fill="#667eea" opacity="0.6"/>
\x3Ccircle cx="130" cy="140" r="12" fill="#764ba2" opacity="0.6"/>
\x3Ccircle cx="100" cy="160" r="8" fill="#ff6b6b" opacity="0.5"/>
\x3C/svg>`;
parseSVGColors();
}
function uploadSVG() {
document.getElementById('fileInput').click();
}
function handleFileUpload(event) {
const file = event.target.files[0];
if (!file) return;
const reader = new FileReader();
reader.onload = (e) => {
document.getElementById('svgInput').value = e.target.result;
parseSVGColors();
showToast('β
SVG file loaded');
};
reader.readAsText(file);
event.target.value = '';
}
function copySVGCode() {
const code = document.getElementById('svgInput').value;
if (!code.trim()) { showToast('β οΈ No SVG code to copy'); return; }
navigator.clipboard.writeText(code).then(() => showToast('β
SVG code copied'));
}
function downloadSVG() {
const code = document.getElementById('svgInput').value;
if (!code.trim()) { showToast('β οΈ No SVG code to download'); return; }
const blob = new Blob([code], { type: 'image/svg+xml' });
const url = URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = url;
a.download = 'modified.svg';
a.click();
URL.revokeObjectURL(url);
showToast('β
SVGDownloaded');
}
function showToast(msg) {
const toast = document.getElementById('toast');
toast.textContent = msg;
toast.classList.add('show');
setTimeout(() => toast.classList.remove('show'), 2000);
}
// Handle Enter key for picker
document.getElementById('pickerInput').addEventListener('keydown', (e) => {
if (e.key === 'Enter' && pickerCallback) {
pickerCallback(document.getElementById('pickerInput').value);
}
});