If you've ever pasted a HEX code from a design file into CSS and gotten a slightly different-looking RGB value, or wondered whether your white text on a purple button passes accessibility guidelines, this guide walks through the actual math — and how to skip it with a free converter.
#7C3AED splits into three two-character (base-16) blocks — RR, GG, BB — each converted to a base-10 number from 0–255. 7C=124, 3A=58, ED=237 gives rgb(124, 58, 237), which is hsl(262, 83%, 58%) in the HSL model.HEX and RGB describe the exact same underlying color — they're just two different notations for the same three light-intensity values. HEX is compact and common in design tools and stylesheets; RGB spells out the same numbers in decimal, which is often what a canvas API, image-editing tool, or older CSS property expects. HSL, meanwhile, reorganizes those same values around how people actually think about color: a hue on the wheel, how saturated it is, and how light or dark it is. That's why designers often prefer nudging the "L" value up or down to get a lighter or darker version of a brand color, rather than guessing new RGB numbers.
#F0A is expanded by doubling each digit: F→FF, 0→00, A→AA, giving #FF00AA. This is common in hand-written CSS but not in design-tool exports.| Format | Example value | Typical use |
|---|---|---|
| HEX | #7C3AED | CSS, design tools, brand guides |
| RGB | rgb(124, 58, 237) | Canvas/image APIs, legacy CSS |
| HSL | hsl(262, 83%, 58%) | Tweaking lightness/saturation by hand |
| CMYK (approx.) | C48 M76 Y0 K7 | Rough print reference (not exact) |
Say you're matching a competitor's button color from a screenshot. You sample the pixel and get rgb(124, 58, 237) from an image tool, but your CSS file uses HEX everywhere else for consistency. Rather than converting by hand, a converter that keeps every format in sync — HEX, RGB, HSL, HSV, and CMYK — lets you paste in whichever one you have and read off the rest instantly.
This isn't a cosmetic nice-to-have — it's the difference between text that's genuinely readable and text that fails for anyone with low vision, color-blindness, or simply a phone screen in bright sunlight. The math itself linearizes each color's red, green, and blue channels, weights them (green contributes most to perceived brightness, blue the least), and sums them into a single luminance value. The ratio is then just (L1 + 0.05) / (L2 + 0.05) using the lighter and darker of the two luminances.
#FFFFFF) on the purple #7C3AED button used throughout this guide comes out around 4.6:1 — just over the AA threshold for normal text, but short of the 7:1 needed for AAA. Darkening the purple slightly, or using it only for large headings, would push it comfortably past AAA.A practical workflow: pick your two colors (text and background), paste them into a contrast checker, and look at the live preview alongside the pass/fail badges for AA and AAA at both text sizes. If a combination fails, try adjusting only the lightness (L in HSL) of one color rather than the hue — that usually preserves your brand color while fixing contrast.
Say your brand color is a purple at hue 262°. Its complementary color sits at hue 82° — a yellow-green, giving you a natural accent for a single call-to-action button that needs to pop against a mostly-purple interface. An analog set (232°, 262°, 292°) stays close in hue for a homepage gradient or a set of category tags that should feel related but distinguishable. A triadic set (262°, 22°, 142°) works well for a small multi-series chart where you need a few colors that are clearly different but equally "loud."
Beyond the wheel-based palettes, a lightness ramp — the same hue and saturation stepped from very light to very dark — is what most modern design systems use for numbered scales (Tailwind's 50 through 950, for instance). Generating that scale automatically from one base color, and mapping your original color to its nearest step, saves the trial-and-error of picking ten shades by eye.
bg-[#7C3AED], a Swift UIColor initializer, an Android/Kotlin color int, or a Flutter Color() — each with slightly different syntax for the same RGB values.
This step is where manual conversion becomes tedious fast: Swift wants each channel as a 0–1 float, Android wants a single hexadecimal 0xAARRGGBB integer, and Flutter wraps that same integer in its own constructor. If your interface also supports transparency, the alpha channel needs to be folded into whichever format you're outputting — an 8-digit HEX, an RGBA decimal, or an ARGB integer — which is easy to get backwards by hand.
Pick a color once and get every format, contrast check, and palette instantly — no manual math, nothing leaves your browser.
Try the free Color Converter →