CSS Typography

Readable, beautiful text is a big part of good UI. This page covers font stacks, @font-face, variable fonts, line-height, line-length (measure), hyphens and wrapping, ligatures, and responsive type with clamp().

1) Sensible Font Stacks


body{
  font-family: system-ui, -apple-system, "Segoe UI", Roboto, Ubuntu, Cantarell, "Noto Sans", Helvetica, Arial, "Apple Color Emoji", "Segoe UI Emoji";
  line-height: 1.6;
  color: #0f172a;
}
h1, h2, h3{ font-weight: 700; letter-spacing: .2px; }

This paragraph uses a modern system font stack for fast rendering.

2) Load Web Fonts with @font-face


@font-face{
  font-family: "Inter Var";
  src: url("../asset/fonts/Inter-VariableFont.woff2") format("woff2");
  font-weight: 100 900; /* variable range */
  font-display: swap;
}
body{ font-family: "Inter Var", system-ui, -apple-system, Segoe UI, Roboto, Helvetica, Arial; }

Place the WOFF2 in ../asset/fonts/ and update the path. font-display: swap avoids invisible text.

3) Variable Fonts (axes like "wght", "wdth")


.title{ font-variation-settings: "wght" 700, "wdth" 100; }
.subtle{ font-variation-settings: "wght" 350; }
Variable font heavy title
Subtle weight paragraph using a variable axis

Requires a variable font family; otherwise these declarations are ignored.

4) Line Height & Comfortable Measure (Line Length)


p{ line-height: 1.6; }
.content{ max-width: 60ch; }

Use line-height between 1.5–1.8 for body text and keep line length around 45–75 characters. The ch unit tracks the width of the “0” glyph, which makes it handy for text measure.

5) Wrapping, Hyphenation & Overflow


.hyph{ hyphens: auto; }
.wrap-any{ overflow-wrap: anywhere; }
.break-all{ word-break: break-all; }
.ellipsis{ white-space: nowrap; text-overflow: ellipsis; overflow: hidden; }

Hyphenation lets long words wrap gracefully in justified or narrow columns (enable appropriate language metadata).

supercalifragilisticexpialidocious_is_an_extremely_long_identifier

overflow-wrap:anywhere

supercalifragilisticexpialidocious

word-break:break-all

This is a very long line that will be truncated with an ellipsis at the end when it overflows the container width.

ellipsis

6) Ligatures & OpenType Features


.ligatures{ font-variant-ligatures: common-ligatures discretionary-ligatures; }
.oldstyle{ font-feature-settings: "onum" 1; } /* oldstyle numerals */

Ligatures: fi fl ffi ffl — office, waffle, shuffle

No ligatures: fi fl ffi ffl — office, waffle, shuffle

Subtle text shadow for light backgrounds (use sparingly).

7) Responsive Type with clamp()


h1{ font-size: clamp(28px, 4vw, 44px); }
p.lead{ font-size: clamp(16px, 1.2vw + 12px, 22px); }

Fluid Heading

Subheading adjusts with viewport

Body size adapts gently across devices.

8) Small Caps, Tracking & Leading


.caps{ font-variant-caps: small-caps; }
.tracking{ letter-spacing: .4px; }
.leading{ line-height: 1.7; }

Small caps improve certain headings or labels.

Slight tracking can help uppercase text breathe.

Comfortable leading improves readability in long passages.

9) Drop Cap with ::first-letter


.dropcap::first-letter{
  float: left;
  font-size: 3.2em;
  line-height: .9;
  margin: .04em .18em 0 0;
}

Drop caps add a magazine feel to intros. Keep contrast high and ensure the drop cap doesn’t overlap too many lines on small screens.

Accessibility & Best Practices:

  • Ensure sufficient color contrast (WCAG AA: 4.5:1 for body text).
  • Avoid very light weights for long paragraphs; use 400–500 for body, 600–700 for headings.
  • Set a comfortable line-height (1.5–1.8) and measure (~60ch).
  • Use font-display: swap to prevent FOIT (invisible text).
  • Prefer system stacks for dashboards; load brand fonts only where needed.
  • Use hyphens:auto + correct lang attribute for better wrapping.