Course outline · 0% complete

0/30 lessons0%

Course overview →

Colors and typography

lesson 4-2 · ~8 min · 11/30

Colors

Color and type are most of what users actually perceive as design, and on a team they arrive as exact values, such as a brand gold of #d4af37. Reading and writing these formats fluently is part of the job.

Three common ways to write the same color:

h1 {
  color: rgb(212, 175, 55);  /* red, green, blue: 0 to 255 each */
  color: #d4af37;            /* hex: the same three numbers in base 16 */
  color: gold;               /* one of about 140 named colors */
}
NotationShapeNote
rgb(212, 175, 55)three 0 to 255 channelsmost readable
#d4af37two hex digits per channelwhat you will see everywhere
golda nameabout 140 exist

Hex is #RRGGBB, with two hex digits from 00 to ff, meaning 0 to 255, per channel. So #000000 is black, #ffffff is white, and #ff0000 is pure red.

Two properties use colors constantly. color sets the text color, and background-color, or the shorthand background, fills the area behind the element.

For transparency, rgba(0, 0, 0, 0.5) adds a fourth number, an opacity from 0 for invisible to 1 for solid.

#d4af37redgreenblue21217555rgb(212, 175, 55)Two hex digits reach 255, so ff is the largest a single channel can be.Equal values in all three channels always produce a gray.
A hex color splits into three pairs of digits, one per channel, each standing for a number from 0 to 255.

Typography

body {
  font-family: Georgia, "Times New Roman", serif;
  font-size: 16px;
  line-height: 1.5;
}
PropertyEffectGood default
font-familya fallback list of fonts to tryend with a generic family
font-sizetext size16px, the browser default
line-heightspace between lines, as a multiple1.4 to 1.6
font-weightboldnessbold, or 100 to 900
text-alignhorizontal alignmentleft for body text

font-family is a fallback list, so the browser tries Georgia, then Times New Roman, then whatever serif font it has. Always ending with a generic family, meaning serif, sans-serif, or monospace, guarantees something sensible.

Body text should rarely go below 16px, and line-height given as a plain multiple rather than a pixel value scales correctly when the font size changes.

Setting these once on body lets nearly every element inherit them. Inheritance is part of the cascade, which is next lesson.

Reading a hex color

#00ff00 is pure green.

The channels read red, then green, then blue, so 00 red, ff green, and 00 blue means all green and nothing else. ff is 255, the maximum for a channel.

HexChannelsColor
#00ff000, 255, 0pure green
#ff0000255, 0, 0pure red
#ffffff255, 255, 255white
#0000000, 0, 0black

Reading hex by splitting it into three pairs makes this mechanical rather than memorized. Equal values in all three channels always give a gray, which is a useful sanity check.

Converting one channel to hex

Hex colors are base-16 numbers, and JavaScript converts a channel with toString(16).

console.log((212).toString(16));
console.log((5).toString(16));
console.log((5).toString(16).padStart(2, "0"));

Output

d4
5
05
ValueRaw hexPadded
212d4d4
5505

Small values produce a single digit, which is why padding is required. A hex color needs exactly two digits per channel, so an unpadded 5 would shift every later digit and produce a completely different color.

Building a full hex color

rgbToHex(r, g, b) converts three 0 to 255 channel values into a #rrggbb string, using the toString(16) and padStart pair from above.

function rgbToHex(r, g, b) {
  const hex = (n) => n.toString(16).padStart(2, "0");
  return "#" + hex(r) + hex(g) + hex(b);
}

console.log(rgbToHex(212, 175, 55));
console.log(rgbToHex(0, 0, 0));
console.log(rgbToHex(255, 255, 255));

Output

#d4af37
#000000
#ffffff
InputOutput
212, 175, 55#d4af37
0, 0, 0#000000
255, 255, 255#ffffff

The one-channel helper does all of the real work, and the outer function only concatenates its three results after a #. Extracting that helper is what keeps the padding rule in exactly one place, so the black case comes out as six zeros rather than three.