How to Extract a Color Palette From Any Website

Extract color palette from website HTML, rendered CSS, or one JSON command. DevTools, grep, and magpie brand, tested on real sites, failure modes included.

MMotherlode Lab10 min read
Magpie title card: How to Extract a Color Palette From Any Website

How to Extract a Color Palette From Any Website

Linear’s homepage carries 23 distinct hex colors in its inline CSS. The same HTML document holds 47 if you also count the ones hiding in SVG fills and script payloads. Every site’s palette sits in plain text like that; the job is knowing which layer to read.

This guide shows four ways to extract a color palette from website code: one click for a single color, one panel for a full audit, one grep for scripting, and one command that returns the whole brand surface as JSON. I ran all four on 2026-10-16 against six real sites, and I’ll show where each method comes back empty, because every one of them has a blind spot.

Which website color palette extractor fits the job

Method What you get What it misses Best for
Eyedropper in DevTools One rendered pixel The other 99% of the palette Stealing a single accent
Chrome’s CSS Overview panel Every color in rendered CSS, grouped by use, with element lists Colors painted by canvas or images A one-time audit while the page is open
curl + grep Hex codes in raw HTML, ranked by frequency rgb(), hsl(), named colors, external stylesheets A fast, scriptable pass
magpie brand Colors, fonts, logo, favicon as one JSON object External stylesheets, JS-injected styles, old HTML color attributes Automation, agents, brand snapshots

You need a browser and a terminal; nothing to install beyond curl for the first three methods. Paste-a-URL extractor sites exist too (palette.site and colorize.design are the ones that rank), and they’re fine for public pages, but the page renders on their servers, so keep internal URLs out of the box.

One line of etiquette before the steps: reading a public page’s CSS is what every browser does when it loads the page, so this is the polite end of scraping. Still respect robots.txt and rate limits, and don’t hammer a site with palette checks in a loop. Specific legality questions get their own answer in the FAQ.

Step 1: Grab one color with the Chrome DevTools color picker

Open the page, press F12, and click the Inspect tool (or press Ctrl+Shift+C on Windows, Cmd+Shift+C on macOS). Hover elements until the one with the color you want is highlighted, then look at the Styles pane on the right. Every color value there renders a small swatch.

Click a swatch. A picker opens with an eyedropper that samples any pixel on the page, not just the selected element. The hex lands in your clipboard when you click. This is the only method here that reads rendered pixels, so it also works on colors inside photographs and canvas drawings.

What to watch for: the eyedropper samples anti-aliased edges too. If a picked hex looks slightly off from the brand color, you probably sampled the blend between a glyph and its background. Move half a pixel into a flat area and pick again. The limit is scope: one pixel says nothing about the rest of the system.

Step 2: Audit every color in the CSS Overview panel

For the full inventory, DevTools has a panel built for exactly this. Open DevTools, click the three-dot menu (Customize and control DevTools), choose More tools, then CSS Overview. Press Capture overview.

The Colors section lists every color in the page’s computed styles, grouped by role: background colors, text colors, border colors, and so on. Click any swatch and DevTools lists the elements that use it; hover an entry to highlight it on the page. The same report flags low-contrast text combinations, which matters if you plan to reuse the palette in your own UI.

The CSS Overview panel reads computed styles, so it sees colors from external stylesheets that the terminal methods below never touch. Two caveats. First, the counts include every gray in the design system, and there are always more grays than brand colors. Second, on single-page apps, re-capture after navigating, because the report is a snapshot of one rendered state.

Step 3: Extract colors from website CSS with one grep

When the browser gets in the way, go to the terminal. This is the whole scriptable method:

curl -sL https://linear.app -o linear.html
grep -oE '#[0-9a-fA-F]{3,8}' linear.html \
  | tr 'A-F' 'a-f' \
  | sort | uniq -c | sort -rn | head

Real output from that exact command, on a 1,256,592-byte copy of Linear’s homepage saved on 2026-10-16:

 429 #e2e4e7
 150 #e4e5e9
 147 #f79ce0
  89 #55cdff
  74 #9c9da1
  69 #08090a
  48 #fff
  42 #2e2e32

Two things this raw pass gives you that no GUI does. Frequency ranking comes free: the number in front of each hex is how many times it appears, which is a rough importance signal. And the net is wide: grep matches hex codes anywhere in the document, including SVG fill attributes and JSON blobs inside script tags, so it found 47 distinct colors in that file where a CSS-only scan found 23.

The blind spots are the price. grep '#…' never sees rgb(28, 133, 232), hsl() values, or named colors like rebeccapurple, and it never opens external stylesheets. If the page ships all its CSS in a linked bundle (Stripe does; I found zero hex colors in its style blocks and style attributes when I ran this), grep the bundle URLs too, or move to the next step. If curl returns a JavaScript shell with no styles at all, save the page from a real browser (Ctrl+S, “HTML only”) and grep that file instead.

Step 4: Extract color palette from website HTML in one command

The previous three methods answer “what colors does this page use”. A different question is “what is this brand’s surface”, and that includes fonts, the logo, and the favicon. Magpie, a local scraping CLI I work on, has a command that answers it with zero LLM calls and no API key:

git clone https://github.com/motherlodelab/magpie.git
cd magpie && go build -o magpie ./cmd/magpie
./magpie brand https://linear.app

Real output from 2026-10-16 (colors list abridged; the full run returned 23):

{
  "colors": ["#080808", "#191d20", "#1c85e8", "#27a644", "#585a5c",
             "#626366", "#6b6b6b", "#83dcdc", "..."],
  "fonts": ["var(--font-monospace)"],
  "logo": "https://linear.app/api/og/main?title=Linear&v=4",
  "favicon": "https://linear.app/favicon.ico?v=2",
  "title": "Linear – The system for product development",
  "final_url": "https://linear.app"
}

How it works matters for trusting it: the command scans <style> blocks and inline style attributes in the fetched HTML, lowercases and deduplicates every hex it finds, and reads font-family declarations the same way. Values come back verbatim, so Linear’s only font entry is the CSS variable var(--font-monospace); treat that as a pointer, not a font name. Logo resolution follows img[src*="logo"], then inline SVG logo classes, then falls back to the og:image. Because the output is deterministic JSON, you can diff two runs in git and see exactly when a site’s palette changed.

Now the honest limits, all hit during today’s testing:

  • External stylesheets are not fetched. Pages that ship all CSS in linked bundles come back with "colors": null. Stripe’s homepage did exactly that.
  • The fetch is static. Styles injected by JavaScript at runtime don’t exist in the raw HTML, so heavily client-rendered pages look colorless.
  • Old HTML color attributes are invisible. Hacker News paints its famous orange with bgcolor="#ff6600" in the markup, twice. magpie brand on news.ycombinator.com returns no colors, while the grep method catches it immediately.
  • Thin or JS-shell pages refuse rather than lie. vercel.com and allbirds.com both returned Error: quality blocked (empty) on 2026-10-16. I prefer that to a junk palette, but it means some pages need the browser methods from Steps 1 and 2.
  • No frequency ranking. Colors come back sorted alphabetically, not by how often they’re used, so the list alone doesn’t tell you which hex is “the” brand color. Step 5 fixes that.

Magpie is dual-licensed (AGPL-3.0-or-later or commercial), runs as one static binary, and the same extraction is available to AI agents over its MCP server. If your goal is a reusable pipeline rather than a one-off look, that shape fits; the trade-off is on the page above, not hidden in a footnote.

Step 5: Get brand colors from a website without counting grays

Every method so far returns soup, because design systems use far more structural gray than brand color. On Linear’s homepage the most frequent hex was #e2e4e7 at 429 occurrences: a border gray, not a brand statement. Frequency alone gets brand colors wrong more often than right.

Three filters, in the order I apply them:

  1. Drop the neutrals. Anything near #fff, #000, #111, or with roughly equal RGB channels (grays) is structure, not identity. On Linear’s file that removes about half the 47 candidates immediately.
  2. Prefer named tokens over raw hex. Sites define their real palette in CSS custom properties, and the variable names tell you the intent. Linear’s inline styles carry 57 hex-valued custom-property declarations; filtering names down to color, brand, or accent still leaves 48, including --accent:#FFEBC6 and --diff-new-color:#27A644. Grep for them: grep -oE '\-\-[a-z0-9-]*(color|brand|accent)[a-z0-9-]*:\s*#[0-9a-fA-F]{3,8}' linear.html. A variable named accent beats a hex that merely appears often.
  3. Check the logo. The brand’s own mark is the one element guaranteed to carry identity colors. Fetch the logo URL magpie brand reports, and if it’s an SVG, read its fill attributes directly.

After those filters on Linear’s file, the plausible brand set is short: one blue, one green, one pink, one yellow, plus near-black. That is a palette you can actually use, and it took two greps.

Make it stick

Watch for redesigns. Because magpie brand output is stable JSON, a cron job plus git diff turns palette checking into a changelog. Run it weekly per competitor; a new hex in the diff is a redesign signal weeks before a press release. The broader setup lives in the competitor website monitoring guide.

Test contrast before you reuse. A palette copied from a marketing hero often fails WCAG for body text; marketing pages put cream on white because it photographs well, not because it reads well. Check text/background pairs against the 4.5:1 threshold (WebAIM’s contrast checker is the fastest way), and remember the CSS Overview panel already flags low-contrast pairs on the source page.

Mine the tokens, not just the colors. Fonts came back alongside colors for a reason: a brand surface is type plus color. The same token-hunting logic works for other structured facts on the page, from JSON-LD schema to text extraction, and the underlying selector mechanics are the ones compared in LLM extraction versus CSS selectors.

FAQ

How do I find the exact hex codes a website uses? Open DevTools, run the CSS Overview panel (More tools → CSS Overview → Capture overview). It lists every color in computed styles; click a swatch to see which elements use it. For a scriptable list, curl the page and grep for hex patterns.

How do I copy a color from an image on a website? Use the DevTools eyedropper: click any color swatch in the Styles pane and sample the image pixel directly. It reads rendered pixels, so photographs and canvas work. No other method in this guide sees inside images.

Why don’t the extracted colors match the brand’s official palette? Marketing pages render dozens of structural grays and one-off tints, so raw extraction over-represents neutrals. Filter them out, prefer CSS variables named like --accent or --brand, and cross-check the logo’s SVG fill. For the official set, look for a brand or press page first.

Is it legal to extract colors from a website? Hex values are facts, and facts aren’t copyrightable; reading public CSS is what browsers do. This is not legal advice, but palette extraction sits at the harmless end of scraping. Respect robots.txt and terms of service, don’t overload servers, and never copy a trademarked logo into your own branding.

Does this work on sites that require JavaScript? Partially. The browser methods (eyedropper, CSS Overview) see the fully rendered page, so they always work. Terminal methods read raw HTML and miss JS-injected styles; on those pages, save the rendered page from the browser and grep the saved file, or use a scraper that renders JavaScript.

Start with the CSS Overview panel on a page you admire today; it needs no install and no code. When you want the same data arriving as JSON on a schedule, that’s the moment to clone Magpie and put brand in a cron job.

Stop renting credits.

One flat price, your machine, your keys.

Download free for Windows, macOS and Linux

Windows · macOS · Linux $49/mo flat, cancel anytime