Reference

CSS Color Formats Reference: Hex, RGB, HSL, HWB, Lab, LCH, OKLCH

CSS now offers more than ten ways to write the same color. The choice matters: some formats are easier to author by hand, some are perceptually uniform, and some unlock wider gamuts. This reference shows one color in every format, plus the hex notations you meet outside CSS.

Last reviewed on 2026-10-03

The official list

The formats are defined by the W3C's CSS Color Module Level 4: named colors, hex notation, rgb()/rgba(), hsl()/hsla(), hwb(), lab(), lch(), oklab(), oklch(), and color(), plus keywords like transparent and currentColor. CSS Color Module Level 5 adds color-mix() and relative color syntax. MDN's <color> reference page documents the same list with browser support data. Every format describes an sRGB color unless it explicitly names another space (Lab, OKLab, Display P3, Rec. 2020, and so on).

Why so many formats exist

For most of CSS's history there was one practical color format — hexadecimal — and one alternative — rgb(). Both describe a point inside the sRGB cube, the standard color space for web monitors. They worked because monitors were uniform and the cube was small.

Two things changed. Modern displays can show colors outside sRGB (the wider Display P3 and Rec. 2020 gamuts). And designers grew tired of color systems that behave inconsistently — increasing "lightness" by 10 produces very different-looking jumps depending on the hue. The answer was to import color spaces that have been used in print and color science for decades, and to give CSS a syntax for any of them.

The result: a richer toolbox. The converter on the home page produces the four most common formats (HEX, RGB, HSL, RGBA) for fast everyday work; this page covers everything else.

The classics

Hexadecimal — #RRGGBB

color: #6C5CE7;
color: #6c5ce7e6;   /* with 8-digit alpha */
color: #f00;        /* shorthand expands to #ff0000 */

Compact, ubiquitous, and the lingua franca of design tools. Best for: pasting one specific color out of a mockup. Worst for: reasoning about relationships between colors. The named colors index is essentially a hex lookup table.

8-digit hex and alpha — #RRGGBBAA

color: #6C5CE7FF;   /* opaque, same as #6C5CE7 */
color: #6C5CE7E6;   /* E6 = 230/255 ≈ 0.90 alpha */
color: #6C5CE780;   /* 80 = 128/255 ≈ 0.50 alpha */
color: #F008;       /* 4-digit #RGBA → #FF000088 */

CSS appends alpha as the last two digits. To convert an alpha value: hex pair → decimal → divide by 255. Going the other way, 0.5 × 255 = 127.5, which rounds to 128 = 80. Watch out when copying from Android or .NET, which put alpha first (see hex outside CSS below). Full opacity math is in the RGBA guide.

RGB — rgb()

color: rgb(108, 92, 231);
color: rgb(108 92 231);          /* modern: spaces, no commas */
color: rgb(108 92 231 / 0.4);    /* with alpha via slash */
color: rgb(42.35% 36.08% 90.59%); /* percentages also valid */

Same color cube as hex, written in decimal. Useful when integrating with code that already speaks 0–255 channels (canvas, image processing). The rgba() function still works for backwards compatibility but the modern rgb(r g b / α) form makes it redundant — and more on alpha is in the RGBA & transparency guide. Need the reverse direction? The RGB to HEX converter handles it.

HSL — hsl()

color: hsl(246.9, 74.3%, 63.3%);
color: hsl(246.9 74.3% 63.3%);
color: hsl(246.9deg 74.3% 63.3% / 0.4);

Hue (degrees), saturation (%), lightness (%). Far easier than hex for adjusting brightness or building a scale. Not perceptually uniform — the HSL guide explains the trade-offs. Note that whole-number HSL is lossy: hsl(247 74% 63%) resolves to #6B5BE6, one step off #6C5CE7 on every channel; keep a decimal if the exact hex matters.

HWB — hwb()

color: hwb(246.9 36.1% 9.4%);   /* hue, whiteness, blackness */

A lesser-known cousin of HSL: hue plus the percentage of white and the percentage of black mixed in. Some artists find it more intuitive than HSL for tints and shades because adding white is literally adding white. Browser support is now broad. Niche choice — useful when you're thinking like a painter.

Perceptually uniform formats

Lab — lab()

color: lab(46.78% 35.35 -69.88);

Lightness (0–100%), a axis (green to red), b axis (blue to yellow). A perceptual color space derived from CIELAB. Equal numeric distances in lab() correspond approximately to equal perceived differences — the property HSL lacks. Best for color comparisons and scientific work, but rarely used by hand because the a/b axes aren't intuitive.

LCH — lch()

color: lch(46.78% 78.31 296.84);   /* lightness, chroma, hue */

The polar form of Lab. Same perceptual basis, but expressed as lightness + chroma (saturation analogue) + hue (degrees) — much closer to how designers think. Better than HSL for color systems where steps need to feel even.

OKLab and OKLCH — oklab(), oklch()

color: oklch(56.76% 0.2021 283.08);
color: oklab(56.76% 0.0457 -0.1968);

Refinements of Lab and LCH that fix known issues with hue uniformity at the blue end of the spectrum. oklch() is the format design-system maintainers reach for in 2026 — perceptually uniform, intuitive axes, and supported across every modern browser. If you're building a color scale for a serious product, this is the default to pick.

The color() function

color: color(srgb 0.4235 0.3608 0.9059);         /* exactly #6C5CE7 */
color: color(srgb-linear 0.15 0.107 0.7991);     /* same color, linear light */
color: color(display-p3 0.4134 0.3631 0.8744);   /* same color, P3 coordinates */
color: color(display-p3 0.4 0.3 1);              /* a more vivid violet outside sRGB */

The escape hatch into wider color spaces. color() takes an explicit color-space identifier and channel values. Wide-gamut spaces (display-p3, rec2020) can express vivid greens and reds that sRGB-only formats cannot. On a monitor that supports them, the difference is real; on an sRGB-only monitor the browser falls back to the closest in-gamut match.

Named colors and keywords

color: rebeccapurple;
color: transparent;
color: currentColor;

The 140+ named CSS colors are documented and clickable in the CSS named colors index. A handful of keywords are not part of the named-color list but behave like colors:

One color in every format

Here is #6C5CE7 (the hexrgb.com violet) written every way CSS and common tools accept. All values are computed with the CSS Color 4 conversion matrices (Lab/LCH use the D50 white point, as CSS does) and rounded; every row describes the same color.

FormatValue
Hex#6C5CE7 / #6c5ce7
Hex with alpha#6C5CE7FF
RGBrgb(108 92 231)
RGB percentagesrgb(42.35% 36.08% 90.59%)
HSLhsl(246.9 74.3% 63.3%)
HWBhwb(246.9 36.1% 9.4%)
Lablab(46.78% 35.35 -69.88)
LCHlch(46.78% 78.31 296.84)
OKLaboklab(56.76% 0.0457 -0.1968)
OKLCHoklch(56.76% 0.2021 283.08)
color() sRGBcolor(srgb 0.4235 0.3608 0.9059)
color() linear sRGBcolor(srgb-linear 0.15 0.107 0.7991)
color() Display P3color(display-p3 0.4134 0.3631 0.8744)
Normalized RGB (0–1)0.4235, 0.3608, 0.9059
Integer / 0x literal0x6C5CE7 = 7101671
ARGB (Android, .NET)0xFF6C5CE7
BGR (Windows COLORREF, VB)&H00E75C6C

Paste any hex into the converter to get the everyday formats instantly.

Hex to RGB 0–1 (normalized float RGB)

Shaders (GLSL, HLSL), game engines (Unity's Color), Apple's UIColor/Color, and the Figma plugin API describe colors as floats from 0 to 1 instead of 0–255 integers. The conversion is a division:

normalized = channel / 255
channel    = round(normalized × 255)

Worked example: #2069E8.

R: 0x20 =  32 →  32 / 255 = 0.1255
G: 0x69 = 105 → 105 / 255 = 0.4118
B: 0xE8 = 232 → 232 / 255 = 0.9098

GLSL:   vec3(0.1255, 0.4118, 0.9098)
Unity:  new Color(0.1255f, 0.4118f, 0.9098f)
Swift:  UIColor(red: 0.1255, green: 0.4118, blue: 0.9098, alpha: 1)
Figma:  { r: 0.1255, g: 0.4118, b: 0.9098 }
CSS:    color(srgb 0.1255 0.4118 0.9098)

Divide by 255, not 256: 255 must map to exactly 1.0. Four decimal places are enough to round-trip any 8-bit value.

sRGB vs linear. Dividing by 255 gives gamma-encoded sRGB values, the "base RGB" that design tools and CSS use. Lighting and blending math in a linear-color pipeline expects linear values, which are obtained by applying the sRGB transfer curve: for #2069E8 they are about 0.0144, 0.1413, 0.8070. Engines usually convert for you when a color is flagged as sRGB; if you type linear values into an sRGB field (or vice versa), the color will look washed out or too dark.

Hex color notations outside CSS

The same six hex digits appear in many languages with different prefixes, and some systems change the byte order. Always establish which order you are reading before converting.

NotationWhere you see itByte order
#RRGGBB, #RRGGBBAACSS, SVG, design toolsRGB, alpha last
0xRRGGBBJavaScript, C, Python, Three.js, game codeRGB
0xAARRGGBBAndroid Color ints, .NET Color.FromArgb, many graphics APIsAlpha first, then RGB
&H00BBGGRRWindows COLORREF, Visual Basic / VBA, Excel's RGB() resultBGR (reversed)
&HAABBGGRRAdvanced SubStation Alpha (.ass) subtitlesBGR, alpha first and inverted (00 = opaque)
16#…PLC languages (IEC 61131-3 Structured Text)Just a base-16 number

0xRRGGBB — hex integer literals

0x6C5CE7 is the same digits as #6C5CE7, written as a number (7101671 in decimal). Libraries such as Three.js accept it directly: new THREE.Color(0x6C5CE7). To produce CSS, format it as six hex digits with leading zeros: '#' + n.toString(16).padStart(6, '0').

0xAARRGGBB — ARGB (Android, .NET)

Example: 0xFF90BE6D. Split it into bytes: FF | 90 BE 6D. The first byte is alpha (FF = fully opaque), the rest is RGB. CSS equivalent: #90BE6D, or #90BE6DFF with explicit alpha — note the alpha moves from the front to the back. 0x8090BE6D would be the same green at 128/255 ≈ 50% opacity: #90BE6D80.

&H00BBGGRR — BGR (Windows, Visual Basic)

Windows COLORREF values and Visual Basic colors store red in the lowest byte, so the hex reads backwards. &H is VB's hex prefix and a trailing & marks a Long.

Example: &H00C0C0FF&. Drop the prefix and suffix → 00C0C0FF. Bytes: 00 (unused) | BB = C0 | GG = C0 | RR = FF. So red = 255, green = 192, blue = 192 → #FFC0C0, a light pink. Reading it naively as RGB would give #C0C0FF, a lavender — the classic mistake. Likewise VBA's RGB(108, 92, 231) returns &HE75C6C, not &H6C5CE7.

Subtitle files in .ass format use the same BGR order, with an optional alpha byte in front where 00 means opaque and FF transparent — the opposite of CSS.

16# — PLC radix notation

In IEC 61131-3 languages, 16# means "base 16" (2# is binary, 8# octal). 16#4BC is simply the number 0x4BC = 1212 decimal. If that number is a 24-bit color register, pad it to six digits: 16#0004BC → #0004BC, a very dark blue. It is not the CSS shorthand #4BC (which expands to #44BBCC) unless the device documentation explicitly says it uses 4-bit-per-channel color. Check the register's byte order too; some HMIs store BGR.

Choosing a format

If you're…PickWhy
Pasting one color out of FigmaHEXUniversal, terse, exactly what design tools export.
Tweaking brightness or building a small scale by handHSLLightness slider you can adjust in your head.
Building a serious design-system color scaleOKLCHPerceptually uniform; even-looking steps.
Adding a translucent overlayRGBA or 8-digit hexDirect alpha control; see the RGBA guide.
Targeting wide-gamut displayscolor(display-p3 …)Only way to express colors outside sRGB.
Inheriting from the surrounding text colorcurrentColorAdapts automatically to theme changes.
Matching the user's system themeSystem color keywordsBrowser handles light/dark switching.

Modern syntax conventions

Across all the function-style formats, modern CSS prefers spaces over commas, and a slash separator for alpha:

/* old, still valid */
rgb(108, 92, 231)
rgba(108, 92, 231, 0.4)
hsl(245, 75%, 63%)
hsla(245, 75%, 63%, 0.4)

/* modern */
rgb(108 92 231)
rgb(108 92 231 / 0.4)
hsl(245 75% 63%)
hsl(245 75% 63% / 0.4)

Pick one style per codebase. Mixing them works but reads like inconsistent code.

Color-mix and relative color syntax

/* mix two colors */
background: color-mix(in oklch, #6C5CE7 60%, white);

/* derive a color from another */
border-color: hsl(from var(--brand) h s calc(l - 12%));

color-mix() blends two colors in a chosen color space, removing a common reason to commit pre-mixed tints to the codebase. Relative color syntax (hsl(from … ), oklch(from … )) takes an existing color and tweaks one channel — perfect for hover states and theming. Both are now widely supported and especially useful when paired with CSS custom properties.

color-mix() in detail

color-mix(in srgb, #6C5CE7, white)          /* 50/50 → rgb(181.5 173.5 243) */
color-mix(in srgb, #6C5CE7 25%, transparent) /* 25% opacity tint of the brand */
color-mix(in oklch, #6C5CE7 60%, white)      /* perceptual mix, keeps the hue vivid */

The first argument picks the interpolation space. srgb mixes channel by channel: (108 + 255) / 2 = 181.5, (92 + 255) / 2 = 173.5, (231 + 255) / 2 = 243. oklch or oklab usually give more even-looking tints and avoid the grayish midpoint that sRGB mixes produce between distant hues. Percentages that don't add up to 100% are normalized; if they sum to less than 100%, the result becomes partly transparent.

Relative color syntax in detail

rgb(from #6C5CE7 r g b / 50%)                  /* same color, 50% alpha */
hsl(from var(--brand) calc(h + 180) s l)       /* the complementary hue */
oklch(from var(--brand) calc(l - 0.1) c h)     /* a darker hover shade */
oklch(from var(--brand) l 0 h)                 /* a neutral gray at the same lightness */

After from, the origin color is converted to the function's color space and its channels become keywords (r g b, h s l, l c h, plus alpha). In rgb(from …), r g b are numbers from 0 to 255; in oklch(from …), l is a number from 0 to 1. Hue math such as calc(h + 180) wraps automatically, which makes relative syntax a direct way to build the color harmony schemes in CSS.

Gamut, fallbacks, and graceful degradation

Wide-gamut formats can describe colors a sRGB-only monitor cannot show. The browser handles this by mapping the requested color into the destination gamut. The result is usually visually close, but if you depend on the exact wide-gamut value, supply a fallback:

.brand {
  color: #6C5CE7;                                /* sRGB fallback */
  color: color(display-p3 0.4 0.3 1);            /* wider gamut, more vivid */
}

Browsers that don't recognise the second declaration ignore it and use the first. Browsers that do recognise it apply the wider color where the display can show it.

A common-mistakes section

Quick reference

Frequently asked questions

What color formats does CSS support?

CSS Color Module Level 4 defines named colors, hex notation (#RGB, #RGBA, #RRGGBB, #RRGGBBAA), rgb(), hsl(), hwb(), lab(), lch(), oklab(), oklch() and the color() function for spaces such as srgb, srgb-linear, display-p3 and rec2020. Level 5 adds color-mix() and relative color syntax. MDN documents all of them under the CSS color value page.

What is 8-digit hex color in CSS?

An 8-digit hex color is #RRGGBBAA: the usual six digits followed by two alpha digits from 00 (transparent) to FF (opaque). #6C5CE7E6 is #6C5CE7 at 230/255 ≈ 90% opacity. The 4-digit #RGBA shorthand works the same way. Note that Android and .NET put alpha first (AARRGGBB).

How do I convert hex to RGB 0–1 values?

Convert each two-digit pair to decimal and divide by 255. For #2069E8: 0x20 = 32, 0x69 = 105, 0xE8 = 232, so the normalized RGB is 32/255 ≈ 0.1255, 105/255 ≈ 0.4118 and 232/255 ≈ 0.9098. To go back, multiply by 255 and round.

What does &H00C0C0FF& mean as a color?

It is a Windows/Visual Basic style color in &H00BBGGRR order (the trailing & is VB's Long type suffix; .ass subtitle color tags use a similar &H…& form). Reading the bytes BB=C0, GG=C0, RR=FF gives red 255, green 192, blue 192, which is #FFC0C0 in CSS, a light pink.

How do I convert 0xFF90BE6D to a CSS color?

0xFF90BE6D is a 32-bit ARGB integer as used by Android and .NET. The first byte FF is alpha (fully opaque) and the rest is the RGB value, so the CSS equivalent is #90BE6D, or #90BE6DFF with explicit alpha, which is rgb(144 190 109).

What does 16#4BC mean?

16# is the IEC 61131-3 radix prefix used in PLC languages such as Structured Text, so 16#4BC is the hexadecimal number 4BC, which is 1212 in decimal. As a 24-bit color value it would be 16#0004BC, CSS #0004BC; it is only #44BBCC if a system explicitly treats three hex digits as CSS-style shorthand.

Is CSS hex color sRGB?

Yes. Hex notation, rgb(), hsl() and hwb() all describe colors in the sRGB color space with gamma-encoded channels. #6C5CE7 is exactly color(srgb 0.4235 0.3608 0.9059). Linear-light values, as used in shader lighting math, are different: color(srgb-linear 0.15 0.107 0.7991).

What is relative color syntax in CSS?

Relative color syntax creates a new color from an existing one: rgb(from #6C5CE7 r g b / 50%) keeps the channels and sets alpha to 50%, and oklch(from var(--brand) calc(l - 0.1) c h) produces a darker shade of the same hue. Inside the function, the channel names refer to the origin color's values in that color space.