Every website has a visual identity — a set of brand colors that define its look and feel. Extracting those colors programmatically opens up powerful use cases: dynamic theming, branded dashboards, competitive analysis, and design system automation.
In this guide, we'll explore how brand color extraction works and how to implement it.
Before diving into the how, let's understand the why:
Brand color extraction is a multi-step process:
The most direct source of brand colors: the website's stylesheets.
function extractColorsFromCSS() {
const colors = new Set();
// Check all computed styles
for (const sheet of document.styleSheets) {
try {
for (const rule of sheet.cssRules) {
const text = rule.cssText;
// Match hex colors
const hexMatches = text.match(/#[0-9A-Fa-f]{3,8}/g);
hexMatches?.forEach(c => colors.add(c.toUpperCase()));
}
} catch (e) {
// Cross-origin stylesheets may be inaccessible
}
}
return [...colors];
}
Beyond stylesheets, inline styles on key elements carry brand signals:
function extractInlineColors() {
const selectors = [
'header', 'nav', '.navbar', '.header',
'a', 'button', '.btn', '.button',
'h1', 'h2', '.brand', '.logo',
];
const colors = new Map();
for (const selector of selectors) {
const elements = document.querySelectorAll(selector);
for (const el of elements) {
const style = getComputedStyle(el);
const color = style.color;
const bg = style.backgroundColor;
if (color !== 'rgb(0, 0, 0)') {
colors.set(color, (colors.get(color) || 0) + 1);
}
if (bg !== 'rgba(0, 0, 0, 0)' && bg !== 'rgb(255, 255, 255)') {
colors.set(bg, (colors.get(bg) || 0) + 1);
}
}
}
// Return colors sorted by frequency
return [...colors.entries()]
.sort((a, b) => b[1] - a[1])
.map(([color]) => color);
}
Not all colors on a page are brand colors. A good algorithm distinguishes brand colors from content colors:
When CSS analysis is inconclusive, analyzing the logo image provides a reliable fallback:
async function extractColorsFromLogo(logoUrl) {
const img = new Image();
img.crossOrigin = 'anonymous';
img.src = logoUrl;
await img.decode();
const canvas = document.createElement('canvas');
const ctx = canvas.getContext('2d');
// Scale down for performance
const scale = Math.min(1, 100 / Math.max(img.width, img.height));
canvas.width = img.width * scale;
canvas.height = img.height * scale;
ctx.drawImage(img, 0, 0, canvas.width, canvas.height);
const imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);
const pixels = imageData.data;
// Count color frequencies
const colorCounts = new Map();
for (let i = 0; i < pixels.length; i += 4) {
const r = pixels[i], g = pixels[i + 1], b = pixels[i + 2];
// Skip transparent and near-white pixels
if (pixels[i + 3] < 128) continue;
if (r > 240 && g > 240 && b > 240) continue;
const hex = `#${r.toString(16).padStart(2, '0')}${g.toString(16).padStart(2, '0')}${b.toString(16).padStart(2, '0')}`;
colorCounts.set(hex, (colorCounts.get(hex) || 0) + 1);
}
return [...colorCounts.entries()]
.sort((a, b) => b[1] - a[1])
.slice(0, 5)
.map(([color]) => color.toUpperCase());
}
Building this yourself means dealing with:
A dedicated API like Brandohue handles all of this:
const response = await fetch('https://api.brandohue.com/api/v1/extract', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer YOUR_API_KEY`,
},
body: JSON.stringify({ url: 'https://stripe.com' }),
});
const { colors, colorPalette, contrastRatios } = await response.json();
// colors: ["#635BFF", "#0A2540", "#00D924"]
// colorPalette.dominant.hex: "#635BFF"
// contrastRatios.dominantOnWhite: 4.2
What the API provides:
function BrandedDashboard({ companyDomain }) {
const [colors, setColors] = useState(null);
useEffect(() => {
brandohue.extract(companyDomain).then(data => {
const root = document.documentElement;
root.style.setProperty('--brand-primary', data.colorPalette.dominant.hex);
root.style.setProperty('--brand-accent', data.colorPalette.accent.hex);
setColors(data.colors);
});
}, [companyDomain]);
if (!colors) return <Skeleton />;
return (
<div className="dashboard" style={{
'--brand-primary': colors[0],
'--brand-accent': colors[1]
}}>
<header style={{ background: colors[0] }}>...</header>
<Chart color={colors[1]} />
</div>
);
}
function AccountCard({ company }) {
return (
<div className="account-card" style={{
borderLeft: `4px solid ${company.brandColor}`
}}>
<img src={company.logo} alt={company.name} />
<h3>{company.name}</h3>
</div>
);
}
Brand color extraction combines CSS analysis, element frequency counting, heuristic ranking, and logo image processing. Building this from scratch requires significant engineering effort and ongoing maintenance.
A color palette API handles all the complexity — CSS parsing, image analysis, accessibility calculations — in a single call, alongside the logo and metadata extraction you likely already need.
Start extracting brand colors with 1000 free credits.