Line-height Crop - a simple CSS formula to remove top space from your text
It’s a natural behavior of text elements to include some space on top (and bottom) of the element itself based on its line-height value. In some cases, you may need to remove those spaces as they can create inconsistencies in your page design.
August 6, 2018
In this article we are going to take a look at how we can remove this space from the text elements using a simple SCSS mixin.
This mixin was originally created for our library of web components and can be easily included in your web project as it has no external dependencies.
Here’s the mixin you can use to remove the top space from your text element:
One of the advantages of doing so is that the crop value will be automatically updated if you decide to change the value of your CSS variables (with no need to modify the mixin call) or if the line-height variable is modified at different media queries (with no need to re-use the mixin).
The mixin explained
When using the lhCrop mixin, a ::before pseudo-element is created with a negative margin which cuts the space above your text element.
The opposite of this top-space value gives you the value used in the mixin (you want a negative margin to crop the top space).
We could have created a similar mixin for the bottom space (or included it in the lhCrop mixin) but this is something we have not been needing so far (so we probably won’t be including it).
If this is something you need, then here’s what you have to do:
create an ::after pseudo-element (this time you want to remove the space from the bottom of the text);
add a negative margin-bottom (you can use the same value used as margin-top in the lhCrop mixin).
The lhCrop mixin is based on two simplifications:
The capital letter height is equal to font-size; this is usually not true. If you consider the Roboto font family, for example, the capital letter is about 75% of the font size;
The space on top of the capital letter is equal to the space at the bottom; again, this is usually not true.
In our experiments, it turned out these two simplifications were more than acceptable and we were always able to obtain the result we were looking for. You may not be able to achieve a pixel-perfect crop but, in our opinion, the ease of use of the mixin makes up for this minor approximation.
You can push the mixin a little further if you want to address the first simplification. Taking the Roboto font family as example, if the height of the capital letter is not 1*font-size but 0.75*font-size, then the above margin value becomes:
margin-top: (0.75 - line-height)*0.5em
Our lhCrop mixin could be modified to take this variable into account:
This time we can pass a second value to the mixin: by default, this value is 1 (so capital-letter height equal to font-size) but you could use a different value if you need more control. In this case, here’s how you would use the mixin:
@include lhCrop(1.2, 0.75); //using Roboto font family
If you are planning on using this modified version of the mixin, then a good approach would be to define, in your _typography.scss file, a -- capital-letter variable for each one of your fonts and use that variable when calling the lhCrop mixin:
/* line-height */
/* capital letters - used in combo with the lhCrop mixin */
@include lhCrop(var(--body-line-height), var(--font-primary-capital-letter));
This makes your system quite easy to maintain: if you need to change your font-family, you’ll only need to update the -- capital-letter variable with no need to modify the mixin calls.
Here’s an example of this mixin in action:
As for the second simplification, you would need to take into account the descender (bottom space) and the ascender (top space + capital letter) of the font family you are using.
We actually didn’t go into this level of customization as it was not necessary for our use-cases.
If you feel like you need a pixel-perfect precision or if the font you are using has a strong unbalance between top and bottom spaces, then the Text Crop Tool is probably a better solution for you.
For now, we have decided to go with the simplified version of the mixin (we have not included the second $capital-letter argument) as it turned out to be accurate enough in all our experiments so far.
💌 Join our newsletter
Get our monthly recap with the latest CodyHouse news