Switch to line height functions #14335
Open
+93
−96
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Introduction
In this PR, I’ll tackle 6 issues we currently have with the way line heights are used in Tailwind. Some of these issues have workarounds that work well, but the idea is that this PR uses a technique to avoid these workarounds. After I explain the issues, I’ll explain step-by-step how I ended up with the current implementation which might be a little overwhelming at first. The reason I combined these issues is because the solutions will continuously override each other.
Issues
1. Line heights are not inherited from parents
For example:
2. Line heights in mobile variants are reset
Details of this issue can be found here: #6504 and #2808.
3. The line height of
text-lg
feels a bit offSee #14223. The line height feels a bit “too loose”. This PR will make clear why I opened that PR 😃.
4. Hard to find sensible line heights when using arbitrary font-sizes
When using arbitrary values for font sizes, the default line height of
1.5
will be used (inherited from<body>
). Let’s say we want to usetext-[2.4rem]
, this will have a line height of3.6rem
, which is obviously too huge. We can fix this by using modifiers, but this somewhat makes the font-size utility the only utility that requires modifiers.5. Named leadings sometimes are a little confusing
There is a difference between the normal line height (
1.5
) and the default line height (specified per font size in the config) which isn’t really clear (see https://x.com/firatciftci/status/1835705812133585062 for example). Also, in cases liketext-3xl leading-tight
, the leading class actually makes the line height less tight.6.
<small>
influences the line heightSee https://play.tailwindcss.com/BXck05lL3v. The line height is set via the
text-2xl
, and because<small>
is aligned to the baseline, there will be more whitespace at the bottom.The fixes
Inheritance with custom properties
To fix (1) and (2), we can rewrite the leading utilities like this:
And the font size utility like this:
This way, the line height of a parent (or the element itself) with a leading will be used if present.
Edit: this will probably be fixed in #14403.
Finding a line height function
For the other issues we’re going to do something different. Let’s start by putting the font sizes and their line heights in a table. We’ll convert everything to rem, so it’s easier to understand:
Ideally, we would have some kind of relation between the font sizes and line heights, but because the line heights of tailwind are hand-picked, we do not have this. However, there seem to be 4 line height functions that partially have a relation with the current values.
Some notes before reading the next table:
rem
)rem
)2em-.5rem
1em + .5rem
2em / 3 + 1rem
1em
If we take a closer look, we’ll notice the line height should be the minimum of A,B&C, and at least D. Thanks to css functions, we can write this as:
Which means font size utilities can look like:
Using the line height function
Ok, now let’s have a look at what we can do with this. We can now drop all line heights defined in the config, because the line height function will take care of it. Now the line height of arbitrary values are automatically calculated based on the idea of decreasing the line height for larger font sizes. If we take our example from issue 4 (
text-[2.4rem]
), we’ll see that the calculated line height falls in the2em / 3 + 1rem
range, so the line height will be2.6rem
. Much better.Keeping support for using line heights in the config
Our brand new line height function provides sensible defaults, but someone might want to use a fixed line-height instead. If we also want to support line height inheritance, we can rewrite our font size utilities like this if a line height is present in our config:
Fixing named line heights
Now let’s have a look at how to improve our named leadings. Using distributivity, we can isolate 1.5 in our line height function:
becomes:
Now that we have isolated 1.5, we can change this number by the other line height factors, for example:
Let’s have a look at how this looks when we plot the calculated line heights with the font sizes. I’ve used the relative line heights and a logarithmic scale to better see what is going on:
The only difference between “default tailwind” (pre PR) and “adjusted normal” is the
text-lg
value. All other named leadings are now adjusted to the value of the font size.Now that we have adjusted our line-height/leading config to variables, we can use the
--line-height-normal
variable in the font size utility:In the meanwhile, we have also fixed issue 5. The “default line height” is now equal to the normal line height, and named line heights have the expected influence on font sizes (tighter, more relaxed,...).
<small>
fixThe last fix is just a small one, we just need to adjust the line height to fix the whitespace:
Remarks
--tw-line-height
) and unprefixed--line-height-normal
custom properties, because I assumed configurable variables aren't prefixed, but internal variables are.min(4em / 9 + 2rem / 3, min((2em + 1rem) / 3, (4em - 1rem) / 3))
function can be moved to a separate variable to make things a little more readable.