Skip to main content
ToolMaple

Color Converter (HEX, RGB, HSL)

Convert between HEX, RGB and HSL with a picker and live preview; click a value to copy it.

Last updated:

RGB
HSL

What HEX, RGB and HSL actually describe

All three are ways of writing the same sRGB color, not three different colors. HEX and RGB are the same numbers in different bases: split #C1170C into the pairs C1, 17 and 0C, read each as base 16, and you get rgb(193, 23, 12). Two hexadecimal digits cover 0 to 255, which is why a channel never goes higher. The three-digit shorthand works by doubling each digit, so #F80 is #FF8800 and not #0F0800.

HSL is the odd one out. Instead of three light sources it gives you a hue angle from 0 to 360 degrees around a color wheel, a saturation percentage, and a lightness percentage that runs from black at 0 through the pure hue at 50 to white at 100. Nothing new is stored; the color just gets coordinates a person can reason about. A lighter version of a brand color is one number in HSL and a guess in RGB.

The naive approaches fail in predictable ways. Adding a fixed amount to each RGB channel to lighten a color clips the strongest channel first, which washes out saturation and pulls the hue toward whatever is left. Multiplying every channel by 0.8 to darken it is closer to correct but still drifts, because the eye does not weight red, green and blue equally. And the most expensive misunderstanding of all: lightness in HSL is not perceived brightness. hsl(60, 100%, 50%) is a bright yellow and hsl(240, 100%, 50%) is a dark blue, yet both claim 50 percent lightness. Two colors with the same L can sit on opposite sides of an accessibility threshold.

Which notation to use for which job

  • HEX: storage and handoff. It is the shortest to paste, the hardest to mistype, and the form every design tool, brand guideline and CSS file already speaks. Keep the HEX as the canonical value for a color and derive everything else from it.
  • RGB: anywhere a form wants three separate numbers or your code wants to do arithmetic. Office color dialogs, native mobile APIs, image libraries and contrast calculations all start from channel values.
  • HSL: picking and adjusting. Fix the hue and move the lightness to get a tint or shade ramp, add 180 degrees to the hue for the complement, step 30 degrees for analogous colors, or 120 degrees for a triad. It is a control surface, not a storage format.
  • Transparency: none of the three carries an alpha channel on this page. In CSS add it as rgb(193 23 12 / 50%), hsl(4 88% 40% / 50%), or an eight-digit HEX such as #C1170C80.
  • OKLCH and LCH: when you want a ramp where the steps look evenly spaced. These are defined in CSS Color Module Level 4 and are perceptually uniform, so changing lightness does not shift the apparent hue the way HSL does. This page does not convert them, so reach for a dedicated OKLCH tool if that is the job.
  • CMYK: print only, and only with the printer profile in hand. There is no reliable device-independent formula.

How to take a color from a design file into code

  1. Copy the HEX out of Figma, Sketch or the style guide and paste it into the HEX field. The leading # is optional, and a three-digit shorthand is accepted and expanded for you.
  2. Check the swatch at the top of the page against the mockup. If it looks wrong, you almost certainly pasted a shade from a neighboring layer rather than the fill you meant.
  3. Read the RGB block if your target takes channel numbers, or the HSL block if you are about to derive related colors from it. Click Copy rgb(...) or Copy hsl(...) to put the complete CSS function on the clipboard, brackets included.
  4. If the design calls for transparency, copy the RGB form and add the alpha yourself rather than guessing an eight-digit HEX.
  5. Before you commit, put the foreground and background pair through the contrast checker so you find out now rather than in review.

How to build a tint and shade ramp from one brand color

  1. Enter the brand HEX and note the HSL triple. For #C1170C that is roughly hsl(4, 88%, 40%).
  2. Leave the hue field alone for every step. Changing it is what makes a palette look like it came from two different brands.
  3. Type each lightness value in turn and copy the HEX that comes back: 95 and 90 for backgrounds, 80 and 70 for hover states and borders, 50 and 40 for the main color, 30 and 20 for text on light backgrounds.
  4. Pull the saturation down by 10 to 20 points at the very light and very dark ends. A near-white at 88 percent saturation looks like a printing error, and a near-black at full saturation looks muddy.
  5. Test the pairs you actually intend to use together. Because HSL lightness is not perceived brightness, a ramp that looks evenly spaced in the numbers will not be evenly spaced to the eye, especially across yellows and blues.

If the hue drifts between steps despite a fixed H, that is the signal to move the ramp to OKLCH, which was designed for this problem.

Getting the value where you need it

Every value is one click from the clipboard. The button beside the HEX field copies the bare code; the small link above each block copies the whole CSS function, brackets and percent signs included.

  • Code editors: paste the HEX for a token file and the rgb() or hsl() form when you need to add alpha in the same line.
  • Figma, Sketch and Illustrator: open the fill color, select the hex field and paste. All of them accept a six-digit code with or without the leading hash.
  • PowerPoint, Word and Excel: open the color dropdown, choose More Colors and then the Custom tab. There are three boxes for red, green and blue that take 0 to 255, which is what the RGB block gives you, and recent versions also take a hexadecimal code in the same panel.
  • iPhone and iPad: tap the copy button, then press and hold in the destination field and tap Paste. iOS asks for permission the first time an app reads another app clipboard.
  • Android: the same flow, press and hold and choose Paste. Gboard keeps a clipboard history behind the clipboard icon if you copied several candidates in a row.
  • Sharing a color with someone else: press Copy share link. The color travels in the address as ?c=ff5500, so whoever opens it lands on the same swatch with every conversion already filled in.

Where the same color is written differently

The numbers are portable; the syntax around them is not. The differences that cause real bugs:

  • Modern versus legacy CSS syntax: CSS Color Module Level 4 defines a space-separated form with a slash before the alpha, rgb(193 23 12 / 50%) and hsl(4 88% 40% / 50%). The older comma form and the rgba() and hsla() spellings remain valid, so both styles will keep working. This page emits the comma form because it pastes cleanly into older toolchains.
  • The native color input: an <input type="color"> hands your script a seven-character lowercase value such as #ff5500, never a shorthand and never an alpha channel. The picker here uppercases it for consistency with the rest of the page, which is cosmetic only.
  • Android: colors are packed integers written 0xAARRGGBB, with alpha at the front. That is the reverse of the eight-digit CSS HEX, where alpha comes last. Copying #C1170C80 into Android code gives you a mostly transparent green-blue instead of a half-transparent red.
  • Apple platforms: UIKit and SwiftUI take channel components as floating point numbers from 0.0 to 1.0, not 0 to 255. Divide by 255, and remember that the same call also expects a color space, so a value handed over without one is interpreted as sRGB.
  • Photoshop and painting apps: their picker is HSB or HSV, not HSL. The hue matches, the third number does not. Setting B to 50 in Photoshop gives you a dark version of the hue, while L at 50 in CSS gives you the pure hue.
  • Python: the standard library has colorsys, but it returns (h, l, s) in that order with all three between 0 and 1, so you have to multiply the hue by 360 and the other two by 100 before the numbers look like CSS.
  • Sass and Tailwind: the long-standing lighten() and darken() helpers in Sass operate in HSL and inherit its hue drift; newer Sass color functions give you finer control. Tailwind CSS version 4 ships its default palette in OKLCH rather than HEX, which is worth knowing before you try to match a custom brand color to one of its scales.

In JavaScript the conversion from a HEX string is short enough to inline, and the same regular expression handles the leading hash:

const [r, g, b] = '#C1170C'.match(/\w\w/g).map(p => parseInt(p, 16))
// [193, 23, 12]

Limits, privacy and accessibility

What leaves your browser: nothing. The conversion is arithmetic running on your device, with no upload and no server round trip. The one thing to know is that the current color is written into the page address as a query parameter once you move off the starting value, so a link you copy or a screenshot of the address bar carries the color with it.

HSL is rounded to whole numbers here. Hue is shown in whole degrees and saturation and lightness in whole percent, so a HEX to HSL to HEX round trip can land one step away in a channel. That is a difference of one part in 255 and is not visible, but it means HSL should not be the place you store a value you intend to compare byte for byte later.

A HEX code is not a guaranteed appearance. Browsers treat a plain six-digit code as sRGB, and what the screen does with it depends on the panel, its profile and the light in the room. Colors outside sRGB, such as the saturated greens available in Display P3, cannot be expressed as a six-digit HEX at all. If a color has to match a physical product or a printed piece, a measured sample beats any screen.

Do not use the lightness field as a contrast check. Contrast under WCAG is computed from relative luminance, which weights the three channels unequally, so equal L values tell you nothing about whether text will be readable. Run the pair through the contrast checker instead. And remember WCAG success criterion 1.4.1: color on its own must never be the only way information is conveyed, so keep the label, icon or underline alongside the red.

Frequently asked questions

How do I convert a HEX color to RGB by hand?

Split the six digits into three pairs and read each pair as a base-16 number. In #C1170C the pairs are C1, 17 and 0C, which are 193, 23 and 12, so the CSS is rgb(193, 23, 12). Each pair covers 0 to 255 because two hexadecimal digits hold 16 x 16 values. A three-digit shorthand such as #F80 is the same color as #FF8800: every digit is doubled, never padded with a zero.

What is the difference between HSL and HSB or HSV?

They share the hue angle but treat the third number differently. In HSL, lightness runs from 0 percent black through 50 percent for the pure hue to 100 percent white. In HSB and HSV, brightness or value runs from 0 percent black to 100 percent for the pure hue, and there is no white end at all. That is why hsl(0, 100%, 50%) and HSB 0, 100, 100 are both pure red. CSS uses HSL. Photoshop and most painting apps use HSB or HSV, so the numbers do not transfer.

Why does my color shift slightly when I convert it back and forth?

The HSL fields on this page are whole numbers, so a hue of 356.4 degrees is shown as 356. Converting that rounded triple back to RGB can land one step away from where you started, which is a change of one in a channel out of 255 and is invisible on screen. If you need the value to survive a round trip exactly, keep the HEX as the source of truth and treat HSL as a control surface for picking, not as storage.

How do I add transparency to a color?

CSS accepts an alpha value in every notation: rgb(193 23 12 / 50%), hsl(4 88% 40% / 50%), or an eight-digit HEX such as #C1170C80 where the last pair is the alpha channel. This page converts the opaque color, so append the alpha yourself. Watch the channel order outside CSS: Android color integers are written 0xAARRGGBB with alpha first, which is the reverse of the CSS eight-digit form.

How do I build a tint and shade ramp from one brand color?

Convert the brand HEX to HSL, keep the hue fixed, then step the lightness for each stop, for example 95, 90, 80 and downward to 20 and 10 percent. Drop the saturation a little as you approach the light end and again at the very dark end, because fully saturated near-white and near-black both look artificial. Check each pair you plan to put together against a contrast checker rather than trusting the lightness numbers.

Is HSL lightness the same thing as perceived brightness?

No, and that is the most expensive misunderstanding in this area. hsl(60, 100%, 50%) is yellow and hsl(240, 100%, 50%) is blue; both read as 50 percent lightness, yet the yellow looks far brighter to the eye. Two colors with identical L can pass and fail an accessibility check against the same background. Use a relative luminance calculation for contrast decisions, not the L field.

What is OKLCH and should I be using it instead?

OKLCH is a perceptually uniform notation defined in CSS Color Module Level 4, with lightness, chroma and hue. Its advantage is that changing lightness keeps the hue looking stable, where HSL drifts. It is a better fit for generating ramps, and Tailwind CSS version 4 ships its default palette in OKLCH. This page converts HEX, RGB and HSL only, so for OKLCH work use a converter that supports it.

Why does the same HEX look different on my phone and my monitor?

A HEX code is only a triple of numbers. What you see depends on the display, its color profile and the ambient light. Browsers treat a plain HEX as sRGB, but a wide-gamut screen may render it more vividly unless the content is color managed. Colors outside sRGB, such as those in Display P3, cannot be written as a six-digit HEX at all, which is one reason CSS Color 4 added notations that can address wider gamuts.

Can I put an RGB or HSL value into PowerPoint, Word or Excel?

Yes. Office color dialogs offer a custom color panel with separate red, green and blue boxes that take 0 to 255, which is exactly what the RGB block on this page gives you, and recent versions also accept a hexadecimal code in the same panel. Paste the HEX if the field is there, otherwise type the three numbers.

Does my color get uploaded anywhere?

No. The conversion runs entirely in your browser, and nothing about the color is sent to a server. Once you move off the starting color the page writes it into its own address as a query parameter such as ?c=ff5500, so that the link you copy reopens the same color. Anyone you hand that link to can read the value, and that is the only place the color travels.

Sources

  • W3C, CSS Color Module Level 4 (the sRGB hex notation, the rgb() and hsl() functions, the space-separated syntax with slash alpha, and the OKLCH and LCH notations).
  • W3C, Web Content Accessibility Guidelines 2.1 (relative luminance and the contrast ratio formula, and success criterion 1.4.1 Use of Color).
  • MDN, the CSS color data type (which notations browsers accept today, with examples).
  • Platform details come from each vendor: the packed 0xAARRGGBB integer from the Android developer documentation for the Color class, the 0.0 to 1.0 components from the UIKit and SwiftUI color references, and the HSB picker behavior from Adobe Photoshop documentation. Office color dialogs were checked against current desktop versions at the time of writing.

More tools

Once the palette exists, the next question is always whether the text on it is readable: the WCAG contrast checker takes the same HEX codes and gives you the ratio and the pass or fail for each level. If you are filling a mockup before the real copy arrives, the lorem ipsum generator produces paragraphs at the length you need.

Related tools

Privacy: the conversion runs entirely in your browser and no color is sent to a server, stored or logged. The current color is kept in the page address so a copied link reopens it, which means the value travels with any link you share. Analytics records only that the page was used, never the color itself.