-
Notifications
You must be signed in to change notification settings - Fork 4.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Switch to line height functions #14335
Conversation
84f2663
to
d8c6ead
Compare
Hey @MartijnCuppens this is very interesting, really appreciate the effort on this one! I love the idea of being able to get a sensible line-height automatically when setting a font-size, my only real hesitation is a gut feeling around things feeling sort of cryptic and magical — The other thing I was wondering is are these functions always guaranteed to land on whole even numbers to avoid any chance weird display rounding issues? We deliberately made sure all of the default line-heights were even numbers so you could easily center text within elements sized using the spacing scale which is also all even numbers. I also wonder if maybe even if we did use this approach if we should keep Very intrigued either way but simultaneously cautious about making things overly complicated, haha. Let me know what you think 👍 |
Thanks for the reply!
I know it's quite an overwhelming function at first. The main goal of this function is to help people with automatically providing a sensible default line height. Right now Tailwind forces you to set a line height. From a typographic perspective, this makes sense. But it doesn't if you want to just want to change the font sizes, and you're used that line heights are relative, like browser default. Let's assume the following case which makes use of custom properties. If you for example use With the solution in this PR, you will have the ability to use fixed line heights in your config and you will have a sensible default if you don't set them. The cryptic line height function will indeed be visible in code, but in return the font size config will be a lot cleaner and developers aren't required to set their line heights anymore.
For the font-sizes Tailwind currently uses: yes, because they're just the same (except for
Here is a complete overview of the font sizes and line heights in
|
Font-size in px | Line height in px |
---|---|
1 | 1 |
2 | 2 |
3 | 3 |
4 | 4 |
5 | 5 |
6 | 6 |
7 | 7 |
8 | 8 |
9 | 10 |
10 | 12 |
11 | 14 |
12 | 16 |
13 | 18 |
14 | 20 |
15 | 22 |
16 | 24 |
17 | 25 |
18 | 26 |
19 | 27 |
20 | 28 |
21 | 29 |
22 | 30 |
23 | 31 |
24 | 32 |
25 | 32.66666667 |
26 | 33.33333333 |
27 | 34 |
28 | 34.66666667 |
29 | 35.33333333 |
30 | 36 |
31 | 36.66666667 |
32 | 37.33333333 |
33 | 38 |
34 | 38.66666667 |
35 | 39.33333333 |
36 | 40 |
37 | 40.66666667 |
38 | 41.33333333 |
39 | 42 |
40 | 42.66666667 |
41 | 43.33333333 |
42 | 44 |
43 | 44.66666667 |
44 | 45.33333333 |
45 | 46 |
46 | 46.66666667 |
47 | 47.33333333 |
48 | 48 |
49 | 49 |
50 | 50 |
51 | 51 |
If we really want to make sure the line heights are even for every font size that exist (includingvw
font sizes), we can make use of the round()
function to round the calculated line heights to 2px
. This might influence browser support, I'm not sure what that currently is for v4.
I also wonder if maybe even if we did use this approach if we should keep leading-tight, leading-loose, and similar using their existing values for backwards compatibility, and just change the default/global line-height? It seems like that might be enough that people almost never need to think about line-height in normal situations, but not sure.
Good point, BC wise, this isn't the best idea. Since this is just config, I don't really mind removing this from the proposal.
I'll remove the change to the leading classes and rebase the PR now that #14403 is merged. Maybe I'll open a new PR and close this one, to make things a little clearer. I'll try to finish that by Monday Tuesday.
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.