Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add fontVariantNumeric utilities #2305

Merged
merged 2 commits into from
Sep 3, 2020
Merged

Add fontVariantNumeric utilities #2305

merged 2 commits into from
Sep 3, 2020

Conversation

adamwathan
Copy link
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.

None yet

1 participant