Development

RGB vs Hex: Why Computers See the Same Colour Two Different Ways

Learn the difference between RGB and hexadecimal colours, how computers represent colour internally, and why rgb(255,0,0) and #FF0000 describe exactly the same thing.

RGB vs Hex: Why Computers See the Same Colour Two Different Ways

CSS can describe red in both of these forms:

rgb(255, 0, 0)
#FF0000

They look unrelated, but for ordinary sRGB CSS colors they encode the same channel values. RGB writes those values in decimal. Hex writes them in hexadecimal.

The useful idea is not that computers somehow see two kinds of color. The notation changes; the encoded channel values do not.

RGB Writes Three Channel Values in Decimal

In the familiar 8-bit form, an RGB color has red, green, and blue channel values from 0 through 255:

rgb(255, 0, 0)
red   = 255
green =   0
blue  =   0

That produces full red with no green or blue contribution.

Other examples follow directly:

rgb(0, 255, 0)     /* green */
rgb(0, 0, 255)     /* blue */
rgb(255, 255, 255) /* white */
rgb(0, 0, 0)       /* black */

CSS also allows other forms of rgb() values, including percentages and modern syntax, but the 0—255 notation makes the relationship with six-digit hex especially easy to see. The rgb() documentation covers the current syntax.

One Byte Explains the 0—255 Range

Eight bits can represent 256 distinct unsigned integer values:

00000000 =   0
11111111 = 255

That makes 8-bit channel values convenient for digital color representation.

A familiar RGB triplet can therefore be pictured as three 8-bit values:

red        green      blue
11111111   00000000   00000000
   255         0          0

That three-byte model is useful for understanding six-digit hex, but it isn’t a description of every modern graphics or color pipeline.

For understanding rgb(255, 0, 0) versus #FF0000, however, three 8-bit channel values are the relevant model.

Hex Writes the Same Numbers in Base 16

Hexadecimal uses sixteen digits:

0 1 2 3 4 5 6 7 8 9 A B C D E F

where:

A = 10
B = 11
...
F = 15

Two hexadecimal digits can represent the same 256 values as eight binary bits:

decimal 255
binary  11111111
hex     FF

So each decimal RGB channel can be written as a two-digit hexadecimal value:

255 → FF
  0 → 00
  0 → 00

Put the three pairs together and add CSS’s # prefix:

FF 00 00 → #FF0000

Nothing about the color changed. Only the number system used to write the channel values changed.

Six-Digit Hex Is RRGGBB

A six-digit CSS hex color follows:

#RRGGBB

Each pair corresponds to one channel.

RGBHex
rgb(255, 0, 0)#FF0000
rgb(0, 255, 0)#00FF00
rgb(0, 0, 255)#0000FF
rgb(255, 255, 255)#FFFFFF
rgb(0, 0, 0)#000000
rgb(128, 64, 255)#8040FF

Hex is compact and maps neatly onto byte-sized values, which is why hexadecimal notation appears throughout computing rather than only in CSS.

CSS also supports shorthand forms. For example:

#F00

expands to:

#FF0000

because each digit is duplicated.

Alpha Adds Another Channel

Transparency adds an alpha value.

Modern CSS can write a 50%-transparent red as:

rgb(255 0 0 / 50%)

An eight-digit hex color can represent approximately the same value:

#FF000080

The layout is:

#RRGGBBAA
 FF000080
 │││││└─ alpha
 └────── RGB

80 in hexadecimal is 128 in decimal. As an 8-bit alpha value, 128/255 is about 0.502, so #FF000080 corresponds to roughly 50.2% alpha rather than mathematically exact 50%.

That small distinction is easy to miss when saying the two forms are “exactly the same.”

RGB and Hex Are Not Separate Color Spaces

For six-digit CSS hex and the ordinary sRGB form of rgb(), the two syntaxes specify sRGB channel values in different notation.

That is different from comparing sRGB with color spaces such as Display P3, Lab, or OKLCH.

Modern CSS supports forms including:

hsl(...)
lab(...)
oklch(...)
color(display-p3 ...)

HSL is another way of specifying sRGB colors. Lab and OKLCH use different color models, and color(display-p3 ...) can represent colors outside the sRGB gamut on capable systems.

So it would be misleading to say that every CSS color notation ultimately describes the same three 8-bit RGB bytes. Browsers perform color conversion and color management as needed for the display and rendering pipeline.

The narrow RGB-versus-hex comparison is simpler: rgb(255, 0, 0) and #FF0000 specify the same sRGB color.

Which Notation Is Easier to Use?

RGB makes the channel values immediately visible in decimal:

rgb(128, 64, 255)

Hex writes the same 8-bit values more compactly:

#8040FF

Neither syntax produces a higher-quality color. In ordinary CSS work, the choice between them is usually about readability, existing conventions, tooling, and whether you want to manipulate channel values directly.

Design systems may standardize on hex for compact tokens. Generated styles may use rgb(). Browser developer tools can convert between them. CSS does not require a project to choose only one.

If the project needs perceptual adjustments, wide-gamut colors, or interpolation behavior, the more important choice may be the color space rather than RGB versus hex notation.

Representation Is the Whole Difference

The same number can be written several ways:

decimal:      255
binary:  11111111
hexadecimal:   FF

Likewise:

rgb(255, 0, 0)

  255   0   0
   FF  00  00

    #FF0000

For this pair of CSS syntaxes, conversion does not invent a new color. It rewrites the same sRGB channel values in another number system.

That is why hex stops looking mysterious once FF is recognized as 255. #FF0000 is simply red = FF, green = 00, blue = 00; rgb(255, 0, 0) writes those same values in decimal.

Top