TailwindCSS Capsize Plugin
tailwindcss-capsize is a TailwindCSS plugin that addresses the long-standing problem of inconsistent text alignment caused by the "extra space" in font bounding boxes, often referred to as leading-trim or text-box-trim. It leverages the Capsize library to generate utility classes that optically align text by adjusting content box edges to match the capital height and baseline of the font. The current stable version is 4.0.1, with patch releases occurring regularly and major versions typically aligning with significant updates to TailwindCSS itself, such as the recent v4 release. Its key differentiator is providing a robust, configuration-driven solution within the Tailwind ecosystem for precise typographic control, relying on `fontMetrics` specific to the fonts used in a project. This plugin is crucial for designers and developers aiming for pixel-perfect typography and consistent vertical rhythm in their web applications, overcoming browser inconsistencies in text rendering. It requires a `tailwindcss` peer dependency and ships with TypeScript types.
Common errors
-
Theme value for `fontMetrics` is missing or invalid for font: [font-name]
cause The `fontMetrics` object is not configured in `tailwind.config.js` or is missing metrics for a font family actively used with the plugin.fixAdd the `fontMetrics` object to your Tailwind theme, ensuring it contains the correct `ascent`, `descent`, `lineGap`, `unitsPerEm`, and `capHeight` values for each font family used. The keys in `fontMetrics` must match those in `fontFamily`. -
Property `--font-size` is undefined
cause The `.capsize` class is applied, but the required `font-size` or `line-height` utilities (which populate custom CSS properties in `modern` mode) are missing on the element or its ancestors.fixEnsure `font-family`, `font-size`, and `line-height` Tailwind utilities are applied to the element containing the `.capsize` class, or its ancestors, to correctly define the CSS custom properties (`--font-size-px`, `--line-height-unitless`, etc.) required by the plugin. -
TypeError: Cannot read properties of undefined (reading 'length') for theme values
cause Internal utilities assumed theme values would always be `string` typed, but in some cases, such as `fontSize` values defined as numbers in the theme, they may be `number`s. This issue specifically affects plugin logic.fixUpdate to `tailwindcss-capsize@4.0.1` or newer. This issue was addressed in patch release `v4.0.1` by improving internal handling of theme value types. -
Text truncation/clamping visually incorrect or broken when using .capsize
cause Text truncation or line clamping utilities (`truncate`, `line-clamp-N`) are applied directly to the element that also has the `.capsize` class.fixWrap the text content in a child `<span>` or similar element. Apply the `.capsize` class to the parent element, and apply the truncation/line-clamping utilities to the child element. Example: `<p class='capsize'><span class='truncate'>...</span></p>`.
Warnings
- breaking Upgraded for Tailwind CSS v4, which involved significant changes to plugin configuration and capabilities. The plugin no longer disables `corePlugins` like `fontSize` directly, leading to duplicate CSS declarations in the output if custom properties are included in the same utilities.
- breaking The default `modern` output mode was introduced, which replaces Tailwind's core `fontFamily`, `fontSize`, and `lineHeight` plugins with custom property-enabled versions. This changes the underlying CSS output for these utilities.
- breaking The plugin adopted the new `@capsize/core` library, which simplified the leading trim technique. This change *will* alter the final output CSS, requiring re-evaluation of design systems for visual consistency.
- gotcha Applying text truncation or line clamping utilities (e.g., `truncate`, `line-clamp-N`) directly to an element with the `.capsize` class can cause rendering issues because `.capsize` uses `::before` and `::after` pseudo-elements to perform the leading trim.
- gotcha The plugin requires a `fontMetrics` key in your Tailwind theme configuration, with specific `ascent`, `descent`, `lineGap`, `unitsPerEm`, and `capHeight` values for each `fontFamily` entry. Without these, the plugin cannot calculate correct leading trim values.
- gotcha The `.capsize` utility class must be applied to the *direct parent* of the text node. Additionally, `font-family`, `font-size`, and `line-height` utilities must be applied somewhere in the cascade above the `.capsize` element for the required custom properties to be available.
Install
-
npm install tailwindcss-capsize -
yarn add tailwindcss-capsize -
pnpm add tailwindcss-capsize
Imports
- default
const pluginCapsize = require('tailwindcss-capsize')import pluginCapsize from 'tailwindcss-capsize'
- CapsizeOptions
import type { CapsizeOptions } from 'tailwindcss-capsize'
Quickstart
// tailwind.config.ts
import type { Config } from 'tailwindcss';
import pluginCapsize from 'tailwindcss-capsize';
import type { CapsizeOptions } from 'tailwindcss-capsize';
const config: Config = {
content: ['./index.html', './src/**/*.{js,ts,jsx,tsx}'],
theme: {
extend: {
fontFamily: {
sans: ['Inter', 'sans-serif'],
},
fontMetrics: {
// These values should be obtained from your font files using tools like Capsize website, fontkit, or FontDrop!
// The keys here MUST match those defined in your `fontFamily` object.
sans: {
capHeight: 2048,
ascent: 2728,
descent: -680,
lineGap: 0,
unitsPerEm: 2816,
},
// Add metrics for other font families you use, e.g., serif: {...}
},
},
},
plugins: [
pluginCapsize({
// Optional: Adjust rootSize if your HTML root font-size is not 16px
rootSize: 16,
// Optional: Customize the utility class name from 'capsize' to something else
// className: 'leading-trim-active'
} as CapsizeOptions), // Casting helps ensure type safety for plugin options
],
};
export default config;
// index.html or a React/Vue component usage
/*
<style>
@tailwind base;
@tailwind components;
@tailwind utilities;
</style>
<div class="p-8">
<p class="font-sans text-xl leading-relaxed capsize">
<span>This text will have precise optical alignment due to Capsize.</span>
</p>
<p class="font-sans text-base leading-normal capsize">
<span>Another example of precisely aligned text.</span>
</p>
<p class="font-serif text-lg leading-tight capsize">
<span>Even serif fonts can benefit from leading-trim.</span>
</p>
</div>
*/