A color model is a mathematical system for describing colors as sets of numbers. In digital displays, colors are produced by combining light in various ways. Different color models offer different approaches to representing the same colors, each with its own strengths and use cases.
The three most common color models in web development are HEX, RGB, and HSL. While they can all represent the same set of colors (the sRGB color space, which covers the 16.7 million colors displayable by standard monitors), they differ significantly in how they express those colors. Understanding when to use each model -- and how to convert between them -- is a foundational skill for every front-end developer and designer.
HEX and RGB are closely related: HEX is simply the hexadecimal notation for the same Red-Green-Blue channel values that RGB uses in decimal. HSL, on the other hand, takes a fundamentally different approach by describing color in terms of Hue, Saturation, and Lightness -- dimensions that map more closely to how humans perceive and talk about color.
Beyond these three, modern CSS also supports newer color models like HWB (Hue, Whiteness, Blackness), LAB (Lightness, a-axis, b-axis), LCH (Lightness, Chroma, Hue), and OKLCH. These newer models offer perceptually uniform color spaces, meaning that equal numerical changes produce equal perceived differences in color. However, HEX, RGB, and HSL remain the most widely used formats, and understanding them is essential before exploring newer alternatives.
In this guide, we will explore each model in depth, walk through the conversion formulas, and show you how to use color effectively in your CSS and design systems.
HEX (hexadecimal) color codes are the most widely recognized color format on the web. A HEX color is written as a # symbol followed by six hexadecimal digits, where each pair of digits represents the intensity of the Red, Green, and Blue channels respectively.
The format is #RRGGBB, where each channel ranges from 00 (0, no intensity) to FF (255, full intensity):
#FF5733
^^ ^^ ^^
| | |
| | +-- Blue: 33 (hex) = 51 (decimal)
| +----- Green: 57 (hex) = 87 (decimal)
+-------- Red: FF (hex) = 255 (decimal)
This gives us rgb(255, 87, 51) -- a vivid reddish-orange color.
When each pair of digits consists of the same character repeated, you can use the 3-digit shorthand. The browser expands each digit by doubling it:
#F00 = #FF0000 (pure red)
#0F0 = #00FF00 (pure green)
#09C = #0099CC (teal blue)
#FFF = #FFFFFF (white)
#000 = #000000 (black)
Note that not all 6-digit codes have a valid 3-digit shorthand. #FF5733, for example, cannot be shortened because the pairs (FF, 57, 33) do not consist of repeated characters.
CSS also supports 8-digit HEX codes in the format #RRGGBBAA, where the last two digits represent the alpha (opacity) channel:
#FF573380 -- ~50% opacity (80 hex = 128 decimal = 128/255 = ~50%)
#FF5733FF -- 100% opacity (fully opaque)
#FF573300 -- 0% opacity (fully transparent)
#FF5733CC -- 80% opacity (CC hex = 204 decimal = 204/255 = ~80%)
There is also a 4-digit shorthand #RGBA that works the same way as the 3-digit shorthand but with an additional alpha digit: #F008 expands to #FF000088.
HEX codes became the dominant color format on the web for several historical reasons. They were supported from the earliest days of HTML and CSS. They are compact (6 characters to represent any color). They are easy to copy and paste from design tools like Photoshop, Figma, and Sketch. And they are case-insensitive: #ff5733, #FF5733, and #Ff5733 all represent the same color.
However, HEX codes have a significant disadvantage: they are not human-readable. Looking at #3B82F6, it is nearly impossible to intuitively know that it is a medium blue. You cannot easily create color variations (lighter, darker, more saturated) by adjusting HEX values mentally. This is where HSL shines.
The RGB color model directly represents the additive color mixing that happens in digital displays. Every pixel on your screen is composed of three tiny sub-pixels -- one red, one green, and one blue. By varying the intensity of each sub-pixel, the display can produce any color in the sRGB gamut.
CSS provides the rgb() function to specify colors using decimal values:
/* Legacy syntax (commas) */
rgb(255, 87, 51)
rgba(255, 87, 51, 0.5)
/* Modern syntax (spaces, optional slash for alpha) */
rgb(255 87 51)
rgb(255 87 51 / 50%)
rgb(255 87 51 / 0.5)
Each channel accepts a value from 0 to 255 (integer) or 0% to 100% (percentage). The alpha value can be a number from 0 to 1 or a percentage from 0% to 100%.
In additive color mixing, combining light of different colors produces new colors. This is different from the subtractive mixing you may remember from mixing paints:
Red + Green = Yellow rgb(255, 255, 0)
Red + Blue = Magenta rgb(255, 0, 255)
Green + Blue = Cyan rgb(0, 255, 255)
Red + Green + Blue = White rgb(255, 255, 255)
No light = Black rgb(0, 0, 0)
When all three channels have equal values, you get a shade of gray. rgb(128, 128, 128) is medium gray, rgb(200, 200, 200) is light gray, and rgb(50, 50, 50) is dark gray.
Each channel ranges from 0 (no contribution of that color) to 255 (maximum contribution). The total number of possible colors is 256 x 256 x 256 = 16,777,216 -- commonly referred to as "16.7 million colors" or "24-bit color" (since 8 bits per channel x 3 channels = 24 bits total).
RGB is useful when you are working with pixel-level operations, image processing, or canvas drawing. JavaScript's Canvas API returns pixel data as RGBA arrays, and WebGL shaders operate on RGB color values. If you are programmatically manipulating individual color channels -- for instance, increasing the red component of every pixel in an image -- RGB is the natural choice.
RGB is also the model that most closely matches how computers and displays actually work. When you need to communicate color values to a graphics API, shader, or low-level rendering system, RGB is typically the expected format.
HSL stands for Hue, Saturation, and Lightness. Unlike RGB and HEX, which describe colors in terms of the physical mechanism used to display them (mixing red, green, and blue light), HSL describes colors in terms that align with human perception. This makes HSL far more intuitive for designers and developers who need to create, adjust, and reason about colors.
Hue (0-360): The position on the color wheel, measured in degrees. Think of it as a circle where colors transition smoothly:
0 / 360 = Red
30 = Orange
60 = Yellow
120 = Green
180 = Cyan
240 = Blue
270 = Purple
300 = Magenta / Pink
330 = Rose
Saturation (0%-100%): How vivid or pure the color is. 100% saturation gives the most vivid version of a hue. 0% saturation removes all color, producing a shade of gray (regardless of the hue value). Think of saturation as how much "gray" is mixed into the color.
Lightness (0%-100%): How much light is in the color. 0% lightness is always black. 100% lightness is always white. 50% lightness gives the purest, most vivid version of the color at the given saturation. Think of lightness as a slider between black and white, with the full color in the middle.
/* Legacy syntax */
hsl(11, 100%, 60%)
hsla(11, 100%, 60%, 0.5)
/* Modern syntax */
hsl(11 100% 60%)
hsl(11 100% 60% / 50%)
hsl(11 100% 60% / 0.5)
The power of HSL becomes clear when you need to create color variations. Consider building a button with normal, hover, and active states:
/* With HSL, creating variations is intuitive */
.button {
--hue: 220;
background: hsl(var(--hue), 90%, 52%); /* Normal */
}
.button:hover {
background: hsl(var(--hue), 90%, 58%); /* Lighter */
}
.button:active {
background: hsl(var(--hue), 90%, 44%); /* Darker */
}
.button:disabled {
background: hsl(var(--hue), 20%, 72%); /* Desaturated */
}
With HEX or RGB, achieving the same effect requires complex calculations or a color manipulation library. With HSL, you simply adjust one number.
HSL also makes it trivial to generate harmonious color palettes. Complementary colors are 180 degrees apart on the hue wheel. Analogous colors are 30 degrees apart. Triadic colors are 120 degrees apart. You can create an entire color scheme by keeping saturation and lightness constant and rotating the hue:
/* Triadic color scheme */
--color-1: hsl(220, 80%, 55%); /* Blue */
--color-2: hsl(340, 80%, 55%); /* Rose */
--color-3: hsl(100, 80%, 55%); /* Green */
/* Analogous color scheme */
--color-1: hsl(200, 75%, 50%); /* Blue */
--color-2: hsl(230, 75%, 50%); /* Indigo */
--color-3: hsl(170, 75%, 50%); /* Teal */
Understanding the math behind color conversions helps you write your own converter functions and debug issues when colors do not look right. Here are the key conversion algorithms.
This is the simplest conversion because HEX is just a different notation for the same RGB values. Split the 6-character hex string into three 2-character pairs and convert each from base-16 to base-10:
function hexToRgb(hex) {
// Remove the # if present
hex = hex.replace(/^#/, '');
// Handle shorthand (#RGB -> #RRGGBB)
if (hex.length === 3) {
hex = hex[0] + hex[0] + hex[1] + hex[1] + hex[2] + hex[2];
}
const r = parseInt(hex.substring(0, 2), 16);
const g = parseInt(hex.substring(2, 4), 16);
const b = parseInt(hex.substring(4, 6), 16);
return { r, g, b };
}
// Example: hexToRgb('#FF5733') => { r: 255, g: 87, b: 51 }
The reverse is equally straightforward. Convert each decimal channel value to a 2-digit hexadecimal string:
function rgbToHex(r, g, b) {
const toHex = (n) => {
const hex = Math.max(0, Math.min(255, n)).toString(16);
return hex.length === 1 ? '0' + hex : hex;
};
return '#' + toHex(r) + toHex(g) + toHex(b);
}
// Example: rgbToHex(255, 87, 51) => '#ff5733'
Converting from RGB to HSL requires more computation. The algorithm normalizes the RGB values to 0-1 range, finds the maximum and minimum channel values, then computes lightness, saturation, and hue:
function rgbToHsl(r, g, b) {
r /= 255;
g /= 255;
b /= 255;
const max = Math.max(r, g, b);
const min = Math.min(r, g, b);
const delta = max - min;
let h, s;
const l = (max + min) / 2;
if (delta === 0) {
h = 0;
s = 0; // achromatic (gray)
} else {
s = l > 0.5
? delta / (2 - max - min)
: delta / (max + min);
switch (max) {
case r:
h = ((g - b) / delta + (g < b ? 6 : 0)) / 6;
break;
case g:
h = ((b - r) / delta + 2) / 6;
break;
case b:
h = ((r - g) / delta + 4) / 6;
break;
}
}
return {
h: Math.round(h * 360),
s: Math.round(s * 100),
l: Math.round(l * 100)
};
}
// Example: rgbToHsl(255, 87, 51) => { h: 11, s: 100, l: 60 }
The reverse conversion uses a helper function to compute each RGB channel from the intermediate values:
function hslToRgb(h, s, l) {
s /= 100;
l /= 100;
const c = (1 - Math.abs(2 * l - 1)) * s;
const x = c * (1 - Math.abs((h / 60) % 2 - 1));
const m = l - c / 2;
let r, g, b;
if (h < 60) { r = c; g = x; b = 0; }
else if (h < 120) { r = x; g = c; b = 0; }
else if (h < 180) { r = 0; g = c; b = x; }
else if (h < 240) { r = 0; g = x; b = c; }
else if (h < 300) { r = x; g = 0; b = c; }
else { r = c; g = 0; b = x; }
return {
r: Math.round((r + m) * 255),
g: Math.round((g + m) * 255),
b: Math.round((b + m) * 255)
};
}
// Example: hslToRgb(11, 100, 60) => { r: 255, g: 87, b: 51 }
There is no direct formula for HEX-to-HSL conversion. Instead, you chain the conversions: HEX to RGB, then RGB to HSL. The same applies in reverse: HSL to RGB, then RGB to HEX.
// HEX -> HSL: chain hexToRgb() then rgbToHsl()
function hexToHsl(hex) {
const { r, g, b } = hexToRgb(hex);
return rgbToHsl(r, g, b);
}
// HSL -> HEX: chain hslToRgb() then rgbToHex()
function hslToHex(h, s, l) {
const { r, g, b } = hslToRgb(h, s, l);
return rgbToHex(r, g, b);
}
Color conversions involving HSL can introduce rounding errors. Converting from HEX to HSL and back may not always yield the exact same HEX code, because the intermediate HSL values are rounded to integers. For most practical purposes, the difference is imperceptible (off by 1 in one RGB channel at most), but it is worth knowing if you need exact round-trip fidelity.
CSS has evolved significantly in how it handles colors. Understanding the available options helps you choose the right format for each situation.
CSS defines 140+ named colors, ranging from the obvious (red, blue, green) to the esoteric (papayawhip, blanchedalmond, rebeccapurple). Named colors are readable and memorable, but they offer limited precision. There is no named color for #3B82F6. Named colors work well for prototyping, placeholder content, and simple applications.
One of the most powerful patterns in modern CSS is combining custom properties (CSS variables) with HSL. This enables dynamic theming and easy color manipulation:
:root {
/* Define brand color as HSL components */
--brand-h: 220;
--brand-s: 90%;
--brand-l: 52%;
/* Generate palette from a single hue */
--brand-50: hsl(var(--brand-h), var(--brand-s), 97%);
--brand-100: hsl(var(--brand-h), var(--brand-s), 93%);
--brand-200: hsl(var(--brand-h), var(--brand-s), 86%);
--brand-300: hsl(var(--brand-h), var(--brand-s), 74%);
--brand-400: hsl(var(--brand-h), var(--brand-s), 64%);
--brand-500: hsl(var(--brand-h), var(--brand-s), var(--brand-l));
--brand-600: hsl(var(--brand-h), var(--brand-s), 44%);
--brand-700: hsl(var(--brand-h), var(--brand-s), 36%);
--brand-800: hsl(var(--brand-h), var(--brand-s), 28%);
--brand-900: hsl(var(--brand-h), var(--brand-s), 20%);
}
/* Dark mode: just adjust lightness and saturation */
[data-theme="dark"] {
--brand-s: 80%;
--brand-l: 60%;
}
By storing hue, saturation, and lightness as separate custom properties, you can create entire color scales and switch themes by changing just a few values.
currentcolor Keyword
CSS provides the currentcolor keyword, which resolves to the element's computed color property. This is incredibly useful for SVG icons and border colors that should match the text:
.icon-button {
color: hsl(220, 90%, 52%);
border: 2px solid currentcolor; /* Matches text color */
}
.icon-button svg {
fill: currentcolor; /* Icon matches text color */
}
.icon-button:hover {
color: hsl(220, 90%, 44%); /* Everything updates together */
}
CSS Color Level 4 introduces several new capabilities. The color-mix() function lets you blend two colors:
/* Mix 50% blue with 50% white */
background: color-mix(in srgb, #3B82F6 50%, white);
/* Mix 30% black into a color for a darker variant */
background: color-mix(in srgb, #3B82F6, black 30%);
The oklch() color space provides perceptually uniform colors, meaning equal changes in values produce equal perceived changes:
/* OKLCH: Lightness, Chroma, Hue */
color: oklch(0.65 0.2 250); /* A vibrant blue */
/* Create a palette with consistent perceived lightness */
--red: oklch(0.65 0.2 25);
--blue: oklch(0.65 0.2 250);
--green: oklch(0.65 0.2 145);
The relative color syntax allows you to derive new colors from existing ones by modifying individual components:
/* Lighten a color by 20% */
background: hsl(from var(--brand) h s calc(l + 20%));
/* Desaturate a color */
background: hsl(from var(--brand) h calc(s - 30%) l);
/* Change the hue to get a complementary color */
background: hsl(from var(--brand) calc(h + 180) s l);
You do not need to be a designer to understand the fundamentals of color theory. A few key concepts will dramatically improve your ability to choose effective color combinations.
The color wheel is a circular arrangement of colors based on their hue values. Primary colors (Red, Green, Blue in the RGB model) are evenly spaced at 0, 120, and 240 degrees. Secondary colors (Yellow, Cyan, Magenta) fall between the primaries. The color wheel is the foundation for understanding color relationships.
Color harmony refers to combinations of colors that are aesthetically pleasing. Here are the major harmony schemes, all easily calculated using HSL hue values:
Complementary: Two colors opposite each other on the wheel (180 degrees apart). High contrast, energetic. Example: blue (hsl(220, 80%, 50%)) and orange (hsl(40, 80%, 50%)).
Analogous: Three colors adjacent on the wheel (30 degrees apart). Harmonious, low contrast. Example: blue (hsl(220, 80%, 50%)), indigo (hsl(250, 80%, 50%)), teal (hsl(190, 80%, 50%)).
Triadic: Three colors evenly spaced (120 degrees apart). Vibrant, balanced. Example: red (hsl(0, 80%, 50%)), green (hsl(120, 80%, 50%)), blue (hsl(240, 80%, 50%)).
Split-Complementary: A base color and two colors adjacent to its complement (150 and 210 degrees from the base). Offers contrast without the tension of pure complementary. Example: blue (hsl(220, 80%, 50%)), yellow-orange (hsl(25, 80%, 50%)), red-orange (hsl(55, 80%, 50%)).
Tetradic (Rectangle): Four colors forming a rectangle on the wheel. Rich color schemes with plenty of variety. Works best when one color is dominant and the others are used as accents.
Colors with hue values from roughly 0 to 60 and 300 to 360 are considered warm (reds, oranges, yellows). Colors from 120 to 270 are cool (greens, blues, purples). Warm colors tend to advance (appear closer) and evoke energy, while cool colors tend to recede and evoke calm. Most effective designs use a dominant temperature with accents from the opposite side.
Colors carry psychological associations that influence user perception:
Red - Urgency, errors, danger, passion (delete buttons, error states)
Orange - Energy, warmth, warnings (warning banners, CTAs)
Yellow - Caution, optimism, attention (warning icons, highlights)
Green - Success, growth, safety (success states, "go" actions)
Blue - Trust, stability, calm (primary actions, links, corporate)
Purple - Luxury, creativity, wisdom (premium features)
Gray - Neutrality, professionalism (backgrounds, disabled states)
These associations are culturally influenced and not universal, but they provide a useful starting point for choosing semantic colors in your UI.
Color accessibility is not optional -- it is essential. Approximately 8% of men and 0.5% of women have some form of color vision deficiency (commonly called "color blindness"). Beyond that, everyone experiences situational impairments: using a phone in bright sunlight, viewing a projector in a lit room, or reading a screen with tired eyes.
The Web Content Accessibility Guidelines (WCAG) define specific contrast ratio requirements:
Level AA (minimum):
- Normal text (<18pt / <14pt bold): 4.5:1 contrast ratio
- Large text (≥18pt / ≥14pt bold): 3:1 contrast ratio
- UI components and graphical objects: 3:1 contrast ratio
Level AAA (enhanced):
- Normal text: 7:1 contrast ratio
- Large text: 4.5:1 contrast ratio
The contrast ratio is calculated from the relative luminance of two colors. The formula is:
Contrast Ratio = (L1 + 0.05) / (L2 + 0.05)
Where L1 is the relative luminance of the lighter color
and L2 is the relative luminance of the darker color.
Relative luminance for a color (R, G, B in 0-255):
1. Normalize: R' = R/255, G' = G/255, B' = B/255
2. Linearize: for each channel c:
if c <= 0.04045: c_lin = c / 12.92
else: c_lin = ((c + 0.055) / 1.055) ^ 2.4
3. L = 0.2126 * R_lin + 0.7152 * G_lin + 0.0722 * B_lin
Notice the weighted formula for luminance: green contributes the most (71.52%), red is next (21.26%), and blue contributes the least (7.22%). This reflects human vision, which is most sensitive to green light.
WCAG guideline 1.4.1 states that color must not be the only means of conveying information. For example:
The three most common types of color vision deficiency are:
Chrome DevTools has a built-in "Rendering" panel that can simulate these conditions. Firefox and Safari offer similar tools. Avoid red/green combinations as the sole differentiator in your UI -- use blue/orange as a more universally distinguishable alternative.
A well-structured color system is one of the most important foundations of a design system. It ensures visual consistency, makes theming possible, and helps developers make confident color choices.
Most design systems define a palette of color scales -- a range from very light to very dark for each hue. Tailwind CSS, for example, uses a 50-950 scale with 11 shades. Here is how you might generate a similar scale using HSL:
:root {
/* Blue scale */
--blue-50: hsl(214, 100%, 97%); /* Near-white blue tint */
--blue-100: hsl(214, 95%, 93%);
--blue-200: hsl(213, 97%, 87%);
--blue-300: hsl(212, 96%, 78%);
--blue-400: hsl(213, 94%, 68%);
--blue-500: hsl(217, 91%, 60%); /* Base color */
--blue-600: hsl(221, 83%, 53%);
--blue-700: hsl(224, 76%, 48%);
--blue-800: hsl(226, 71%, 40%);
--blue-900: hsl(224, 64%, 33%);
--blue-950: hsl(226, 57%, 21%); /* Near-black blue shade */
}
Notice that building a natural-looking scale is not as simple as linearly changing the lightness value. Real-world color scales also adjust saturation and sometimes even hue slightly across the range. The lighter shades tend to have higher saturation, and the hue may shift slightly (warmer in light shades, cooler in dark shades) to create a more natural progression.
Beyond raw color scales, design systems define semantic tokens that describe the purpose of a color rather than its visual appearance:
:root {
/* Semantic tokens reference the palette */
--color-bg-primary: var(--white);
--color-bg-secondary: var(--gray-50);
--color-text-primary: var(--gray-900);
--color-text-secondary: var(--gray-600);
--color-border: var(--gray-200);
--color-link: var(--blue-600);
--color-success: var(--green-600);
--color-warning: var(--amber-500);
--color-error: var(--red-600);
--color-info: var(--blue-500);
}
/* Dark theme: same semantic tokens, different values */
[data-theme="dark"] {
--color-bg-primary: var(--gray-950);
--color-bg-secondary: var(--gray-900);
--color-text-primary: var(--gray-50);
--color-text-secondary: var(--gray-400);
--color-border: var(--gray-700);
--color-link: var(--blue-400);
--color-success: var(--green-400);
--color-warning: var(--amber-400);
--color-error: var(--red-400);
--color-info: var(--blue-400);
}
This separation of palette from semantics is what makes theming possible. Components reference semantic tokens, and themes override the mapping from semantic tokens to palette values.
Your primary color is the most important color decision in your design system. Here are key considerations:
Here are practical recommendations for working with colors in web development projects.
Write your CSS using HSL because it is easier to create variations and reason about colors. But use HEX codes when communicating with designers, copying colors from design tools, or documenting colors in style guides -- HEX is the universal language of digital color.
Never hardcode color values throughout your stylesheets. Define them once as custom properties and reference them everywhere. This makes updates easy, enables theming, and provides a single source of truth:
/* Bad: hardcoded colors scattered everywhere */
.header { background: #3B82F6; }
.button { background: #3B82F6; }
.link { color: #3B82F6; }
/* Good: centralized color definitions */
:root { --primary: hsl(217, 91%, 60%); }
.header { background: var(--primary); }
.button { background: var(--primary); }
.link { color: var(--primary); }
A common mistake is using too many colors. Most effective interfaces use:
That is typically 4-5 hues total, each with a scale of 8-11 shades. Restraint in color choice leads to more cohesive, professional-looking interfaces.
Colors look different depending on their surroundings. A shade of gray can appear warm or cool depending on the colors around it. Always test your colors in the actual context where they will be used, not in isolation:
If your application will support dark mode, plan for it from the beginning. Colors that work well on light backgrounds often need adjustment for dark backgrounds. Typically, you should:
#000000) backgrounds -- dark gray (#1a1a2e or similar) is easier on the eyes.Transparent colors behave differently depending on what is behind them. A semi-transparent overlay will look different on light and dark backgrounds. When using alpha transparency:
color-mix() instead of transparent overlays when the background is known.Converting between color formats manually is tedious and error-prone. Our free Color Converter tool makes it instant:
Whether you are translating a HEX code from a Figma mockup into HSL for your CSS custom properties, or converting an RGB value from a Canvas API into a HEX code for documentation, the Color Converter eliminates the mental math and potential errors.
HEX is a hexadecimal representation of RGB values using a '#' prefix followed by 6 characters (e.g., #FF5733). RGB specifies colors using Red, Green, and Blue channel values from 0-255 (e.g., rgb(255, 87, 51)). HSL defines colors by Hue (0-360 degrees), Saturation (0-100%), and Lightness (0-100%), making it more intuitive for humans to adjust colors (e.g., hsl(11, 100%, 60%)). All three formats can represent the same 16.7 million colors in the sRGB color space.
To convert HEX to RGB, split the 6-character hex string into three pairs. Convert each pair from hexadecimal to decimal. For example, #FF5733: FF = 255 (Red), 57 = 87 (Green), 33 = 51 (Blue), giving you rgb(255, 87, 51). For shorthand hex like #F00, expand each character by doubling it: F becomes FF, 0 becomes 00, 0 becomes 00, giving #FF0000 = rgb(255, 0, 0).
HSL is more intuitive for color manipulation because it separates color into three human-friendly dimensions: Hue (the actual color), Saturation (how vivid it is), and Lightness (how bright or dark). This makes it trivial to create lighter or darker variants by adjusting lightness, desaturate a color by lowering saturation, or find complementary colors by rotating the hue. In CSS, HSL combined with custom properties enables powerful theming systems with minimal code.
Color contrast ratio measures the difference in perceived brightness between two colors, expressed as a ratio like 4.5:1. It is critical for web accessibility: the WCAG guidelines require normal text to have at least a 4.5:1 contrast ratio against its background (AA level) and 7:1 for enhanced accessibility (AAA level). Large text requires at least 3:1. Poor contrast makes text difficult or impossible to read for users with visual impairments or in suboptimal viewing conditions.
Modern browsers support a wide range of color formats: HEX (#RRGGBB, #RGB, #RRGGBBAA, #RGBA), RGB/RGBA with both comma and space syntax, HSL/HSLA, 140+ named colors, and newer formats including HWB, LAB, LCH, and OKLCH. The CSS Color Level 4 specification also introduces color-mix() for blending colors and relative color syntax for deriving new colors from existing ones. All modern browsers (Chrome, Firefox, Safari, Edge) support these newer features.
You can add transparency (alpha channel) in several ways. Use rgba(255, 87, 51, 0.5) for 50% opacity, or hsla(11, 100%, 60%, 0.5). The 8-digit HEX format #FF573380 encodes alpha in the last two digits (80 hex = ~50% opacity). Modern CSS supports the slash syntax: rgb(255 87 51 / 50%) or hsl(11 100% 60% / 0.5). You can also use the opacity property to make an entire element and its children transparent.
Stop guessing color values or writing conversion scripts. Use our free Color Converter to instantly translate between HEX, RGB, and HSL -- right in your browser with zero data sent to any server.
Try the Color Converter NowMaster JSON syntax, formatting best practices, validation techniques, and common parsing errors.
Master Base64 encoding and decoding. Learn the algorithm, common use cases, Base64URL differences, and code examples in multiple languages.
Master Kubernetes YAML from Deployments and Services to advanced scheduling and security contexts.