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

@themosaad/tailwindcss-capsize

v1.0.0

Published

A Tailwind CSS plugin for trimming the whitespace above and below text nodes. This is a port of Capsize.

Downloads

1,861

Readme

A Tailwind CSS plugin for automatically trimming the whitespace above and below text nodes. This is a port of Capsize.

Huge thanks to Michael Taranto and the Seek team behind it for figuring out the hard parts.

View live demo

<p class="capsize font-sans text-xl leading-tight">Capsized Text</p>

Table of Contents

Installation

Install the plugin from npm:

# Using npm
npm install @themosaad/tailwindcss-capsize

Then add the plugin to your tailwind.config.js file:

// tailwind.config.js
module.exports = {
  theme: {
    fontFamily: {
      // define your custom font
      sans: ['Inter var', 'sans-serif'],
    },
    capsize: {
      fontMetrics: {
        // define font metrics for your custom font from Capsize's website
        sans: {
          capHeight: 2048,
          ascent: 2728,
          descent: -680,
          lineGap: 0,
          unitsPerEm: 2816,
        },
      },
      // define the utility class for trimming (leave empty to trim all text nodes)
      className: 'capsize',
    },
  },
  plugins: [require('@themosaad/tailwindcss-capsize')],
}

Usage

Now you can use the capsize class to trim any text:

<p class="capsize font-sans text-xl leading-tight">Capsized Text</p>

Trim by default

if you prefer to trim text nodes by default, don't define a class name. This will move the trimming css to the font-size classes:

// tailwind.config.js
module.exports = {
  theme: {
    capsize: {
      fontMetrics: {
        // ...
      },
      // className: 'capsize',
    },
  },
  plugins: [require('@themosaad/tailwindcss-capsize')],
}

this way, you can use:

<p class="font-sans text-xl leading-tight">Capsized Text</p>

Default line-height

The root line-height is set to 1.5 by default. Which you can alter via:

// tailwind.config.js
module.exports = {
  theme: {
    capsize: {
      rootLineHeightUnitless: 1.2,
  },
}

Therefore, if that's the line-height you want for a capsized element, you can ditch the leading class:

<p class="font-sans text-xl">Capsized Text</p>

If you want better default line-height per font-size, you can enable the defaultLineHeights experimental feature. Which will become the default in Tailwindcss v2.

// tailwind.config.js
module.exports = {
  experimental: {
    defaultLineHeights: true,
  },
}

Define a default font-family

In most cases, you'll have a default font-family that's used accross the website by default.

If you added the font-sans class to the body or a parent element, you can use

<p class="text-xl">Capsized Text</p>

Usage with @apply

Since the plugin outputs pseudo-elements, you'll need to use the experimental applyComplexClasses feature:

// tailwind.config.js
module.exports = {
  experimental: {
    applyComplexClasses: true,
  },
}

Which will allow you to use:

p {
  @apply capsize font-sans text-xl leading-7;
}

Root font-size

The plugin outputs the following inside the @tailwind/base:

html {
  font-size: 16px;
  --root-font-size-px: 16;
}

So overriding it from you css might mess up the trimming calculations.

To change the default root font-size:

// tailwind.config.js
module.exports = {
  theme: {
    capsize: {
      rootFontSizePx: {
        default: 16,
      },
    },
  },
}

You can also change the rootFontSize for each screen:

// tailwind.config.js
module.exports = {
  theme: {
    capsize: {
      rootFontSizePx: {
        default: 16,
        sm: 18,
        lg: 20,
      },
    },
  },
}

Limitation and Customization

  • Accepts rem and px for fontSize.
  • Accepts rem, px, and unitless for lineHeight.
  • Doesn't trim text on IE11 as it uses css variables for the trimming calculations. (will work on a JS polyfill or an average pre-calculation for all project fonts)
  • ~~Adds padding: 0.05px 0 to capsized element which will override your padding utility classes.~~ No longer the case from v0.3.0.

Behind the scenes

The plugin adds the following to typography-related utility classes:

To font-family classes, it adds css variables with font metrics:

.font-sans {
  font-family: Inter var, system-ui;
  --cap-height-scale: 0.7272;
  --descent-scale: 0.2414;
  --ascent-scale: 0.96875;
  --line-gap-scale: 0;
  --line-height-scale: 1.2102;
}

To font-size classes, it adds css variables for calculating the font-size in pixels:

.text-6xl {
  font-size: 4rem;
  --font-size-rem: 4;
  --font-size-px: calc(var(--font-size-rem) * var(--root-font-size-px));
}

To line-height classes, it adds css variables for calculating the line-height in pixels:

.leading-tight {
  line-height: 1.25;
  --line-height-unitless: 1.25;
  --line-height-px: calc(var(--line-height-unitless) * var(--font-size-px));
}

To the capsized element's pseduo selectors, it adds the trimming calculation:

.capsize::before {
  content: '';
  display: table;
  --line-height-normal: calc(var(--line-height-scale) * var(--font-size-px));
  --specified-line-height-offset-double: calc(var(--line-height-normal) - var(--line-height-px));
  --specified-line-height-offset: calc(var(--specified-line-height-offset-double) / 2);
  --specified-line-height-offset-to-scale: calc(
    var(--specified-line-height-offset) / var(--font-size-px)
  );
  --line-gap-scale-half: calc(var(--line-gap-scale) / 2);
  --leading-trim-top: calc(
    var(--ascent-scale) - var(--cap-height-scale) + var(--line-gap-scale-half) - var(--specified-line-height-offset-to-scale)
  );
  margin-bottom: calc(-1em * var(--leading-trim-top));
}

.capsize::after {
  content: '';
  display: table;
  --line-height-normal: calc(var(--line-height-scale) * var(--font-size-px));
  --specified-line-height-offset-double: calc(var(--line-height-normal) - var(--line-height-px));
  --specified-line-height-offset: calc(var(--specified-line-height-offset-double) / 2);
  --specified-line-height-offset-to-scale: calc(
    var(--specified-line-height-offset) / var(--font-size-px)
  );
  --prevent-collapse-to-scale: calc(var(--prevent-collapse) / var(--font-size-px));
  --line-gap-scale-half: calc(var(--line-gap-scale) / 2);
  --leading-trim-bottom: calc(
    var(--descent-scale) + var(--line-gap-scale-half) - var(--specified-line-height-offset-to-scale)
  );
  margin-top: calc(-1em * var(--leading-trim-bottom));
}

This port vs original Capsize

Aside from implementing the calculations via CSS variables to allow the usage of utility classes as illustrated above, I use a different method to prevent margin collapse that's not yet used in the original Capsize package ([email protected] at the time).

Capsize currently adds a 0.05 top and bottom padding to the capsized element to prevent margin collapse.

From v0.3.0, I implemented a new way to prevent the collapsing based on @michaeltaranto's findings in this issue that's not yet implemented in their Capsize.

Now, you can use padding classes on the capsized element:

<a href="#" class="capsize font-sans text-xl leading-tight px-2 py-4">
  Capsized Link with Padding
</a>

If you encountered any crossbrowser issue with the new prevent collapse implementation, you can reverse back to the original implementation with padding:

// tailwind.config.js
module.exports = {
  theme: {
    capsize: {
      keepPadding: true,
    },
  },
}

cap-height (since v0.4.0)

Instead of setting the font-size, you can use cap-height to declare the height of a the capital letters, and it'll automatically set the font-size based on the fontMetrics.

This comes in handy when you have an icon next to the test and you want to visually balance their height.

<p class="font-sans cap-height-4">Capsized Text that's 1rem in height</p>

Default values

Default values are cut from the extendedSpacingScale feature flag. Found it unuseful to inclue the very small and very large values.

You can override the default values via:

module.exports = {
  theme: {
    // ...
    capHeight: {
      2: '0.5rem',
      2.5: '0.625rem',
      3: '0.75rem',
      3.5: '0.875rem',
      4: '1rem',
      5: '1.25rem',
      6: '1.5rem',
      7: '1.75rem',
      8: '2rem',
      9: '2.25rem',
      10: '2.5rem',
      11: '2.75rem',
      12: '3rem',
      13: '3.25rem',
      14: '3.5rem',
      15: '3.75rem',
    },
  },
}

line-gap (since v0.4.0)

line-gap goes hand in hand with cap-height to have predectible height.

If the following example wrapped to 2 lines. The total height of the element would be 3rem.

<p class="font-sans cap-height-4 line-gap-4">
  Capsized Text that's 1rem in height and has a 1rem line-gap
</p>

Default values

line-gap has the same default values as cap-height which you can override via:

module.exports = {
  theme: {
    // ...
    lineGap: {
      2: '0.5rem',
      2.5: '0.625rem',
      3: '0.75rem',
      3.5: '0.875rem',
      4: '1rem',
      5: '1.25rem',
      6: '1.5rem',
      7: '1.75rem',
      8: '2rem',
      9: '2.25rem',
      10: '2.5rem',
      11: '2.75rem',
      12: '3rem',
      13: '3.25rem',
      14: '3.5rem',
      15: '3.75rem',
    },
  },
}

You can also set default line-gap values for each cap-height similar to the defaultLineHeights experimental feature via:

module.exports = {
  theme: {
    // ...
    capHeight: {
      2: ['0.5rem', { lineGap: '0.5rem' }],
      3: ['0.75rem', { lineGap: '0.625rem' }],
      // ...
    },
  },
}