Skip to main content

Colors & Typography

Colours and fonts are the two most visible aspects of any design. This chapter covers every way CSS lets you define colours and control how text looks.

Colour values​

CSS offers several formats for specifying colours. They all produce the same result - pick the one that fits your workflow.

Named colours​

CSS defines 148 named colours. Some common ones:

NameColourNameColour
redRedblueBlue
greenGreenorangeOrange
whiteWhiteblackBlack
tomatoTomatocoralCoral
navyNavytealTeal
h1 {
color: navy;
background-color: lightyellow;
}

Named colours are convenient for quick prototyping but limited for precise design work.

Two related keywords are worth knowing even though they are not named colours:

  • transparent - fully transparent black (rgba(0, 0, 0, 0))
  • currentColor - reuses the element's current color value

Hexadecimal (hex)​

Hex codes are the most common colour format on the web. They start with # followed by six characters (0-9, a-f):

h1 {
color: #1a1a2e;
background-color: #f5f5dc;
}

The six characters represent three pairs: red, green, blue (RR GG BB). Each pair ranges from 00 (none) to ff (full intensity).

HexMeaning
#000000Black (no colour)
#ffffffWhite (all colours full)
#ff0000Pure red
#00ff00Pure green
#0000ffPure blue
#808080Medium grey

Shorthand: When each pair has identical characters, you can shorten to three characters:

#ff0000 → #f00
#336699 → #369
#ffffff → #fff

rgb() and rgba()​

The rgb() function takes red, green, and blue values from 0 to 255:

h1 {
color: rgb(26, 26, 46);
background-color: rgb(245, 245, 220);
}

To add transparency, use a fourth value (the alpha channel) between 0 (fully transparent) and 1 (fully opaque):

.overlay {
background-color: rgb(0, 0, 0, 0.5);
}

Note: The older rgba() syntax still works, but modern CSS allows the alpha value directly inside rgb().

hsl() and hsla()​

HSL stands for Hue, Saturation, Lightness. Many designers prefer it because it maps to how humans think about colour:

  • Hue - a degree on the colour wheel (0-360). 0 = red, 120 = green, 240 = blue
  • Saturation - how vivid the colour is (0% = grey, 100% = full colour)
  • Lightness - how light or dark (0% = black, 50% = pure colour, 100% = white)
h1 {
color: hsl(234, 28%, 14%);
}

.muted {
color: hsl(234, 10%, 50%);
}

HSL makes it easy to create colour variations by adjusting a single value:

.primary {
background-color: hsl(210, 80%, 50%);
}

.primary-light {
background-color: hsl(210, 80%, 70%);
}

.primary-dark {
background-color: hsl(210, 80%, 30%);
}

All three share the same hue and saturation - only lightness changes.

Alpha transparency works the same way:

.overlay {
background-color: hsl(0, 0%, 0%, 0.5);
}

Which format to use?​

FormatBest for
NamedQuick prototyping, reading code
HexCopy-pasting from design tools, most common
rgb()When you need alpha transparency
hsl()Creating colour systems, adjusting shades

Tip: Most design tools (Figma, Sketch, Adobe XD) export hex values by default. Use hex for one-off colours and HSL when building a colour system with consistent hues.

The opacity property​

The opacity property makes an entire element transparent, including all its children:

.faded {
opacity: 0.5;
}

Values range from 0 (invisible) to 1 (fully visible).

The key difference from alpha colours: opacity affects everything inside the element (text, images, child elements), while rgb(0, 0, 0, 0.5) only makes the background transparent.

Color properties​

CSS has two main colour properties:

PropertyWhat it colours
colorText colour
background-colorElement background
.alert {
color: #721c24;
background-color: #f8d7da;
}

Other properties that accept colour values include border-color, outline-color, box-shadow, text-shadow, and text-decoration-color.

currentColor​

The special keyword currentColor refers to the element's color value. It is useful for keeping borders, shadows, and other elements in sync with the text:

.link {
color: #4a90d9;
border-bottom: 2px solid currentColor;
}

If you change the text colour, the border colour changes automatically.

Font family​

The font-family property sets the typeface:

body {
font-family: Georgia, "Times New Roman", serif;
}

The value is a font stack - an ordered list of fonts. The browser uses the first available font and falls back to the next one if it is not installed.

Always end with a generic family as the final fallback:

Generic familyStyleExamples
serifLetters have decorative endsGeorgia, Times New Roman
sans-serifClean, no decorative endsArial, Helvetica, Verdana
monospaceFixed-width charactersCourier New, Consolas
cursiveHandwriting styleComic Sans MS
system-uiOS default UI fontVaries by platform
body {
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
}

code {
font-family: "Fira Code", "Cascadia Code", Consolas, monospace;
}

Note: Font names with spaces must be quoted: "Times New Roman", "Fira Code".

Web-safe fonts​

These fonts are installed on almost every computer and are safe to use without loading external files:

  • Serif: Georgia, Times New Roman
  • Sans-serif: Arial, Verdana, Trebuchet MS, Tahoma
  • Monospace: Courier New, Lucida Console

Loading Google Fonts​

For a wider selection, load fonts from Google Fonts. Add a <link> tag in your HTML <head>:

<link rel="preconnect" href="https://fonts.googleapis.com" />
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;600;700&display=swap"
rel="stylesheet" />

Then use the font in CSS:

body {
font-family: "Inter", sans-serif;
}

Tip: Only load the weights you actually use. Each additional weight increases page load time. If performance or privacy matters, self-host WOFF2 files instead of calling Google Fonts at runtime. See Web Performance for the trade-offs.

Font size​

The font-size property sets how large text appears:

h1 {
font-size: 36px;
}

p {
font-size: 18px;
}

small {
font-size: 14px;
}

We cover the different units (px, em, rem) in detail in the next chapter. For now, px (pixels) is the simplest to understand.

Font weight​

The font-weight property controls how bold text is:

h1 {
font-weight: 700;
}

p {
font-weight: 400;
}

.light {
font-weight: 300;
}
ValueName
100Thin
300Light
400Normal
600Semi-bold
700Bold
900Black

You can also use keywords: normal (= 400) and bold (= 700).

Note: The font file must include the weight you request. If you set font-weight: 300 but the font only has 400 and 700, the browser will substitute the nearest available weight.

Font style​

The font-style property handles italic text:

em {
font-style: italic;
}

.no-italic {
font-style: normal;
}

Values: normal, italic, oblique.

Line height​

The line-height property controls the vertical spacing between lines of text. It is one of the most important properties for readability:

body {
line-height: 1.6;
}

h1 {
line-height: 1.2;
}

A unitless number like 1.6 means "1.6 times the font size". For 18px text, the line height would be 18 × 1.6 = 28.8px.

ValueBest for
1.2Headings (tight spacing)
1.5Body text (comfortable reading)
1.6Long-form content (generous spacing)

Tip: Always use unitless values for line-height. Values with units (28px, 1.5em) do not scale properly when child elements have different font sizes.

Text alignment​

The text-align property controls horizontal text alignment:

h1 {
text-align: center;
}

.right-align {
text-align: right;
}

p {
text-align: left;
}

.justified {
text-align: justify;
}

Text decoration​

The text-decoration property adds (or removes) underlines, overlines, and strikethroughs:

a {
text-decoration: none;
}

.deleted {
text-decoration: line-through;
}

.fancy-underline {
text-decoration: underline wavy #4a90d9;
}

The shorthand accepts up to three values: line (underline, overline, line-through, none), style (solid, dashed, dotted, wavy), and colour.

Text transform​

The text-transform property changes the capitalisation of text:

.uppercase {
text-transform: uppercase;
}

.lowercase {
text-transform: lowercase;
}

.capitalize {
text-transform: capitalize;
}

Letter and word spacing​

Fine-tune spacing between characters and words:

.spaced {
letter-spacing: 2px;
}

.wide-words {
word-spacing: 8px;
}

Small amounts of letter-spacing (0.5-2px) are common on headings and uppercase text to improve readability.

Putting it together​

Here is a complete typography system for a simple page:

*,
*::before,
*::after {
box-sizing: border-box;
}

body {
font-family: "Inter", -apple-system, sans-serif;
font-size: 18px;
line-height: 1.6;
color: #333;
background-color: #fafafa;
margin: 0;
padding: 40px;
}

h1, h2, h3 {
font-family: Georgia, serif;
color: #1a1a2e;
line-height: 1.2;
}

h1 {
font-size: 36px;
margin-bottom: 12px;
}

h2 {
font-size: 28px;
margin-top: 40px;
margin-bottom: 8px;
}

h3 {
font-size: 22px;
margin-top: 32px;
margin-bottom: 8px;
}

p {
margin-top: 0;
margin-bottom: 16px;
}

a {
color: #4a90d9;
text-decoration: underline;
}

a:hover {
color: #2d6cb4;
text-decoration: none;
}

small {
font-size: 14px;
color: #777;
}

This gives you a clean, readable typographic foundation to build on.

What you learned​

  • CSS supports named, hex, rgb(), and hsl() colour formats
  • Use alpha values for transparent colours; use opacity to fade entire elements
  • font-family sets the typeface with a font stack and generic fallback
  • font-size, font-weight, and line-height control text size, boldness, and spacing
  • text-align, text-decoration, and text-transform handle alignment, underlines, and capitalisation
  • Load custom fonts from Google Fonts with a <link> tag
  • A good typography system uses consistent sizes, weights, and line heights

Next step​

Now that you can control colours and fonts, the next chapter covers units and sizing - when to use px vs em vs rem vs % and how each one behaves.