Skip to content

Add fontVariantNumeric utilities - #2305

Merged
adamwathan merged 2 commits into
masterfrom
font-variant-numeric
Sep 3, 2020
Merged

Add fontVariantNumeric utilities#2305
adamwathan merged 2 commits into
masterfrom
font-variant-numeric

Conversation

@adamwathan

Copy link
Copy Markdown
Member

This PR adds a new set of utilities for the font-variant-numeric property:

Class Description
normal-nums Reset font-variant-numeric to normal
ordinal Enables the ordinal feature
slashed-zero Enables the slashed-zero feature
lining-nums Enables the lining-nums feature
oldstyle-nums Enables the oldstyle-nums feature
proportional-nums Enables the proportional-nums feature
tabular-nums Enables the tabular-nums feature
diagonal-fractions Enables the diagonal-fractions feature
stacked-fractions Enables the stacked-fractions feature

The exciting thing about how these are implemented is that they are composable in your HTML, so you can enable multiple font-variant-numeric features by adding multiple classes:

<p class="slashed-zero tabular-nums diagonal-fractions">
  12345
</p>

The normal-nums class can be used to reset things, usually used at a particular breakpoint:

<p class="slashed-zero tabular-nums diagonal-fractions md:normal-nums">
  12345
</p>

By default, only responsive variants are enabled for this new core plugin.

Design details

This was pretty challenging to implement and only works thanks to a magical tip from @davidkpiano. Here's what the CSS looks like:

.ordinal, .slashed-zero, .lining-nums, .oldstyle-nums, .proportional-nums, .tabular-nums, .diagonal-fractions, .stacked-fractions {
  --font-variant-numeric-ordinal: /*!*/;
  --font-variant-numeric-slashed-zero: /*!*/;
  --font-variant-numeric-figure: /*!*/;
  --font-variant-numeric-spacing: /*!*/;
  --font-variant-numeric-fractions: /*!*/;
  font-variant-numeric: var(--font-variant-numeric-ordinal) var(--font-variant-numeric-slashed-zero) var(--font-variant-numeric-figure) var(--font-variant-numeric-spacing) var(--font-variant-numeric-fractions);
}

.normal-nums {
  font-variant-numeric: normal;
}

.ordinal {
  --font-variant-numeric-ordinal: ordinal;
}

.slashed-zero {
  --font-variant-numeric-slashed-zero: slashed-zero;
}

.lining-nums {
  --font-variant-numeric-figure: lining-nums;
}

.oldstyle-nums {
  --font-variant-numeric-figure: oldstyle-nums;
}

.proportional-nums {
  --font-variant-numeric-spacing: proportional-nums;
}

.tabular-nums {
  --font-variant-numeric-spacing: tabular-nums;
}

.diagonal-fractions {
  --font-variant-numeric-fractions: diagonal-fractions;
}

.stacked-fractions {
  --font-variant-numeric-fractions: stacked-fractions;
}

The general idea here is that we build the actual font-variant-numeric property value out of CSS custom properties, and we use this incredible hack of setting a custom property to an empty comment to make it possible to provide a no-op default value for every "slot" in the final property value.

I've had to use /*!*/ rather than /**/ because most CSS minifiers will strip comments that don't start with a !.

Any properties that are incompatible with each other are assigned to the same CSS custom property, so the slots we are filling look like this:

font-variant-numeric: [ordinal] [slashed-zero] [lining-nums | oldstyle-nums] [proportional-nums | tabular-nums] | [diagonal-fractions | stacked-fractions]

...where every slot on its own is optional.

So magical.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant