Alle Artikel
FundamentalsColour theory

What is a hex colour code, and how do you read one?

A plain explanation of what #4DA374 actually means, how to read it without a tool, and why the shorthand form is more limited than it looks.

· Colour & front-end editorial5 Min. Lesezeit
Title card for the article “What is a hex colour code, and how do you read one?”, filed under fundamentals.

Hex codes look like a secret handshake until someone explains the one rule behind them, at which point they become slightly boring. That is the goal of this article.

Base 16 in one paragraph

We normally count in base 10 using the digits 0 to 9. Hexadecimal counts in base 16, so it needs six more digits, and it borrows letters: A is 10, B is 11, C is 12, D is 13, E is 14, F is 15. That is the entire trick.

Two hex digits can express 16 x 16 = 256 values, which is exactly the range one colour channel needs. That is why colours are written in pairs.

Reading a code by hand

  1. Drop the # — it is punctuation, not data.
  2. Split the six digits into three pairs: 4D, A3, 74.
  3. For each pair, multiply the left digit by 16 and add the right digit.
  4. 4D becomes (4 x 16) + 13 = 77. A3 becomes (10 x 16) + 3 = 163. 74 becomes (7 x 16) + 4 = 116.
  5. So #4DA374 is rgb(77, 163, 116).

A quick sanity check: if all three pairs are equal, the colour is a pure grey. #888888 is grey; #FFFFFF is white; #000000 is black.

The shorthand form is smaller than it looks

Reading #4DA374 one pair at a time. Each pair is a base-16 number from 00 to FF. The left digit is worth sixteen times the right one, so 4D is (4 x 16) + 13 = 77.
Each pair is a base-16 number from 00 to FF. The left digit is worth sixteen times the right one, so 4D is (4 x 16) + 13 = 77.

Three-digit codes expand by doubling each digit, so #0AF becomes #00AAFF. That is convenient, but it means shorthand can only reach 16 x 16 x 16 = 4,096 colours out of the 16.7 million available. Fine for a prototype, limiting for a real palette.

/* identical */
color: #0AF;
color: #00AAFF;

/* NOT the same as #0AF */
color: #01AAFF;

Eight digits means transparency

A fourth pair sets alpha. #4DA374CC is the same green at 80% opacity, because CC is 204 and 204 divided by 255 is roughly 0.8. Browsers have supported this for years, though rgb() with a slash is usually easier to read.

Once the base-16 part clicks, hex stops being a code and becomes what it always was: three ordinary numbers, written compactly enough to paste into a chat message.

Reading a code at a glance

You do not need to convert a code to know roughly what it is. A few patterns cover most of what you will meet.

PatternMeansExample
All three pairs equalA neutral grey#767676
First pair highestReddish#C0392B
Second pair highestGreenish#27AE60
Third pair highestBluish#2980B9
All pairs highLight and pale#EAEAF2
All pairs lowDark#161821

Why hex persists

Hex is not the most readable notation, and it is not the most useful one to adjust by hand. It survives because it is short, unambiguous, copies cleanly between tools, and every piece of software written in the last thirty years understands it. For a value you paste once and never edit, those properties matter more than legibility.

The moment you want to derive a colour from another — a hover state, a tint, a ramp — hex stops helping, because there is no arithmetic you can do on the digits that corresponds to a perceptual change. That is the point at which to reach for a different function.

Where hex codes came from

The notation predates the web. Early graphics hardware addressed colour as bytes, and hexadecimal is the conventional way to write bytes because each digit maps to exactly four bits. Two digits is one byte is one channel, with no remainder — which is why the format is six digits rather than some rounder decimal number.

That heritage explains the parts that look arbitrary. The 0 to 255 range, the pairing of digits, and the leading hash are all consequences of how colour was stored on machines from the 1980s, carried forward because changing them would have broken everything that already worked.

Common mistakes

  • Writing a five- or seven-digit code. Only three, four, six and eight digits are valid; anything else is discarded as an invalid declaration.
  • Assuming #123456 and #135 are related. The shorthand doubles each digit, so #135 expands to #113355, not #135000.
  • Treating the digits as percentages. FF is 255, not 100, and 80 is 128, which is why a fifty percent alpha is written 80 rather than 50.
  • Omitting the hash. Without it the value is not a colour at all, and the whole declaration is dropped.
  • Expecting arithmetic on the digits to work perceptually. Halving every pair does not produce a colour that looks half as bright.

The last one is the conceptually important error. Hex digits are storage values, not quantities of light, so there is no simple manipulation of them that corresponds to a change a person would describe in words.

Frequently asked questions

Is #FFF the same as #FFFFFF?
Yes, exactly. The three-digit shorthand expands by doubling each digit, so #FFF becomes #FFFFFF and #A3C becomes #AA33CC. The shorthand can only express colours whose pairs happen to be identical, which is 4,096 of the 16.7 million possible values.
Are hex codes case sensitive?
No. #ff0000 and #FF0000 are identical. Teams usually pick one convention for consistency; uppercase is slightly more common in design tools and lowercase in stylesheets, and neither is more correct.
What does an eight-digit hex code mean?
The last two digits are alpha, the opacity of that colour. #0F37FF80 is the same blue at roughly fifty percent opacity, because 80 in hexadecimal is 128, which is about half of 255.
Why 255 and not 100?
Because each channel is stored in one byte, and one byte holds 256 distinct values numbered 0 to 255. The number is a consequence of how the value is stored, not a deliberate choice of scale.
Do hex codes work everywhere CSS colours are accepted?
Yes, in every browser in use. Hex is the most widely supported colour notation there is, which is why it remains a sensible fallback to declare before newer functions such as oklch().

Sources

Weiterlesen