C.W.K.
Stream
Lesson 07 of 07 · published

Typography & Spacing — Building a Tiny Design System

~12 min · typography, spacing, design-system

Level 0React Novice
0 XP0/54 lessons0/12 achievements
0/100 XP to next level100 XP to go0% complete
Two things separate ad-hoc UIs from designed ones: a typographic scale and a spacing scale. Tailwind gives you defaults; the win is using them with intent.

The typographic scale

Tailwind ships text-xs through text-9xl. The default values follow a roughly 1.25x ratio (a 'major third' in design terms). Use four to six sizes in a single project, not all twelve:

  • text-xs — captions, helper text, badges
  • text-sm — secondary copy, table cells
  • text-base — body copy
  • text-lg — emphasized body, intro paragraphs
  • text-xl to text-2xl — section headers
  • text-3xl to text-4xl — page titles

Resist the urge to use every size. Discipline is what makes a UI feel designed.

Font families

Three slots usually cover an app: a sans-serif for body, a monospace for code/data, and (rarely) a display font for hero titles. Wire them in @theme as --font-sans, --font-mono, --font-display. Tailwind generates font-sans, font-mono, font-display utilities from those.

The spacing scale

Tailwind's spacing scale starts at 0.5 (2px) and goes up. The values follow a 4px grid (1 = 4px, 2 = 8px, 4 = 16px, 6 = 24px, 8 = 32px). Stick to the scale. The moment you start writing p-[13px], your UI is no longer on a grid.

Vertical rhythm

Pick a default vertical spacing between related blocks (space-y-4) and unrelated blocks (space-y-8). Use them consistently. Sections of a page should breathe; clusters within a section should sit close. The brain reads spacing as semantic.

The scale is the design system. A design system isn't a Figma library — it's the set of sizes, spaces, colors, and fonts you commit to. A working Tailwind project with five text sizes, four spacing values, and three semantic colors has a design system. A Figma library with 50 components and no scale discipline doesn't.

Code

@theme — typography + spacing tokens·css
@import "tailwindcss";

@theme {
  /* Fonts — three slots */
  --font-sans: "Inter", system-ui, sans-serif;
  --font-mono: "JetBrains Mono", ui-monospace, monospace;
  --font-display: "Cal Sans", "Inter", sans-serif;

  /* Custom spacing slots layered on top of Tailwind's 4px grid */
  --spacing-section: 4rem;     /* between major page sections */
  --spacing-cluster: 1rem;     /* between related items */
  --spacing-gutter: 1.5rem;    /* page gutters */
}

/* Use as: gap-cluster, py-section, px-gutter */
A page that uses the scale with intent·tsx
function HomePage() {
  return (
    <main className="min-h-screen bg-bg text-fg">
      <div className="max-w-3xl mx-auto px-gutter py-section space-y-section">
        {/* Hero — display font, big title */}
        <section>
          <h1 className="font-display text-4xl text-fg">
            Welcome
          </h1>
          <p className="mt-2 text-lg text-muted">
            A short intro paragraph in slightly emphasized body type.
          </p>
        </section>

        {/* Content cluster — tight spacing within, big spacing between sections */}
        <section className="space-y-cluster">
          <h2 className="text-2xl font-semibold">Latest posts</h2>
          <article className="space-y-2">
            <h3 className="text-lg font-medium">First post</h3>
            <p className="text-base text-muted">Body paragraph.</p>
            <p className="text-xs text-subtle">Posted 2026-05-25</p>
          </article>
        </section>
      </div>
    </main>
  );
}

External links

Exercise

Take the home page above (or your bootstrap project's App.tsx) and audit it: list every text size, every spacing value, every font family in use. If the list is longer than 6 text sizes, 5 spacing values, or 3 fonts, prune. Refactor to use the reduced set. Notice that the page reads more consistent — that's the design system showing through.
Hint
An honest audit is the hardest part. Grep your JSX for text-, p-, m-, space-y-, gap-, font- and tally. The fixes are easy once you can see the sprawl.

Progress

Progress is local-only — sign in to sync across devices.
Spotted a bug or have feedback on this page?Report an Issue

Comments 0

🔔 Reply notifications (sign in)
Sign inPlease sign in to comment.

No comments yet — be the first.