edubun 한국어

Colour and units

Light grey #bbbbbb text on white has a contrast ratio of 1.92 to 1. WCAG asks for at least 4.5 to 1 for normal text.

Ways to write a colour

CSS accepts colours in several notations, and they all end up as the same thing: amounts of red, green and blue light on the screen. Named colours such as red, navy or rebeccapurple are easy to read but limited. Hex notation writes red, green and blue as two hexadecimal digits each, from 00 to ff (0 to 255): #1a5fb4 is 26 red, 95 green and 180 blue, a medium blue. rgb(26 95 180) says the same thing in decimal. hsl(210 80% 40%) describes a colour by hue (an angle on the colour wheel, where 0 is red, 120 green and 240 blue), saturation and lightness, which makes it easy to produce a lighter or darker shade of the same hue by changing one number.

color: navy;
color: #1a5fb4;              /* same as #1A5FB4 */
color: #36c;                 /* short form of #3366cc */
color: rgb(26 95 180);
color: rgb(26 95 180 / 50%); /* half transparent */
color: hsl(210 80% 40%);
background-color: transparent;
The older comma syntax, rgb(26, 95, 180), still works everywhere.

A fourth value, after a slash, sets the alpha channel: rgb(0 0 0 / 50%) is black at half opacity, so whatever is behind shows through. color sets the text colour, background-color the fill behind an element, and border-color its border. The keyword currentColor means the element's text colour, which is handy for icons and borders that should match the text.

Contrast is not optional

Text that is too close in lightness to its background is hard to read for many people: anyone with low vision, older readers, and everyone reading a phone in sunlight. WCAG 2.2, the W3C accessibility guidelines, measures this as a contrast ratio from 1 to 1 (no difference) to 21 to 1 (black on white). Success criterion 1.4.3 asks for at least 4.5 to 1 for normal text and 3 to 1 for large text, which WCAG defines as at least 18 point, or 14 point bold. Dark grey #767676 on white just passes at 4.54 to 1; #777777 just fails at 4.48. Browser developer tools show the ratio when you inspect a text element, so there is no need to guess.

Colour should also never be the only way information is shown. A form that marks errors only by turning a border red leaves out everyone who cannot see red well; add a message or an icon as well.

Absolute and relative units

Lengths need a unit, except zero. px is the CSS pixel, a fixed unit; on high-density screens one CSS pixel covers several physical pixels, so it stays roughly the same size to the eye. Relative units scale with something else. em is relative to the element's own font size, so padding: 0.5em on 20 pixel text is 10 pixels. rem is relative to the root (html) font size, which is 16 pixels in browsers unless the reader has changed it, so 1.25rem is normally 20 pixels. % is relative to the parent, usually its width. vw and vh are hundredths of the viewport width and height, and ch is about the width of the digit zero in the current font.

Which to use? Sizing text in rem respects the reader: if someone sets their browser to larger text, everything sized in rem grows with it, while text fixed in px may not. Padding in em grows with the text it surrounds. Pixels are fine for things that should not scale, such as a 1 pixel border.

hex colour#rrggbb, each pair 00 to ff
hsl()Hue angle, saturation %, lightness %
alphaOpacity, after a slash: rgb(0 0 0 / 50%)
contrast ratio4.5:1 normal text, 3:1 large text (WCAG 1.4.3)
pxCSS pixel, fixed
emRelative to the element font size
remRelative to the root font size (16px by default)
vw / vh1% of the viewport width / height
  1. How much red is in #ff8000, on a 0 to 255 scale?
  2. How much green is in #ff8000?
  3. In hsl(), which hue angle is pure green?
  4. What minimum contrast ratio does WCAG 1.4.3 ask for normal text?
    • 4.5 to 1
    • 3 to 1
    • 7 to 1
  5. Does #777777 on white pass the 4.5 to 1 requirement?
    • No, it is 4.48 to 1
    • Yes, it is 4.54 to 1
    • Yes, any grey passes
  6. The root font size is 16px. How many pixels is 1.5rem?
  7. An element has font-size: 20px and padding: 0.5em. How many pixels of padding?
  8. The viewport is 400px wide. How wide is 50vw?
  9. Why size text in rem rather than px?
    • It follows the reader browser text-size setting
    • It is always smaller
    • It loads faster
  10. A form marks errors only with a red border. What is missing?
    • A message or icon, because colour alone is not enough
    • A darker red
    • Nothing
Key points
  • Named, hex, rgb() and hsl() colours; a slash adds alpha.
  • WCAG 1.4.3: 4.5:1 for normal text, 3:1 for large text; never colour alone.
  • px is fixed; em follows the element font size; rem follows the root (16px by default).