Letter Spacing
Utilities for controlling the tracking (letter spacing) of an element.
On this page
typography/letter_spacing
A live demo of this example follows.
letter_spacing.dart
View source
Open demo
WDiv(
className: 'flex flex-col gap-4',
children: [
WText('Tight letter spacing', className: 'tracking-tight'),
WText('Normal letter spacing', className: 'tracking-normal'),
WText('Wide letter spacing', className: 'tracking-wide'),
],
)
Basic Usage#
Use tracking-{size} to control the letter spacing of an element. The named steps are in em, exactly as in Tailwind: a multiple of the font size of the text they apply to, so the same class reads the same on a caption and on a headline.
WText(
'The quick brown fox jumps over the lazy dog.',
className: 'text-sm tracking-wide',
)
This spaces 14px text by 14 * 0.025 = 0.35 logical pixels.
Quick Reference#
| Class | Value | At 14px (text-sm) |
At 30px (text-3xl) |
|---|---|---|---|
tracking-tighter |
-0.05em | -0.7 | -1.5 |
tracking-tight |
-0.025em | -0.35 | -0.75 |
tracking-normal |
0em | 0 | 0 |
tracking-wide |
0.025em | 0.35 | 0.75 |
tracking-wider |
0.05em | 0.7 | 1.5 |
tracking-widest |
0.1em | 1.4 | 3.0 |
Which Font Size an em Uses#
Flutter's TextStyle.letterSpacing is in logical pixels, so Wind multiplies the em by the size the text actually renders at, in this order:
- The
text-*size in the same className, including a responsive or state variant (text-sm md:text-3xl). OnWText, atextStyle:font size wins over both, because it is what the text renders at. - The font size the element inherits from the nearest
DefaultTextStyle(a parentWDivwith atext-*class publishes one, and so does a Material ancestor). - Flutter's
kDefaultFontSize(14), the size unsized text paints at. The theme'sbaseis not used: no text paints at it unless aDefaultTextStylesets it, and the em has to match the glyphs.
WInput skips the second step: EditableText reads no DefaultTextStyle, so a field with no text-* size paints at Flutter's kDefaultFontSize (14) and its em resolves there.
The em is taken from the unscaled font size. Flutter scales fontSize by the accessibility TextScaler but leaves letterSpacing as written, so under large text the spacing is a smaller share of the glyph than the em says.
A WDiv or WButton resolves its tracking at its own font size and publishes the result in pixels, the way CSS computes letter-spacing. A child with a different text-* size inherits those pixels, not the em; give the child its own tracking-* when it should scale.
WDiv(
className: 'text-xs uppercase tracking-widest',
children: [
WText('Section'), // 12 * 0.1 = 1.2
],
)
Responsive Design#
Apply different letter spacing at different breakpoints using the standard sm:, md:, lg:, xl:, and 2xl: prefixes.
WText(
'Responsive Tracking',
className: 'tracking-normal md:tracking-wide lg:tracking-widest',
)
Dark Mode#
Use the dark: prefix to apply different tracking when the application is in dark mode.
WText(
'Dark Mode Tracking',
className: 'tracking-normal dark:tracking-wide',
)
Arbitrary Values#
If the built-in scale doesn't meet your needs, use bracket notation to apply custom values directly. An em value scales with the font size like the named steps; a px value or a bare number is logical pixels, as it is in leading-[24] and text-[20]. Both take a negative sign.
// -0.02em of 30px: letterSpacing -0.6
WText('Headline', className: 'text-3xl tracking-[-0.02em]')
// Exactly 3 logical pixels at any size
WText('Custom Spacing', className: 'tracking-[3px]')
Customizing Theme#
To retune the scale, override its keys through the tracking property in WindThemeData. The values are em multipliers, like the defaults: 0.05 is 5% of the font size, never 0.05 logical pixels.
WindThemeData(
tracking: {
'tight': -0.02,
'widest': 0.15,
},
)