Tailwind leading-* Handoff Mess — Design to Code

Tailwind CSS design

Figma says line height 24 on a 16 text style. The engineer applies text-base leading-6 and moves on. Another frame uses 150% line height. Someone else types leading-[150%]. Visual QA fails on half the pages because Tailwind’s leading-* scale is absolute rem sizes, not “Figma’s 24 means leading-6” in every theme — and percentage vs px gets mixed in handoff notes.

What leading-* actually sets

In default Tailwind, leading-6 is line-height: 1.5rem (24px at 16px root) — a fixed length, not 1.5 unitless relative to font-size. That matters:

UtilityComputed idea (default theme)
leading-none1 (unitless)
leading-tight1.25 (unitless)
leading-61.5rem (absolute)
leading-[1.5]unitless 1.5 × font-size
leading-[24px]absolute 24px

If the designer changes font size to 18px but keeps “line height 24px”, absolute leading-6 stays 24px (ratio shrinks). Unitless 1.333 would keep a proportional look when type scales.

Convert Figma → Tailwind without guessing

Case A — Figma shows px line height (e.g. 24) and font size 16

  • Ratio = 24 / 16 = 1.5
  • Prefer leading-normal (1.5) or leading-[1.5] for proportional scaling
  • Or leading-6 if you intentionally want 24px locked

Case B — Figma shows percent (e.g. 140%)

  • Use unitless: leading-[1.4]
  • Do not map 140% to leading-7 by superstition

Case C — Design tokens named “Body / 16 / 24”

Document the token as both size and line-height in code:

// tailwind.config.js
theme: {
  extend: {
    fontSize: {
      body: ["1rem", { lineHeight: "1.5" }], // 16 / 24
      "body-lg": ["1.125rem", { lineHeight: "1.5rem" }], // decide unitless vs rem deliberately
    },
  },
},

Then components use text-body once — no scavenger hunt for matching leading-*.

Handoff protocol that stops Slack ping-pong

  1. Designers specify font-size + line-height + whether line-height is fixed or relative.
  2. Engineers never “pick the closest leading-N” without computing the ratio.
  3. Shared type styles live in Tailwind fontSize tuples or CSS variables, not ad-hoc class piles.
  4. Visual QA compares computed line-height in DevTools to the token, not the class name.

Common mismatches

Design noteBad codeBetter
16 / 24text-base leading-4text-base leading-normal or text-body
14 / 20text-sm leading-6 (too tall)text-sm leading-[1.4286] or token
12 / 16leading-4 with wrong text sizepair text-xs with matching LH
”Tight” in Figmarandom leading-tightmeasure actual %

Fluid type

If you use clamp() for font-size, absolute rem line-heights can look cramped at one viewport and airy at another. Prefer unitless line-height for fluid type, or define line-height inside the same clamp expression in CSS — utilities alone get messy.

Quick audit

# find lonely leading utilities that may be hand-tuned
rg "leading-\\[" src --glob '*.tsx'

Replace one-off arbitrary leadings with named fontSize styles when the same pair appears three times.

Review heuristic

Reject new leading-[Npx] in PRs when a fontSize token already encodes the pair. Capture the Figma ratio once; after tokens exist, stop hunting class strings. Designers who update a text style should change the token — not ping engineering to rewrite seventeen components that hard-coded leading-6.

Handoff mess is a unit problem: px vs percent vs rem vs unitless. Compute the ratio, encode it in a token, and stop treating leading-6 as a synonym for “whatever Figma’s 24 meant that day.”