Skip to content
ColorKit

Free font pairing tool

Font pairing with the numbers behind it

This font pairing tool is free and needs no signup: choose a heading face and a body face and the bench reports what is happening between them — the x-height gap, the scale ratio at the sizes you set, and the weight step — then writes both CSS rules for you. Eight curated combinations sit underneath, each with the kind of page it suits and the reason it holds together. Drop in your own headline and paragraph and every one of them re-renders with your words, which is the only honest way to judge a pair.

  • 100% free
  • No signup
  • 8 curated pairs
  • 64 combinations
  • Weight axis on both roles

The pair, on your own words

Type that survives the second screenful

A page of text is a texture before it is a message. Readers take in the rhythm of the ascenders, the width of the counters and the way the lines end, and only then begin to read. Set the body in the face you will ship, at the size you will ship it, over the measure you will ship it on, and the combination either holds or it does not.

Press Ctrl+V anywhere on the page to drop in the headline and copy you are actually shipping — no need to click the field first.

Choose the two roles

x-height, same size
0.514 / 0.486 em (+5.8%)
x-height as set
18.5px / 7.8px
Scale ratio
2.38×
Body at heading x-height
16.9px
Cap height, same size
0.708 / 0.660 em
  • Didone display heading over a humanist body — the skeletons differ, which is the contrast doing the work.
  • 2.38× is the usual working range for an h1 or h2 sitting directly above its own copy.
  • 300 units of weight separate the two roles.

CSS for the two roles

h1, h2, h3 {
  font-family: "Playfair Display", Georgia, serif;
  font-weight: 700;
  font-size: 36px;
  line-height: 1.2;
}

body {
  font-family: "Source Sans 3", system-ui, sans-serif;
  font-weight: 400;
  font-size: 16px;
  line-height: 1.55;
}

The rule assumes Playfair Display and Source Sans 3 are loaded on your own site; the stacks above name a system fallback so the first paint has something with similar proportions to use.

Eight combinations and the reason each one holds

  • Editorial and marketing pages

    Type that survives the second screenful

    A page of text is a texture before it is a message. Readers take in the rhythm of the ascenders, the width of the counters and the way the lines end, and only then begin to read. S

    Playfair Display 700 / Source Sans 3 400 · x-height +5.8%

    Playfair carries the widest stroke contrast in this set, and its hairlines start to break up below roughly 20px — which is the argument for putting it in a heading and never in a caption. Source Sans 3 answers with monoline strokes and the shallowest x-height here, 0.486em, so the paragraph stays quiet under a face that is doing all the talking.

  • Product interfaces and dashboards

    Type that survives the second screenful

    A page of text is a texture before it is a message. Readers take in the rhythm of the ascenders, the width of the counters and the way the lines end, and only then begin to read. S

    Space Grotesk 700 / Inter 400 · x-height -11.0%

    Both faces are grotesques, so the mood agrees; the separation comes from Space Grotesk squaring off its curves and cutting terminals at an angle where Inter keeps every stroke upright and unremarkable. A heading can afford that much personality precisely because Inter's 0.546em x-height holds the paragraph beneath it at a very even reading line.

  • Long-form articles

    Type that survives the second screenful

    A page of text is a texture before it is a message. Readers take in the rhythm of the ascenders, the width of the counters and the way the lines end, and only then begin to read. S

    Merriweather 700 / Inter 400 · x-height +1.6%

    These two sit 1.6% apart in x-height, the closest match anywhere in this set, so a page set this way reads as one voice rather than as two fonts sharing a column. Merriweather was drawn for screens at text sizes, which is why its serifs still have body at 28px instead of thinning out the way a print face does.

  • Documentation and knowledge bases

    Type that survives the second screenful

    A page of text is a texture before it is a message. Readers take in the rhythm of the ascenders, the width of the counters and the way the lines end, and only then begin to read. S

    Roboto Slab 700 / Source Sans 3 400 · x-height +8.6%

    A slab keeps the authority of a serif without the thick-to-thin modulation, so it holds up at the 18-20px a third-level heading in a docs sidebar actually gets. It also runs close to Source Sans 3 in width, which stops a two-line heading from overhanging the column its body copy sits in.

  • A blog living inside an app

    Type that survives the second screenful

    A page of text is a texture before it is a message. Readers take in the rhythm of the ascenders, the width of the counters and the way the lines end, and only then begin to read. S

    Inter 700 / Lora 400 · x-height +9.2%

    This is the inversion — interface face on top, book face underneath — and it is the right way round when the page is mostly product and occasionally prose. Mind the size: Lora's x-height is 8.4% under Inter's, so a 16px paragraph beneath a 16px sans label looks a step smaller until you push it to 17px.

  • Changelogs and developer landing pages

    Type that survives the second screenful

    A page of text is a texture before it is a message. Readers take in the rhythm of the ascenders, the width of the counters and the way the lines end, and only then begin to read. S

    JetBrains Mono 500 / Inter 400 · x-height +0.7%

    A monospaced heading reads as machine output, which is the intended signal on a release note, and 500 is about as heavy as it should go before the fixed advances start to look padded. Keep these headings to six words or so: every glyph occupies 0.6em whether it is an i or an M, so a long mono line runs wide and rags badly.

  • Serif on serif, for a masthead voice

    Type that survives the second screenful

    A page of text is a texture before it is a message. Readers take in the rhythm of the ascenders, the width of the counters and the way the lines end, and only then begin to read. S

    Playfair Display 700 / Lora 400 · x-height +2.8%

    Two serifs work together when they come from different centuries: Playfair is a didone with vertical stress and abrupt hairlines, Lora a contemporary text face with brush-derived, blunter serifs. Their x-heights are 2.8% apart, close enough to look deliberate, and the failure mode to watch for is not clash but sameness — if a glance cannot separate them, drop to one family at two weights.

  • One family, two weights

    Type that survives the second screenful

    A page of text is a texture before it is a message. Readers take in the rhythm of the ascenders, the width of the counters and the way the lines end, and only then begin to read. S

    Inter 800 / Inter 400 · x-height 0.0%

    The combination nobody puts in a gallery: a single variable file, a 400-unit step along its weight axis, and no second download to pay for. Because the axis runs 100 to 900, the 800 here is drawn weight rather than the browser thickening a 400 outline, which is the difference between a heading and a smudge on a low-resolution screen.

How to pair a heading font with a body font

Three steps from a known-good combination to the two CSS rules you will ship.

  1. Start from a combination that already works

    Scroll to the eight cards and find the one whose job matches yours — editorial, product UI, documentation, changelog. Each card names the two families, the weights and the x-height gap between them, and Load into the bench drops that exact configuration into the controls at the top so you can start editing rather than guessing.

  2. Put your own words in it

    Replace the heading line and the paragraph with the copy you are actually shipping; pressing ⌘V or Ctrl+V anywhere on the page drops a paragraph straight into the body field. Every one of the eight cards re-renders with your text, so the comparison happens on your sentence lengths and your vocabulary rather than on a specimen line chosen to flatter the font.

  3. Read the three verdicts, then take the CSS

    The panel under the selects grades structure, scale and weight separately: whether the two skeletons differ at all, whether the heading is far enough above the body to read as a heading, and whether the weight step is doing any work. Adjust the sizes until the scale ratio lands between 1.6× and 2.6×, then press Copy CSS for both rules with the font-size and line-height already filled in.

Technical specifications

Families in the bench8 — Inter, Source Sans 3 and Space Grotesk (sans), Playfair Display, Lora, Merriweather and Roboto Slab (serif and slab), JetBrains Mono (monospace)
Curated combinations8, each with a named job; their x-height gaps run from −11.0% (Space Grotesk over Inter) to +9.2% (Inter over Lora)
Metrics sourcex-height and cap height read from each font's own metrics table and normalized to the em, so Inter's 2048-unit em and Lora's 1000-unit em compare directly
Weight axesEvery family is variable: Lora is narrowest at 400-700, Inter and Roboto Slab widest at 100-900, and the sliders step by 50
Size rangesHeading 20-72px, body 12-24px, both in 1px steps
Sample text90 characters for the heading, 700 for the paragraph, held in memory only
CSS outputOne block with font-family, font-weight, font-size and line-height for both roles; line-height is fixed at 1.2 for headings and 1.55 for body
PriceFree, no signup, and all 64 heading-and-body combinations are open

Frequently asked questions

How many typefaces should one site use?

Two is the working answer and one is the safe one. A heading face and a body face give you enough range for a marketing page, a docs section and a settings screen; a third family almost always turns out to be a fourth role nobody defined — captions, code, a badge — and each of those can be a weight or a size of the two you already have. If you are choosing under time pressure, take one variable family and separate the roles with 400 units of weight, which is the eighth combination in the list below.

Can two serifs be paired?

Yes, when the two come from different genres, and the pairing here to look at is Playfair Display over Lora. Playfair is a didone: vertical stress, abrupt hairlines, drawn for display sizes. Lora is a contemporary text serif with blunter, brush-derived serifs that hold at 16px. Because the genres are that far apart, the reader sees a decision. Two serifs from the same genre — two old-style text faces, say — read as a mistake rather than a choice, and the fix is to use one of them at two weights.

Why does the paragraph look smaller when I set the body in a serif?

Because px measures the em box and your eye measures the x-height, and the two disagree by up to 14% across this set. Lora draws its lowercase at 0.500em against Inter's 0.546em, so the same 16px produces an 8.0px lowercase in one and 8.7px in the other. The bench prints the size that closes the gap — Body at heading x-height — which for Lora under an Inter heading comes out at 17.5px rather than 16px.

Should the heading and the body have the same x-height?

No, and it is the most repeated piece of bad pairing advice on the web. Matched x-heights matter when two faces run at the same size in the same block — a sans label inside serif copy, a monospaced token in a sentence — because there the mismatch shows up as a step in the line. A heading sits at two or three times the body size, where the number that decides whether it reads as a heading is the scale ratio between the two rendered x-heights, not their agreement per em.

What weight should body copy be?

400 in almost every case, and 300 is a trap. A 300 weight tested on a Retina display disappears on a 1080p Windows laptop with grayscale antialiasing, which is still a large share of desktop traffic. Because all eight families here are variable, the interesting move is upward rather than downward: 450 or 500 for body text on a dark background, where light text on dark visually thickens and a 400 can look overweight.

Does pairing two families cost a second download?

Yes — one woff2 per family, and there is no way around it except not pairing. That is the hidden argument for the same-family combination: Inter 800 over Inter 400 is a single variable file covering every weight from 100 to 900, so the heading weight is free once the body weight has loaded. Two families cost two files, which is still fine for most pages; what each one actually weighs is listed family by family on the Google Fonts preview page.

Can I pair a family that is not in this list?

Not in the bench — it only offers the eight families this site ships, because a preview of a font nobody loaded is a preview of your system fallback. The method transfers, though: open your candidate in a font editor or read its metrics, divide the x-height by the units per em, and compare that against the numbers printed here. Anything within about 3% of your body face will sit on the same reading line, and anything more than 10% away needs a size adjustment rather than a different opinion.

About pairing a heading face with a body face

Three things decide whether a combination holds, and only one of them is a matter of taste. The first is structural contrast: two faces must differ enough in skeleton — a serif against a sans, a didone against a grotesque — that the reader registers a change of role instead of a change of file. The second is agreement in mood, which is why a geometric sans drawn in 2020 sits badly under a revival of an eighteenth-century text face however well the shapes behave. The third is measurement, and it is the one that galleries skip. A pairing gallery shows you 60px of heading over 40px of body on a card two hundred words wide; everything looks good at that size. The test that matters is 300 words of your own copy at 16px, which is why the sample text here is editable and why every card restates it.

The measurements themselves come from the fonts. Each family carries a metrics table declaring its units per em, its cap height and its x-height, and dividing the last by the first gives a number you can compare across families: 0.486em for Source Sans 3, 0.555em for Merriweather, a spread of 14% in the height of a lowercase letter at identical px. That is what people are reporting when they say a font runs small. For a heading over a paragraph the useful figure is not whether those two numbers agree but the ratio between the rendered x-heights — under about 1.3× the heading stops reading as a heading, and above 2.6× it starts wrapping to four lines on a phone. If you want that ladder of sizes to be systematic rather than hand-picked, the typography scale generator builds it from a base and a ratio, and the line height calculator settles the leading each step needs at the measure you are setting.

What most pairing advice never mentions is the invoice. Every family you add is another woff2 the browser has to fetch before it can stop showing the fallback, and the eight here range from 22 KB to 95 KB each — the per-family figures are broken out on the Google Fonts preview page. That is the quiet case for the one-family combination: a variable font carries its whole weight axis in a single file, so Inter 800 over Inter 400 costs one download and still gives you 400 units of contrast. When you do commit to two, keep the rest of the system in units that survive a reader changing their browser font size — the px to rem converter turns the pixel values this page produces into the rem values a stylesheet should carry, and letter spacing is worth a second pass on any heading you set above 40px, where the default tracking is always too loose.

Where your headline and copy stay

Every number on this page is worked out by JavaScript running in the tab you are reading it in. Nothing you type, paste or open is uploaded, logged or kept, which is also why the tools carry on working after you disconnect from the network.

The sample text is component state and nothing else — it is never written to local storage, so reloading the page brings back the default paragraph and the draft headline you typed is gone. The eight font files themselves are served from this domain, which means no request leaves for a font CDN while you compare.