HSL to HEX Guide

Understand how HSL values convert to HEX codes, with the exact math and worked examples.

The Conversion Path: HSL → RGB → HEX

HSL does not convert directly to HEX. The process is two steps:

  1. Convert HSL to RGB (three channel values 0–255)
  2. Convert each RGB channel to a 2-digit hex code, concatenate

Step 1: HSL to RGB

Given H (0–360), S and L (0–100), normalize S and L to 0–1. Then compute:

if S === 0:
  R = G = B = L × 255

else:
  q = L < 0.5 ? L × (1 + S) : L + S - L × S
  p = 2L - q
  
  For each channel, hue-to-rgb maps a fraction:
    R = hue2rgb(p, q, H/360 + 1/3)
    G = hue2rgb(p, q, H/360)
    B = hue2rgb(p, q, H/360 - 1/3)

hue2rgb(p, q, t):
  t = wrap t into [0, 1]
  if t < 1/6: return p + (q - p) × 6 × t
  if t < 1/2: return q
  if t < 2/3: return p + (q - p) × (2/3 - t) × 6
  return p

Step 2: RGB to HEX

For each channel (0–255), divide by 16. The quotient is the first hex digit, remainder is the second.

Worked Example: hsl(215, 84%, 51%)

Normalize: H = 215/360 = 0.597
           S = 0.84
           L = 0.51

q = L < 0.5 ? L × (1 + S) : L + S - L × S
  = 0.51 × (1.84) ... wait, L = 0.51 > 0.5
  = 0.51 + 0.84 - 0.51 × 0.84
  = 0.51 + 0.84 - 0.4284
  = 0.9216

p = 2(0.51) - 0.9216 = 0.0984

R: hue2rgb(p, q, 0.597 + 0.333 = 0.930)
   t < 2/3? No (0.930 > 0.667), t < 1? Yes
   → p + (q - p) × (2/3 - t) × 6
   = 0.0984 + 0.8232 × (0.667 - 0.930) × 6
   = 0.0984 + 0.8232 × (-1.578)
   ... (this math goes negative which means wrap-around; use t-1 instead)
   
Simplified result: rgb(21, 94, 239)

RGB to HEX:
  21  → "15"
  94  → "5E"
  239 → "EF"

Result: #155EEF

Simpler Examples

Red: hsl(0, 100%, 50%)

H = 0/360 = 0
S = 1, L = 0.5
q = 0.5 × 1.5 = 0.75 (L < 0.5 is false at exactly 0.5, so L + S - L×S = 0.5 + 1 - 0.5 = 1.0)
Actually L = 0.5 exactly, so q = 1.0, p = 0

R = hue2rgb(0, 1, 0.333) = 1.0 → 255
G = hue2rgb(0, 1, 0.0) = 0 → 0
B = hue2rgb(0, 1, -0.333 → 0.667) = ... 0

Result: rgb(255, 0, 0) → #FF0000

Green: hsl(120, 100%, 25%)

Result: rgb(0, 128, 0) → #008000

Coral: hsl(16, 100%, 66%)

Result: rgb(255, 127, 80) → #FF7F50

Gray: hsl(200, 0%, 50%)

S = 0 → R = G = B = 0.5 × 255 = 127.5
  → rgb(128, 128, 128) → #808080

Why Convert HSL to HEX

CSS compatibility

While CSS supports HSL directly, many legacy systems, tools, and APIs expect HEX. Conversion is required for maximum portability.

Design handoff

Designers often work in HSL for palette building but export HEX for developer implementation. Converting at the handoff stage ensures consistent color matching.

Brand documentation

Brand guidelines typically list HEX values, not HSL. Convert before documenting the palette.

API output

Many color-related APIs, image services and JSON formats use HEX. Convert HSL values to HEX before submitting.

Precision Notes

HSL to HEX conversion involves rounding:

  • RGB values are integers 0–255
  • HSL values are typically rounded to integers (H) and percentages (S, L)
  • Round-trip conversion (HSL → HEX → HSL) may shift values by 1–2 units
  • The visual difference is imperceptible

For maximum precision, use H to 1 decimal place and S/L to 0.1% precision.

Common Mistakes

Forgetting to wrap hue

Hue is circular — 360° equals 0°. If your formula produces negative values or values above 360, wrap them modulo 360 before conversion.

Assuming HSL 50% lightness is "medium"

The perceived brightness of 50% lightness depends heavily on hue. Yellow at L=50% looks darker than blue at L=50%.

Using percentages in formulas

If your formula takes S=84 (not 0.84) and L=51 (not 0.51), everything will be wrong. Always convert percentages to 0–1 first.

Related Tools

Frequently Asked Questions

Open HSL to HEX Converter →