Typography

How Vanilla Breeze handles typographic refinement: font synthesis control, context-sensitive emphasis, sub/sup positioning, prose hyphenation, drop caps, heading tracking, and character tokens.

Philosophy

VB uses progressive CSS enhancement for typography. Every feature in this guide is additive: browsers that don't support a property simply ignore it and fall back to the base style. No JavaScript is required.

Font Synthesis Control

When a font family lacks a true bold or italic variant, browsers synthesize (fake) one by algorithmically thickening or slanting glyphs. This often looks poor. VB sets font-synthesis: none on <strong>, <b>, <em>, and <i> to prevent faux bold/italic rendering.

font-optical-sizing: auto lets OpenType variable fonts adjust stroke weight and contrast based on the rendered size, producing crisper text at small sizes and better proportions at display sizes.

strong, b { font-weight: 600; font-synthesis: none; font-optical-sizing: auto; } em, i { font-style: italic; font-synthesis: none; font-optical-sizing: auto; }

Combined Bold-Italic

When <b> and <i> are nested (in either order), VB applies both weight and style with synthesis control:

<p>This has <b><i>bold italic</i></b> text with proper synthesis control.</p> <p>This also works: <strong><em>strong emphasis</em></strong>.</p>

Context-Sensitive Emphasis

Bold and italic render differently depending on their surrounding context:

Bold in Code

Inside <code> and <pre>, bold text gets a subtle highlight background instead of relying solely on weight. This is more visible in monospace fonts where weight differences are subtle.

Italic in Blockquote

Inside blockquotes, italic text is de-emphasized: it renders as normal style with medium weight. Since blockquotes are already visually offset, additional italic can feel overwrought.

<pre><code>The <strong>important</strong> part is highlighted.</code></pre> <blockquote> <p>This quote contains <em>emphasis</em> that de-emphasizes gracefully.</p> </blockquote>

Subscript and Superscript

VB uses font-variant-position for sub/sup when the browser supports it. This produces properly designed glyphs from the font's glyph table rather than shrunk-and-shifted text. The fallback uses the traditional font-size + position: relative approach.

<p>Water is H<sub>2</sub>O. Einstein's E=mc<sup>2</sup>.</p> <p>See footnote<sup class="footnote-ref"><a href="#fn1">1</a></sup>.</p>

Headings

All headings (h1h6) receive two typographic enhancements:

  • font-variant-numeric: lining-nums — Ensures numbers in headings align with capital letters rather than descending like oldstyle numerals
  • hyphens: none — Prevents headings from being hyphenated (hyphenation is for body text, not display text)

Additionally, h1 and h2 get tighter letter-spacing (tracking) to improve their visual density at large sizes:

ElementLetter Spacing
h1-0.025em (var(--letter-spacing-tight))
h2-0.01em
h3h6Normal (inherited)
<h1>Chapter 1: The Year 2025</h1> <!-- Lining numerals ensure "2025" aligns with capital letters --> <!-- letter-spacing: -0.025em tightens the large display text --> <h2>Section 3.2 — Implementation</h2> <!-- letter-spacing: -0.01em for h2 -->

Drop Caps

Use data-drop-cap on an <article> or individual <p> to enlarge the first letter. VB uses the CSS initial-letter property when supported (Safari, Chrome 110+), falling back to float + font-size in other browsers.

<article data-drop-cap> <p>Once upon a time, in a land far away, there lived a great typographer who cared deeply about the first letter of every paragraph...</p> </article> <!-- Or on a single paragraph --> <p data-drop-cap>The quick brown fox jumps over the lazy dog.</p>

Prose Hyphenation

Blog-style articles (article.blog) and prose articles (article[data-prose]) get automatic hyphenation. This requires the lang attribute on <html> so the browser knows which language's hyphenation dictionary to use.

PropertyValuePurpose
hyphensautoEnable automatic hyphenation
hyphenate-limit-chars6 3 2Min 6 chars, at least 3 before and 2 after break
hyphenate-limit-lines2No more than 2 consecutive hyphenated lines
hyphenate-limit-zone8%Only hyphenate in rightmost 8% of line
<html lang="en"> <body> <article class="blog"> <!-- Automatically hyphenates long words at line breaks --> <p>The constitutionality of the telecommunications infrastructure was unprecedented.</p> </article> <!-- Or use data-prose for non-blog articles --> <article data-prose> <p>Prose content with automatic hyphenation.</p> </article> </body> </html>

Note: Hyphenation only works when <html lang="..."> is set. Without it, the browser has no dictionary to consult.

Character Tokens

VB provides CSS custom properties for commonly needed typographic characters. Use them in content properties or anywhere CSS accepts string values. Themes can override these tokens to change separators globally.

Separators

TokenCharacterDescription
--sep-breadcrumbSingle right-pointing angle (breadcrumb default)
--sep-list·Middle dot (inline list separator)
--sep-pipe|Vertical bar
--sep-mdashEm dash
--sep-ndashEn dash
--sep-section§Section sign
--sep-paraPilcrow / paragraph sign

List Markers

TokenCharacterDescription
--marker-defaultBullet
--marker-checkCheck mark
--marker-arrowRight-pointing arrow
--marker-dashHyphen bullet

Math and Keyboard

TokenCharacterDescription
--char-times×Multiplication sign
--char-minusTrue minus sign
--char-degree°Degree symbol
--key-cmdCommand (Mac)
--key-optionOption (Mac)
--key-shiftShift
--key-ctrlControl
--key-returnReturn / Enter
/* Use in CSS content property */ nav.breadcrumb li:not(:last-child)::after { content: var(--sep-breadcrumb); /* > */ } ul.inline li + li::before { content: var(--sep-list); /* middle dot */ } /* Keyboard shortcut display */ kbd::before { content: var(--key-cmd); /* Apple command symbol */ }

Baseline Unit (--lh)

The --lh token equals 1.5rem (one body line-height). Use it for vertical rhythm in prose contexts where spacing should align to the text baseline grid:

/* Vertical rhythm using --lh */ .prose p + p { margin-block-start: var(--lh); /* 1.5rem = one line height */ } .prose h2 { margin-block-start: calc(var(--lh) * 2); /* two line heights */ }

Blockquote Hanging Punctuation

Blockquotes apply hanging-punctuation: first last so that opening and closing quotation marks hang into the margin. This is a progressive enhancement supported in Safari.

Status Indicator

An inline status dot for dashboards, deploy statuses, and similar UI. Uses the .status class with data-status.

<span class="status" data-status="success">Deployed</span> <span class="status" data-status="warning">Pending review</span> <span class="status" data-status="error">Build failed</span> <span class="status" data-status="inactive">Offline</span> <span class="status" data-status="check">Tests passed</span> <span class="status" data-status="fail">Lint errors</span>
data-statusIconColor
success● filled circle--color-success
warning● filled circle--color-warning
error● filled circle--color-error
inactive○ empty circle--color-text-muted
check✔ check mark--color-success
fail✘ cross mark--color-error

Metadata List

An inline list of items separated by middle dots. Use ul.meta for article metadata, tag lists, or similar horizontal data.

<ul class="meta"> <li><time datetime="2026-03-07">March 7, 2026</time></li> <li>Thomas Powell</li> <li>8 min read</li> <li><a href="/tags/css">CSS</a></li> </ul> <!-- Separator variants --> <ul class="meta" data-separator="pipe">...</ul> <ul class="meta" data-separator="dash">...</ul> <ul class="meta" data-separator="slash">...</ul>

List Marker Variants

Override default bullet markers with data-marker on a <ul>.

<ul data-marker="check"> <li>Task completed</li> <li>All tests passing</li> </ul> <ul data-marker="arrow"> <li>Feature one</li> <li>Feature two</li> </ul>

Section Numbering

Use data-section-numbers on an <article> for §-style legal/document numbering. Each h2 gets a section number; h3 headings get alphabetic sub-numbers.

This is distinct from data-numbered (outline-style 1.1, 1.2 numbering).

<article data-section-numbers> <h2>Definitions</h2> <p>For the purposes of this agreement...</p> <h3>Scope</h3> <p>This section defines the scope.</p> <h3>Exclusions</h3> <p>The following are excluded.</p> <h2>Terms of Service</h2> <p>By using this service you agree...</p> </article>

Block Progress

A Unicode block-character progress bar for terminal-style UI. Uses role="meter" for accessibility.

<span class="block-progress" role="meter" aria-valuenow="70" aria-valuemin="0" aria-valuemax="100" aria-label="Build progress"> <span aria-hidden="true" data-filled>&block;&block;&block;&block;&block;&block;&block;</span> <span aria-hidden="true" data-empty>&blk14;&blk14;&blk14;</span> <small>70%</small> </span>

Print URL Expansion

When printing, VB automatically expands external, email, and phone link URLs after the link text so readers can see the destination. This is suppressed for image links and same-page anchors.

Related

  • Design Tokens — Full token reference including font sizes, line heights, and measure
  • i18n — Locale-aware quotes, script-specific typography
  • Anchor element — Link auto-indicators for mailto, tel, PDF
  • Fluid Scaling — Responsive typography with clamp()
  • hgroup — Heading group patterns (eyebrow, byline, display, section-header)