Color guide

HSL Color Guide: Hue, Saturation and Lightness Explained

A practical guide to HSL colors, including hue, saturation, lightness, CSS syntax, palette adjustments, alpha and common mistakes.

Why HSL feels different from RGB

HSL represents a color with hue, saturation and lightness rather than separate red, green and blue channels. That makes it useful when the task is phrased in visual language: make this blue lighter, reduce its saturation, or rotate the hue toward purple. RGB can represent the same color precisely, but changing one RGB channel often changes more than one perceptual quality at once. HSL reorganizes the coordinates so common design adjustments can be expressed more directly.

The model is convenient rather than perfectly perceptual. Equal numeric changes in HSL lightness do not always look equally large across different hues, and very saturated colors can behave unexpectedly near the extremes. Still, HSL is widely supported in CSS, simple to learn and often easier to reason about than raw channel arithmetic. For many interface tasks it provides a helpful bridge between visual intent and code.

Hue: the position around the color wheel

Hue is usually written as an angle. Zero degrees is red, 60 degrees is yellow, 120 is green, 180 is cyan, 240 is blue and 300 is magenta, with 360 wrapping back to red. Values between those landmarks produce intermediate hues. CSS accepts degrees and other angle units, although degrees are the most readable in design discussions. Rotating the hue while keeping saturation and lightness fixed creates a simple family of related colors.

Hue is only visually meaningful when saturation is above zero. At zero percent saturation the color is gray, so changing the hue number does not change the rendered result. This is important when storing or comparing HSL values: two gray values can contain different hue numbers yet look identical. A UI that lets users edit HSL should treat hue as a coordinate, not as an independent guarantee of visible color.

Saturation: colorfulness in the HSL model

Saturation ranges from zero to one hundred percent. At zero percent the result is completely neutral for the chosen lightness. Increasing saturation moves the color away from gray and toward the vivid edge of the HSL space. A brand accent often uses relatively high saturation, while backgrounds and secondary surfaces may use lower saturation to reduce visual competition. The ideal value depends on contrast, context and the hue itself.

A common mistake is assuming that the same saturation percentage creates the same perceived intensity for every hue and lightness. It does not. A 70% saturated yellow may feel much brighter than a 70% saturated blue. Use the percentage as a controllable parameter, then evaluate the result visually and with contrast measurements. HSL is a design-friendly coordinate system, not a substitute for perception testing.

Lightness: moving between black and white

Lightness is also a percentage. Zero percent is black and one hundred percent is white regardless of hue or saturation. Fifty percent is the midpoint where fully saturated HSL colors are typically at their strongest. Raising lightness above that midpoint mixes the color toward white; lowering it mixes toward black. This makes HSL convenient for generating rough tints and shades from a base hue.

However, HSL lightness is not relative luminance, the quantity used in WCAG contrast calculations. Two colors with the same HSL lightness can have very different measured luminance and therefore different text contrast. Yellow is a familiar example: it can look bright and produce poor contrast with white text even when a similarly coded blue supports white text comfortably. Always measure contrast separately instead of treating the L value as an accessibility score.

Writing HSL in CSS

A familiar CSS form is hsl(217, 91%, 60%). Modern syntax can omit commas: hsl(217 91% 60%). Alpha can be added with a slash, such as hsl(217 91% 60% / 0.75). Browsers calculate the rendered color from these coordinates, and developer tools can often display equivalent RGB or HEX values. Pick one style and keep it consistent across the codebase so reviews focus on actual changes rather than formatting differences.

HSL values can also use CSS variables. A project might store --brand-hue: 217 and construct related colors with hsl(var(--brand-hue) 80% 50%). This pattern can be convenient for themes where a hue changes while the overall structure remains similar. Be careful with generated states: simply adding or subtracting lightness does not guarantee accessible hover, focus or disabled colors.

Building a palette with HSL

Start with a base color that already matches the desired identity, then create only the number of steps the interface truly needs. For a simple component family, you might keep hue mostly stable, reduce saturation for subtle surfaces and vary lightness for borders, backgrounds and strong actions. Evaluate each step next to the others; numeric regularity is less important than a clear visual hierarchy.

For larger systems, define roles instead of just a ladder of numbers. A “primary text” token has a job that includes contrast requirements, while a “blue-700” token only describes its palette position. HSL can help generate candidates, but semantic tokens should be chosen by testing them in their actual contexts. This prevents a mathematically tidy palette from forcing poor combinations into real components.

Common HSL mistakes

One mistake is changing lightness to create text states without rechecking contrast. Another is driving saturation to zero and then expecting hue changes to remain visible. Teams also sometimes treat HSL as perceptually uniform and assume equal numeric steps will look equally spaced. They will not. If evenly perceived ramps are important, a perceptual space such as OKLCH may be a better generation tool even if final values are exported to another syntax.

Do not confuse HSL with HSV or HSB. The models use a similar hue coordinate but define the other dimensions differently, so hsl(200 80% 50%) is not interchangeable with hsv(200 80% 50%). When moving values between tools, check which model the interface labels and use a converter rather than copying percentages into the wrong function.

A practical workflow

Use HSL when the edit you want to make sounds like hue, saturation or lightness. Enter the base color, adjust one dimension at a time, compare the result in context and then check text contrast against the intended foreground or background. If the design will be handed to another system, copy the format that system expects rather than preserving HSL solely for its own sake.

The picker on this site can parse common HSL input and show equivalent RGB and HEX values. That makes it useful for exploring a visual adjustment in HSL while still delivering a fixed value to code, design documentation or another tool. Treat HSL as a convenient editing model and contrast testing as a separate validation step.

Try the values yourself

Use the RGB Color Picker to enter a color, convert between common web formats and inspect practical contrast information.

Open the color picker