Give your homepage a readable type scale and an accessible colour palette using CSS custom properties.
Why this matters
Most of what makes a page feel professional is not fancy layout: it is readable text, consistent sizes and a small, deliberate set of colours. Designers call these a type scale and a colour palette. In this lesson you turn your unstyled homepage into something you would be happy to show an employer, using CSS custom properties so the whole design can be adjusted in one place.
Custom properties (CSS variables)
A custom property is a named value you define once and reuse:
:root {
--color-text: #1f2937;
--color-bg: #fdfcf9;
--color-accent: #1d4ed8;
}
body {
color: var(--color-text);
background-color: var(--color-bg);
}
a {
color: var(--color-accent);
}
- Names start with two dashes;
:rootis the<html>element, so properties defined there are available everywhere (they inherit). var(--color-accent)reads the value. Change the accent once, and every link, button and border that uses it follows.- This is exactly how design systems keep large sites consistent.
Choosing a palette
Keep it small:
- Text: a very dark grey or near-black (pure
#000on pure white can feel harsh). - Background: white or a very light tint.
- Accent: one brand colour for links, buttons and highlights.
- Muted: a mid grey for secondary text such as dates and footers.
Then check contrast. WCAG asks for a contrast ratio of at least 4.5:1 for normal text and 3:1 for large text (about 24px, or about 19px bold). Developer tools show the ratio when you inspect a colour, and free tools such as the WebAIM Contrast Checker do the same. Mid greys on white often fail, so test your muted colour carefully. Dark grey #4b5563 on white passes; light grey #9ca3af does not.
Fonts
font-family takes a list, the font stack. The browser uses the first one available and falls back along the list:
body {
font-family: system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
}
system-ui uses the operating system's own interface font, which is fast (nothing to download) and very readable. Always end the stack with a generic family such as sans-serif or serif. Web fonts from services such as Google Fonts are an option later, but every font file is another download, so use one or two at most.
A type scale
A type scale is a set of sizes that grow by a fixed ratio, so headings look related rather than random. With a base of 1rem (16px by default) and a ratio of 1.25:
:root {
--step-0: 1rem; /* body */
--step-1: 1.25rem; /* h3 */
--step-2: 1.563rem;
--step-3: 1.953rem; /* h2 */
--step-4: 2.441rem; /* h1 */
}
h1 { font-size: var(--step-4); }
h2 { font-size: var(--step-3); }
h3 { font-size: var(--step-1); }
Use rem for font sizes. One rem is the root font size, which respects the size the user has chosen in their browser settings. Fixed px sizes for text can override that choice.
Readable text
body {
font-size: var(--step-0);
line-height: 1.6; /* unitless: 1.6 times the font size */
}
main {
max-width: 65ch; /* roughly 65 characters per line */
margin: 0 auto; /* centre the column */
padding: 0 1rem;
}
h1, h2, h3 {
line-height: 1.2; /* headings need tighter lines */
}
- Line height of about 1.5 to 1.7 for body text helps the eye find the next line. Write it without a unit so it scales with each element's font size.
- Line length of about 45 to 75 characters is comfortable to read. The
chunit is the width of the "0" character, which makes this easy.
Links and focus
Links should look like links. Keep the underline in body text (colour alone is not enough for people who cannot distinguish it), and make sure keyboard users can see focus:
a { color: var(--color-accent); }
a:hover,
a:focus-visible { text-decoration-thickness: 2px; }
Never remove the focus outline without providing a clear replacement.
Common mistakes
- Too many colours and fonts. Three or four colours and one or two fonts are plenty.
- Low-contrast grey text, the most common accessibility failure on the web.
- Text sizes in
px, which ignore the user's preferred size. - Full-width paragraphs on large screens, with 150 characters per line.
- Hard-coding the same hex value in twenty places instead of a custom property.
Quick recap
- Define colours and sizes once as custom properties on
:root, then usevar(). - A small palette with 4.5:1 contrast for body text.
- A font stack ending in a generic family;
remsizes from a ratio-based type scale. - Line height about 1.6 and line length about 65ch; visible links and focus.
Try it
Open the Do tab and style the homepage: palette variables, a font stack, a type scale and comfortable line length.