npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

leading-trim

v1.0.2

Published

Strip out spacing above and below the first and last lines of a text block

Downloads

3,097

Readme


What's this for?

By default text elements include vertical space based on its line-height value. The effect of that extra space may be overlooked or worked around, but when working with precise scales and layout components, there's probably no room for random spacing going around your text.

leading-trim is a JavaScript port of EightShapes's Text Crop mixin (source). It returns a CSS styles object ready to be used with any CSS-in-JS library that let's you inject styles with nested pseudo-elements.

Install

npm install leading-trim

# or

yarn add leading-trim

Usage

Skip to the tl;dr

leading-trim exports a set of functions:

leadingTrim

Use it when you're setting your font-family to a custom @font-face

import { leadingTrim } from "leading-trim";

leadingTrim({
  lineHeight: 1.5,  // unitless `line-height` that you want for the text
  reference: {      // reference numbers for the `@font-face` you'll use
    fontSize: 40,   // `font-size` in px
    lineHeight: 1,  // unitless `line-height`
    topCrop: 5,     // height to remove from the top in px
    bottomCrop: 6,  // height to remove from the bottom in px
  },
  correction: {     // (optional) adjust the cropping result
    top: 1,         // a positive value shortens the crop
    bottom: -1,     // a negative value expands the crop
  },
});

systemFontLeadingTrim

Use them when you're setting your font-family to a typical system font stack:

body: {
  fontfamily: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen-Sans, Ubuntu, Cantarell, "Helvetica Neue", sans-serif;
}

The reference numbers are already set for this one so you don't have to. Naturally different operative systems will use different fonts, so it's a close approximation, you can still use correction for your use-case:

import { systemFontLeadingTrim } from "leading-trim";

systemFontLeadingTrim({
  lineHeight: 1.5,  // unitless `line-height` that you want for the text
  correction: {     // (optional) adjust the cropping result
    top: 1,         // a positive value shortens the crop
    bottom: -1,     // a negative value expands the crop
  },
})

systemMonoFontReference

Same as above but for a monospace font-family stack:

body: {
  fontfamily: SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
}
import { systemMonoFontReference } from "leading-trim";

systemMonoFontReference({
  lineHeight: 1.5,  // unitless `line-height` that you want for the text
  correction: {     // (optional) adjust the cropping result
    top: 1,         // a positive value shortens the crop
    bottom: -1,     // a negative value expands the crop
  },
})

If the reference numbers were correctly matched, you probably won't need correction numbers different than -1 or 1.

The output of the above functions is a JS object ready to be used in a CSS-in-JS library of your choice:

{
  "display": "block",
  "lineHeight": 1.5,
  "&::after": {
    "marginTop": "calc(-0.375em - 1px + -1px)",
  },
  "&::before": {
    "marginBottom": "calc(-0.375em - 1px + 1px)",
  },
  "&::before, &::after": {
    "content": "\\"\\"",
    "display": "block",
    "height": 0,
    "paddingTop": "1px",
    "width": 0,
  }
}

The code above will work with any font size automatically so it's up to you if you want to provide it along or just let the element inherit the one from the parent element.

Check the examples for a more realistic usage.

Disclaimer: My weapon of choice is React so the examples are only based on that, feel free to PR some other examples using other libraries.

tl;dr

Using a custom font

  1. Use the EightShapes's Text Crop mixin tool to obtain the reference numbers (I got the best results using a line height of 1 and a > 32px font size)
  2. Pass your lineHeight and the reference numbers from the previous step to the leadingTrim function
  3. Inject the styles object that the function outputs using your prefered CSS-in-JS library

Using a system font

Pass your lineHeight to the systemFontLeadingTrim function and inject the styles object that the function outputs using your prefered CSS-in-JS library.

FAQ

Why do I need those reference numbers?

To be able to calculate the size of the top and bottom crop for any given line-height. It's basicaly a rule of 3 so it needs something to compare.

You'll need different reference numbers for each font-family you use (not needed for different font-weights as font height is not changing in that case).

The EightShapes's Text Crop mixin tool makes it a really easy to get it working fast.

Where can I find more info about this trick?

I started learning about this technique when I saw it applied in SEEK's Braid Design System, since then I've seen other resources that may help you wrap your head around the issue:

Where did I hear this name before?

There's a a CSS proposal to address this natively using the leading-trim property. This is not trying to pollyfill that property proposal at all, but it does have a matching purpose:

By using leading-trim to strip out the spacing above the cap height and below the alphabetic baseline, centering the box actually centers the text; and does so reliably, regardless of what font is used to render it.


Built with TypeScript using tsdx