Course outline

HTML & CSS / Adaptable interfaces / Lesson 10

Typography, color, and writing direction

Build readable text systems that adapt to user settings, language, bidirectional content, and visible interaction states.

About 4 min readContent reviewed
On this page

Lesson goals

  • Typography is a relationship system
  • Create a readable prose block
  • Color should support information

Typography is a relationship system

Readable typography combines font choice, size, line height, line length, spacing, and hierarchy. A beautiful font does not compensate for cramped lines or a low-contrast foreground. Start with a dependable system font stack and a sensible base size, then test actual content in the languages you support. Different scripts have different shapes and spacing needs; a line-height that works for short Latin headings may clip or crowd Arabic marks. Avoid treating text as an image that must fit an exact rectangle. Users can zoom, substitute fonts, and change spacing, so content must remain available when its metrics differ.

Use relative sizes with bounds

rem sizes follow the root font size, while em values depend on the relevant element context. A unitless line-height scales with each element’s font size and generally composes better through inheritance than a fixed pixel line-height. ch approximates the advance measure of the font’s zero glyph, so it is useful as a rough line-length constraint rather than an exact character counter for every language. clamp can bound fluid values, but avoid using viewport units alone for text because that may undermine expected resizing. Check browser zoom and user font settings instead of assuming a relative unit automatically solves accessibility.

Create a readable prose block

The first example sets a system stack, a relative font size, unitless line-height, and a bounded measure. The heading remains semantically h1 even though the CSS changes its size. The block can shrink on narrow screens, and padding preserves space near the edges. A line-height value is not a promise that every font renders identically; test fallback fonts and combining marks. Avoid fixed block heights around paragraphs unless there is a clear overflow design, because translated or enlarged text commonly needs additional lines. Let the content determine its block size in ordinary reading layouts.

html Prose typography
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Prose typography</title>
<style>
body { font-family: system-ui, sans-serif; font-size: 1rem; line-height: 1.6; } .prose { max-inline-size: 65ch; margin-inline: auto; padding: 1rem; } h1 { font-size: 2rem; line-height: 1.2; }
</style>
</head>
<body>
<main class="prose"><h1>Readable content</h1><p>Text should remain available when users choose a larger font or a narrower reading window.</p><p>A content-sized block can grow naturally.</p></main>
</body>
</html>
Expected output
A readable prose column that can grow with text.

The prose uses flexible width and height. A unitless line-height scales with each text size rather than fixing every line to a pixel box.

Treat direction as content metadata

Set lang to identify language and dir to establish base text direction where needed. CSS logical properties such as margin-inline-start follow that direction, while margin-left always names a physical side. Inline fragments with an unknown direction can use bdi to isolate their bidirectional effects; dir="auto" can be useful for user-supplied text after understanding its behavior. The second example embeds a Latin reference inside Arabic content and isolates it. Do not reverse the text string or reverse all flex rows to “make Arabic work.” Direction, layout order, and the actual content sequence are related but distinct concerns.

html Bidirectional content
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Bidirectional content</title>
<style>
.note { border-inline-start: .3rem solid #174e9a; padding-inline-start: 1rem; }
</style>
</head>
<body>
<main lang="ar" dir="rtl"><h1>مرجع الطلب</h1><p>رقم الطلب: <bdi>AB-123</bdi></p><p class="note">تتبع الحافة المنطقية اتجاه المحتوى.</p></main>
</body>
</html>
Expected output
Arabic flows right to left with an isolated Latin reference.

The language and direction describe Arabic content. The isolated reference retains its own order, while logical border and padding follow the inline start.

Color should support information

Choose foreground and background pairs with sufficient contrast for the text’s size and role under the applicable accessibility requirements. Do not communicate errors, selected state, or chart categories by color alone; add words, shape, or another meaningful cue. Links should remain identifiable in prose, and focus needs a distinct visible indication. Test forced-colors or high-contrast settings where your audience uses them, because custom backgrounds and shadows may change or disappear. A design token named danger does not prove its colors are readable in every combination. Review actual adjacent colors and all states, including disabled, visited, focused, and error presentations.

Common errors and fixes

Enlarged text disappears below a card edge

Why it happens
A fixed block height assumes original font metrics.
How to fix it
Allow content growth or provide an explicit accessible overflow design.
Prevent it next time
Test font substitution and zoom.

Arabic alignment needs many left-right overrides

Why it happens
Physical properties encode one direction.
How to fix it
Use suitable logical properties and explicit direction metadata.
Prevent it next time
Review components in both base directions.

An error is discoverable only as red text

Why it happens
Color alone carries its meaning.
How to fix it
Add an explicit message and programmatic association.
Prevent it next time
Review states without relying on hue.

Check your understanding

1. Why is 65ch not a guarantee of sixty-five Arabic characters per line?

Show worked solution

The ch unit is based on a font metric for the zero glyph, while actual glyph widths vary by language, font, shaping, and content. Use it as a rough measure, then inspect real Arabic prose and adjust the design by readability rather than by a literal character-count claim.

2. A selected option is shown only with a green background. Add equivalent information.

Show worked solution

Use the native selected or checked state for the appropriate control and a visible textual or shape cue where needed. Keep contrast sufficient and expose state through the control’s real semantics. CSS can reinforce a selected state but cannot invent the missing interaction contract.

Key takeaways

  • Typography must survive changed metrics.
  • Language and direction are separate metadata.
  • Color reinforces meaning rather than carrying it alone.

Official references