Skip to content
Foxipa

Suggest an edit

Tell us what should be corrected, clarified, or improved. Submission will be connected to Foxipa’s contribution service later.

No information is sent anywhere yet. Your suggestion is only prepared in your browser.

Learning

Typography and Font Selection in CSS

CSS font families, font matching, web fonts, descriptors, features, variations, synthesis, and font palettes, with explicit boundaries to CSS Text and Writing Modes.

Levels: Intermediate ~22 min read

Intermediate

CSS typography is the part of CSS that controls which font is selected, which face is used, and how that selected font is varied and presented. This lesson focuses on the CSS Fonts model: font families, font matching, web fonts, font descriptors, font features, and font variations. It deliberately does not become a general text-layout lesson; line breaking, justification, white-space processing, writing modes, and other text processing belong to the CSS Text and Writing Modes owners.

A font family is a choice set, not a single installed file

The `font-family` property gives the user agent an ordered list of family choices. The user agent evaluates the list and selects an appropriate face for each run of text. A family name therefore describes a set of faces, while a particular face is selected using other font properties and the glyphs needed by the text.

css family-stack.css
1
2
3
p {
  font-family: "Example Sans", system-ui, sans-serif;
}
Interactive Runnable example
Edit

Ready to run.

Quick check

What does the order in a `font-family` list primarily express?

Generic families provide a final category-level fallback

CSS defines generic family keywords such as `serif`, `sans-serif`, `monospace`, `system-ui`, `cursive`, `fantasy`, and `math`, along with additional script- or platform-oriented generic forms. A generic family is not a guarantee of one particular font file; it is a category that the user agent maps to an available font family.

Interactive Runnable example
Edit

Ready to run.

Quick check

What does `sans-serif` identify?

Font matching chooses a face for the text run

Font matching is not simply “find the first installed font.” The user agent starts with the computed family list, narrows a matching family using font properties such as width, style, and weight, and then checks whether the selected face can supply the glyphs required by the text. If it cannot, the process can continue with another family or fallback.

Interactive Runnable example
Edit

Ready to run.

Quick check

Which statement matches the CSS font matching model?

Font weight requests a weight, not necessarily a file named “bold”

`font-weight` expresses the desired typographic weight. A family may contain discrete faces or a variable range. The matching algorithm finds the closest supported value according to the family’s available faces or ranges. `400` and `700` are conventional numeric values, but the CSS model is not limited to those two faces.

css weight.css
1
2
3
4
.light { font-weight: 300; }
.regular { font-weight: 400; }
.medium { font-weight: 500; }
.bold { font-weight: 700; }
Interactive Runnable example
Edit

Ready to run.

Quick check

What is the right mental model for `font-weight: 650`?

Width and style also participate in face selection

`font-stretch` and `font-style` participate in matching alongside weight. A family can expose faces or variable ranges with different widths and styles. CSS therefore separates the requested typographic attributes from the underlying organization of font files.

Interactive Runnable example
Edit

Ready to run.

Quick check

Which properties are part of the CSS face-selection model?

Web fonts are declared with `@font-face`

`@font-face` associates a CSS family name with font resources and descriptors. The author can define a family independently of the font’s internal family naming. The `src` descriptor supplies the font resource list, while descriptors such as `font-weight`, `font-style`, `font-stretch`, and `unicode-range` describe when a face participates in matching.

css font-face.css
1
2
3
4
5
6
@font-face {
  font-family: "Course Sans";
  src: url("course-sans.woff2") format("woff2");
  font-weight: 400;
  font-style: normal;
}

Quick check

What is the main purpose of an `@font-face` rule?

The `src` descriptor provides prioritized font sources

A web font can have more than one source. The user agent evaluates the source list to obtain the font data. A local source can refer to an installed font face, while a URL refers to a font resource. Resource loading itself is a platform concern, but CSS Fonts defines how the declared sources participate in the font face.

css sources.css
1
2
3
4
5
@font-face {
  font-family: "Course Sans";
  src: local("Course Sans"),
       url("course-sans.woff2") format("woff2");
}

Quick check

Where is the prioritized list of font sources declared?

`unicode-range` limits which characters a face covers

`unicode-range` describes the Unicode ranges for which an `@font-face` face is applicable. This can let several faces form a composite family, with different resources supplying different portions of a character set. It is a font-selection mechanism, not a text transformation mechanism.

css unicode-range.css
1
2
3
4
5
@font-face {
  font-family: "Course Latin";
  src: url("latin.woff2") format("woff2");
  unicode-range: U+0000-00FF;
}

Quick check

What does `unicode-range` primarily describe?

Font loading behavior has a CSS-facing display policy

`font-display` controls the CSS Fonts policy for how text is handled while a declared web font is loading or unavailable. It does not guarantee a particular network timing or performance outcome; it specifies the font-display behavior that the user agent applies during the font loading lifecycle.

Interactive Runnable example
Edit

Ready to run.

Quick check

What does `font-display` control?

Font features are distinct from choosing the font face

OpenType and related font features can alter glyph selection and shaping behavior without changing the family choice itself. `font-feature-settings` provides low-level feature-tag control, while higher-level properties such as `font-variant-*` expose standardized typographic controls. The text-shaping details belong to the font-feature model; this lesson focuses on the CSS controls rather than teaching Unicode shaping as a separate subject.

Interactive Runnable example
Edit

Ready to run.

Quick check

What is `font-feature-settings` primarily for?

Kerning and standardized font variants have dedicated controls

CSS Fonts provides higher-level controls for common typographic behavior. `font-kerning` controls whether kerning is applied, while `font-variant-ligatures`, `font-variant-caps`, `font-variant-numeric`, `font-variant-position`, and related subproperties expose standardized feature families. Prefer these higher-level properties when they express the intent; reserve `font-feature-settings` for lower-level feature-tag control.

css font-controls.css
1
2
body { font-family: Georgia, serif; }
.prose { font-kerning: normal; font-variant-numeric: tabular-nums; font-variant-ligatures: common-ligatures; }

Quick check

Which property is the higher-level choice for requesting tabular numerals?

Optical sizing follows the font-size and font design

Variable fonts can expose an optical-size axis. `font-optical-sizing` controls whether the user agent applies automatic optical sizing when the font supports it. This is distinct from `font-variation-settings`: the former expresses the CSS-level optical-sizing policy, while the latter is the lower-level axis mechanism. `auto` is the initial value; `none` disables automatic optical sizing.

css font-controls.css
1
2
3
body { font-family: "Example Variable", system-ui, sans-serif; }
.display { font-size: 3rem; font-optical-sizing: auto; }
.text { font-size: 1rem; font-optical-sizing: none; }

Quick check

What does `font-optical-sizing` control?

Font variations expose axes in variable fonts

Variable fonts can expose continuous variation axes. CSS Fonts maps common axes to properties such as `font-weight`, `font-stretch`, and `font-style`, while `font-variation-settings` provides lower-level axis control. The high-level properties should remain the normal way to request standard axes when they apply.

Interactive Runnable example
Edit

Ready to run.

Quick check

Which is the preferred first choice for a standard weight axis?

Font synthesis controls whether missing styles may be synthesized

When a requested style or weight is not represented by a usable face, a user agent may otherwise synthesize a style where permitted. `font-synthesis` lets authors control which kinds of synthetic faces are allowed. This is different from selecting a real face that the family actually supplies.

Interactive Runnable example
Edit

Ready to run.

Quick check

What does `font-synthesis` control?

Font shorthand is a reset-sensitive shorthand

The `font` shorthand combines several font properties and has special grammar: a font size and family are required, and an optional line-height follows the size after `/`. Like other CSS shorthands, it resets omitted longhands to their initial values. Use it when that reset is intentional, not as an unexplained bundle of unrelated settings.

css font-shorthand.css
1
2
3
.title {
  font: 700 1.5rem/1.2 system-ui, sans-serif;
}

Quick check

What important behavior does the `font` shorthand have?

Font-relative units depend on font metrics

Font-size adjustment can preserve perceived text size across fallbacks

`font-size-adjust` lets an author adjust the used font size based on a font metric so that fallback fonts can preserve a more comparable apparent text size. This is a font-selection/metrics concern, not a general Sizing lesson: it changes how font size is adjusted for typography rather than how a box is sized.

css font-controls.css
1
.copy { font-family: "Primary Sans", system-ui, sans-serif; font-size: 1rem; font-size-adjust: 0.52; }

Quick check

What problem is `font-size-adjust` primarily intended to address?

Units such as `em`, `ex`, `ch`, and `cap` are related to font metrics or the computed font size. Their behavior is therefore connected to the selected font, but the general CSS value and unit model remains owned by Values & Units. This lesson only explains the font-selection dependency needed to understand why changing a font can change a font-relative measurement.

Interactive Runnable example
Edit

Ready to run.

Quick check

Why can changing the selected font affect a `ch`-based measurement?

Font palettes and color fonts are still font features

Color fonts can contain multiple color glyph layers or palettes. CSS Fonts provides controls for selecting or overriding font palettes where supported. This belongs here because it changes how the selected font is rendered; it does not redefine CSS color spaces or background painting.

Interactive Runnable example
Edit

Ready to run.

Quick check

Why does `font-palette` belong with Fonts rather than the Color lesson?

Font matching can vary by character and cluster

A single text run does not necessarily use one physical font file. CSS Fonts describes matching for individual characters and for grapheme clusters so combining marks and variation selectors can be handled coherently. This explains why a fallback font can appear for only part of a line even though one family list is declared on the element.

Interactive Runnable example
Edit

Ready to run.

Quick check

Why can different characters in one element be rendered by different fonts?

A practical font-selection diagnosis

When a font does not appear as expected, diagnose the selection chain instead of immediately changing unrelated typography. Check the computed family list, whether the declared `@font-face` is valid, whether the requested weight/style/width is covered, whether the face covers the characters, and whether fallback or synthesis is allowed. Only after selection is understood should you investigate text layout.

Interactive Runnable example
Edit

Ready to run.

Quick check

What should you check first when a requested web font is not appearing?

What this lesson deliberately does not own

This lesson owns CSS Fonts: selecting font families and faces, declaring web fonts, font descriptors, font matching, font features, font variations, synthesis, and font palettes. CSS Text owns text transformation, white-space handling, line breaking, justification, and related text processing. Writing Modes owns writing-mode direction and flow-relative text geometry. Values & Units owns the general unit definitions. HTML owns document semantics and the meaning of text content.

  1. Font selection and font-face matching → this lesson

  2. Text shaping and line breaking → CSS Text / related text-processing specifications

  3. Writing direction and flow-relative geometry → Writing Modes

  4. Generic value and unit definitions → Values & Units

  5. HTML semantics → HTML curriculum

Specification status and maturity

CSS Fonts Level 3 is a Recommendation. CSS Fonts Levels 4 and 5 are current Working Drafts in the September 2026 W3C publication history. Stable fundamentals are taught first; newer font controls are explicitly presented as developing features rather than as universally settled behavior. The curriculum follows the CSSWG specifications rather than browser-specific tutorials or property catalogs.

Quick review

You should now be able to explain the difference between a font family and a face, trace a family list through font matching and glyph fallback, declare a web font with `@font-face`, understand `unicode-range`, `font-display`, font features, variable-font axes, synthesis, and font palettes, and identify where CSS Fonts ends and CSS Text or Writing Modes begins.

Quick check

Which topic belongs to the existing CSS Text / Text Layout lesson rather than this Fonts lesson?

Was this page helpful?

Mark this learning resource complete to track your learning progress.