ToolPal
Hands holding a colorful fan of swatches on a gray backdrop, ideal for design themes.

HEX vs RGB vs HSL: Pick the Right Color Format for Your Project

📷 Tima Miroshnichenko / Pexels

HEX vs RGB vs HSL: Pick the Right Color Format for Your Project

Stop blindly copy-pasting color codes. Understand the difference between HEX, RGB, and HSL so you can actually pick colors with confidence.

DBy Daniel ParkMarch 9, 20269 min read

Color Codes in Web Development

Every color you see on the web is represented by a code. Understanding these codes is essential for web developers and designers -- not just for writing CSS, but for communicating with designers, debugging layout issues, and building accessible interfaces.

There are three main color formats you will encounter daily: HEX, RGB, and HSL. Each has strengths and weaknesses, and knowing when to reach for which one will make your life noticeably easier.

HEX Colors

HEX (hexadecimal) is the most common color format on the web. It has been around since the early days of HTML, and you will see it everywhere -- in CSS files, design tools like Figma and Sketch, and brand guidelines.

Format: #RRGGBB

  • Each pair represents Red, Green, and Blue (0-255)
  • Values range from 00 (0) to FF (255)
  • The # prefix tells the browser this is a HEX color

Examples

  • #FF0000 = Pure Red
  • #00FF00 = Pure Green
  • #0000FF = Pure Blue
  • #FFFFFF = White
  • #000000 = Black

Shorthand

When each pair has identical digits, you can shorten: #FF6633#F63

This works because the browser expands each digit by repeating it: #F63 becomes #FF6633. But #F37A21 cannot be shortened because the digits in each pair are different.

HEX with Alpha (Transparency)

Modern browsers support 8-digit HEX codes where the last two digits control opacity:

color: #3B82F680;  /* Blue at 50% opacity */

The alpha value 80 in hex equals 128 in decimal, which is roughly 50% of the maximum 255. Some common alpha values to remember:

  • FF = 100% (fully opaque)
  • BF = 75%
  • 80 = 50%
  • 40 = 25%
  • 00 = 0% (fully transparent)

RGB Colors

RGB stands for Red, Green, Blue. It uses decimal numbers (0-255) for each channel, which many people find more intuitive than hexadecimal notation.

Format: rgb(red, green, blue)

color: rgb(59, 130, 246);    /* Blue */
color: rgba(59, 130, 246, 0.5);  /* 50% transparent blue */

The Modern RGB Syntax

CSS has a newer syntax that drops rgba() in favor of just rgb() with an optional alpha:

/* Modern syntax -- works in all current browsers */
color: rgb(59 130 246);           /* no commas */
color: rgb(59 130 246 / 0.5);    /* alpha with slash */
color: rgb(59 130 246 / 50%);    /* alpha as percentage */

This cleaner syntax is fully supported in all modern browsers and is worth adopting if you are not targeting legacy systems.

Why RGB Is Useful

RGB shines when you need to manipulate colors programmatically. Since each channel is a plain number from 0 to 255, it is easy to adjust colors in JavaScript or any programming language:

// Lighten a color by increasing all channels
function lighten(r, g, b, amount) {
  return [
    Math.min(255, r + amount),
    Math.min(255, g + amount),
    Math.min(255, b + amount)
  ];
}

RGB is also the native format for most color picker APIs and image processing libraries, so you avoid conversion overhead.

HSL Colors

HSL stands for Hue, Saturation, Lightness. It is more intuitive for humans because it maps closely to how we actually think about color.

Format: hsl(hue, saturation%, lightness%)

  • Hue: 0-360 (position on the color wheel)
    • 0/360 = Red
    • 120 = Green
    • 240 = Blue
  • Saturation: 0-100% (gray to vibrant)
    • 0% = completely desaturated (gray)
    • 100% = fully saturated (vivid color)
  • Lightness: 0-100% (black to white)
    • 0% = pure black
    • 50% = the pure color
    • 100% = pure white
color: hsl(217, 91%, 60%);   /* Blue */
color: hsl(0, 100%, 50%);    /* Red */
color: hsl(120, 100%, 50%);  /* Green */

Why HSL Is a Game-Changer for Design Systems

The real power of HSL becomes obvious when you need to create color variations. Say your primary brand color is hsl(217, 91%, 60%). Building a full shade palette is trivial:

:root {
  --blue-50:  hsl(217, 91%, 97%);   /* Near white */
  --blue-100: hsl(217, 91%, 93%);
  --blue-200: hsl(217, 91%, 84%);
  --blue-300: hsl(217, 91%, 72%);
  --blue-400: hsl(217, 91%, 60%);   /* Base color */
  --blue-500: hsl(217, 91%, 50%);
  --blue-600: hsl(217, 91%, 40%);
  --blue-700: hsl(217, 91%, 30%);
  --blue-800: hsl(217, 91%, 20%);
  --blue-900: hsl(217, 91%, 10%);   /* Near black */
}

You keep the same hue and saturation, and only adjust lightness. The result is a harmonious set of shades that look like they belong together. Try doing that with HEX codes -- you would need a calculator or a design tool.

Creating Color Harmonies with HSL

Since hue is a position on the color wheel (0-360 degrees), creating color harmonies is just arithmetic:

  • Complementary: add 180 to the hue (hsl(217, 91%, 60%)hsl(37, 91%, 60%))
  • Triadic: add 120 and 240 (hsl(217, ...), hsl(337, ...), hsl(97, ...))
  • Analogous: add/subtract 30 (hsl(187, ...), hsl(217, ...), hsl(247, ...))

This is one of the reasons many design systems and CSS frameworks use HSL internally.

HSL with Alpha

Like RGB, HSL supports transparency:

color: hsl(217, 91%, 60%, 0.5);      /* Old syntax */
color: hsl(217 91% 60% / 50%);       /* Modern syntax */

CSS Named Colors

CSS also includes 147 named colors like red, steelblue, papayawhip, and rebeccapurple. They are convenient for prototyping or quick demos, but you rarely see them in production code because:

  • They are not flexible (you cannot adjust brightness or opacity easily)
  • The names can be misleading (darkgray is actually lighter than gray)
  • Your brand colors will never match a named color exactly

That said, transparent and currentColor are two named values that are genuinely useful. currentColor inherits the current text color, which is handy for SVG icons and borders that should match surrounding text.

When to Use Each

FormatBest For
HEXQuick inline colors, most CSS, brand guidelines
RGB/RGBAProgrammatic color manipulation, canvas work
HSL/HSLADesign systems, creating shade palettes, theming

My practical recommendation: Use HSL as your default for new projects. Define your theme colors as HSL custom properties, and you get effortless light/dark mode toggling by adjusting lightness values. When pasting colors from design tools, HEX is fine -- just convert to HSL for your variables.

Color Conversion Formulas

HEX to RGB

Split the 6-digit hex string into three pairs and convert each from hexadecimal to decimal:

#3B82F63B = 59, 82 = 130, F6 = 246 → rgb(59, 130, 246)

RGB to HSL

This conversion involves more math. The rough steps:

  1. Normalize R, G, B to 0-1 range (divide by 255)
  2. Find the max and min values
  3. Lightness = (max + min) / 2
  4. If max equals min, saturation is 0 (gray)
  5. Otherwise, calculate saturation based on lightness
  6. Calculate hue based on which channel is the max

You do not need to memorize this -- use a tool. But understanding the relationship helps you debug color issues.

Common Color Mistakes and How to Avoid Them

1. Ignoring Contrast Ratios

WCAG 2.1 requires a minimum contrast ratio of 4.5:1 for normal text and 3:1 for large text. That light gray text on a white background might look elegant in your mockup, but it fails accessibility standards and is genuinely hard to read in bright sunlight or on cheap monitors.

2. Using Pure Black on Pure White

#000000 on #FFFFFF creates maximum contrast (21:1), which can cause eye strain during extended reading. Many design systems use a slightly softer combination like #1a1a1a on #FAFAFA, which still passes WCAG AAA while being easier on the eyes.

3. Not Testing Colors in Context

A color that looks great as a small swatch can be overwhelming when applied to a large background area. Always test your colors at scale -- fill an entire screen with the background color and place real text on it before committing.

4. Too Many Colors

A common beginner mistake is using too many distinct colors. Most professional sites stick to 2-3 primary colors plus a neutral palette (grays). If you find yourself reaching for a sixth or seventh distinct hue, step back and simplify.

5. Relying on Color Alone

Never use color as the only way to convey information. If error messages are only marked with red text, colorblind users (roughly 8% of men) will miss them. Always pair color with icons, patterns, or text labels.

Real-World Color Workflow

Here is a practical workflow that works well for most web projects:

  1. Pick a primary hue in HSL (e.g., hsl(217, 91%, 60%))
  2. Generate a shade scale by varying lightness from 5% to 97%
  3. Pick a neutral gray with a hint of your primary hue (e.g., hsl(217, 10%, 50%))
  4. Generate gray shades the same way
  5. Add accent colors sparingly -- one for success (green), one for error (red), one for warning (amber)
  6. Check contrast for every text/background combination
  7. Define everything as CSS custom properties so switching themes is painless
:root {
  --primary: hsl(217, 91%, 60%);
  --primary-light: hsl(217, 91%, 93%);
  --primary-dark: hsl(217, 91%, 35%);
  --text: hsl(217, 15%, 15%);
  --text-muted: hsl(217, 10%, 45%);
  --surface: hsl(217, 20%, 98%);
  --error: hsl(0, 72%, 51%);
  --success: hsl(142, 71%, 45%);
}

Try adjusting the color below to see how the same color is represented across HEX, RGB, and HSL formats:

Try it — Color Converter

Convert Colors Now

Use our Color Picker & Converter to convert between HEX, RGB, HSL, and RGBA instantly. You can also check contrast ratios with our Color Contrast Checker.

Frequently Asked Questions

D

About the author

Daniel Park

Senior frontend engineer based in Seoul. Seven years of experience building web applications at Korean SaaS companies, with a focus on developer tooling, web performance, and privacy-first architecture. Open-source contributor to the JavaScript ecosystem and founder of ToolPal.

Learn more

Share this article

XLinkedIn

Related Posts