TL;DR
I'll explain how to style the paragraph of text on a webpage like this:

(Screenshot of my CodePen demo)
If you feel the above screenshot somehow appears more elegant than ordinary webpages, read on.
Introduction
I believe the paragraph of text appears beautiful when the ratio of the line height against the x-height of text can be written in integers, such as 3 to 1 or 5 to 2.
If the line-height CSS value is, say, 3 times as high as the x-height of text, human eyes will then easily recognize that the whitespace between a pair of lines doubles the size of each line (as shown in the top image).
Regulating the whitespace between lines of text in such a precise manner was difficult for webpages until very recently. Thanks to a new CSS property text-box now available for Chrome and Safari, it is now easier to implement. This article shows you how.
1. Setup
Font metrics
We first set the font-family name and its ratio of x-height to font-size:
:root {
/* Font metric */
--body-font: "Cormorant Garamond";
--x-height-to-font-size-ratio: 0.385; /* Value obtained from Section 3 */
In Section 3 below, I’ll explain how to obtain the ratio of x-height to font-size for a font of your choice. For now, let's assume that you know this value.
Design tokens
Next, we create design tokens for spacing:
:root {
--space100: 0.625rem; /* Change this value to your taste */
--space200: calc(var(--space100) * 2);
}
For tighter spacing, you can change the scaling factor:
:root {
--space100: 0.625rem; /* Change this value to your taste */
--space200: calc(var(--space100) * 3/2); /* x1.5 */
}
Spacing hierarchy
Finally, specify x-height and spaces between lines and between paragraphs:
:root {
--x-height: var(--space100);
--btw-lines: var(--space200);
}
By "space between lines", I mean the whitespace below the baseline of text and above the top of the lowercase x in next line:

In next section, I'll introduce the rest of CSS rules that act like a computer program to render text and spacing. This way, changing the parameters above will automatically alter how text appears.
2. font-size and line-height
Set font properties with the CSS variables created in the previous section as follows:
p {
font-family: var(--body-font);
font-size: calc(var(--x-height) / var(--x-height-to-font-size-ratio));
line-height: calc(var(--x-height) + var(--btw-lines));
}
Multiplying font-size with the "x-height to font-size" ratio yields x-height. Consequently, font-size can be derived by dividing x-height with the "x-height to font-size" ratio.
The line-height value corresponds to the vertical distance between two adjacent baselines, which is the sum of x-height and the space between lines.
The above will render a paragraph of text based on the integer ratio of x-height to line-height.
In next section, let me explain how to obtain the ratio of x-height to font-size, the most important parameter of the entire exercise discussed so far.
3. Obtaining the exact ratio of x-height to font-size
With the adoption of a new CSS property text-box by Safari and Chrome, the ratio of x-height to font-size is now easy to obtain by creating a webpage with the following simple HTML/CSS code:
HTML
Assuming we use "Cormorant Garamond" from Google Fonts:
<head>
<!-- Embedded code from Google Fonts -->
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Cormorant+Garamond:ital,wght@0,300..700;1,300..700&display=swap" rel="stylesheet">
</head>
<body>
<div></div>
<p>
After six months, I couldn’t see the value in it. I had no idea what I wanted to do with my life, and no idea how college was going to help me figure it out. And here I was, spending all of the money my parents had saved their entire life. — Steve Jobs (Stanford University Commencement Address on June 12, 2005)
</p>
</body>
The <div> element will be used to render a ruled paper background. The <p> element can be any paragraph, but make sure the first line includes the lowercase x.
The lowercase x is a great character because it has a flat top as well as a flat bottom sitting on the baseline. It allows us to easily measure the height of it.
CSS
:root {
--body-font: "Cormorant Garamond"; /* replace this with your font */
--x-height-to-font-size-ratio: 0.5; /* tweak this value */
}
body {
--x-height: 100px;
--btw-lines: 100px;
}
p {
font-family: var(--body-font);
font-size: calc(var(--x-height) / var(--x-height-to-font-size-ratio));
line-height: calc(var(--x-height) + var(--btw-lines));
text-box: trim-both ex alphabetic; /* The Magic! */
}
/* Ruled page background */
div {
/* Draw 1px grey lines at 100px intervals */
background: repeating-linear-gradient(
to bottom,
#aaa 0px,
#aaa 1px,
transparent 1px,
transparent 100px
);
/* Render behind the paragraph element */
height: 1000px; /* up to 5 lines of text */
position: absolute;
width: 100%;
z-index: -1;
}
I have prepared a CodePen demo. You can fork it for your use: https://codepen.io/masakudamatsu/pen/gbgxRdd
Make sure you open this demo with Chrome or Safari. It doesn't work with Firefox as of June 2026.
Then start changing the value of --x-height-to-font-size-ratio:
- If the lowercase x is taller than 100px, increase the value. - If it's shorter than 100px, *decrease the value.
Make sure that the flat top of the lowercase x overlaps the first 1px grey line while there is no whitespace between the flat bottom of the lowercase x and the second 1px grey line. If so, that means the x-height is 100px.

See the lowercase x. Its top overlaps the first grey line while its bottom touches on the second grey line.
Don't let the bottom of x overlap the second 1px grey line. If so, the x-height is 101px, not 100px.
Three decimal digits are enough. For example, doing this exercise for Cormorant Garamond took me to the value of 0.385. I did the same exercise for Verdana, a system font of most OS's (except Android), which yielded the value of 0.546.
I've found this value can be different from the "ex-height" value stored in font files. Web tools such as Font metrics calculator for font-size-adjust allow you to upload a font file and extract the ratio of x-height to font-size stored in it. When I uploaded the font file of Cormorant Garamond, downloaded from Google Fonts, I got the value of 0.388. But this value gave me the x-height of 101px.
In passing, classic fonts (or those inspired by classic fonts, like Cormorant Garamond) typically have the value less than 0.5. Modern fonts like Verdana have the value larger than 0.5, for the readability of small-sized text on webpages. A large x-height has become the font design trend since the 1970s (such as Avant Garde Gothic and ITC Garamond).
Next steps
Using this framework, we can set the vertical spacing between paragraphs, between the heading and the paragraph, and between sections with the visually clear hierarchy of information.
Below I'll add links to next blog posts that discuss how to do so.
Top comments (0)