Yeah yeah, naming CSS custom properties (CSS variables) or Sass variables is hard. But even that is not the full picture. In ideal world
Let’s start with typography related CSS variables. I sometimes see that font sizes and line heights are just thrown in the mix and hope for the best. That never ends well.
Typography in design systems is excellent article what I’m talking about. Go read that first.
My current approach is to use T-shirt sizing and it works OK. Here is simplified example:
/* Font families. */
--font-family-sans: "Roboto", sans-serif;
--font-family-serif: "Playfair Display", serif;
/* Font sizes. */
--font-size-sm: 0.875rem;
--font-size-md: 1rem;
--font-size-lg: 1.125rem;
--font-size-xl: 1.25rem;
--font-size-2xl: 1.5rem;
--font-size-3xl: 2rem;
--font-size-4xl: 3rem;
/* Line heights. */
--line-height-sm: 1.25;
--line-height-md: 1.5;
/* Letter spacings. */
--letter-spacing-sm: 0.05em;
--letter-spacing-md: 0.1em;
/* Use CSS variables later. */
body {
font-family: var(--font-family-sans);
font-size: var(--font-size-lg);
line-height: var(--line-height-md);
}
h1,
.h1 {
font-family: var(--font-family-serif);
font-size: var(--font-size-3xl);
line-height: var(--line-height-sm);
}
h2,
.h2 {
font-family: var(--font-family-serif);
font-size: var(--font-size-2xl);
line-height: var(--line-height-sm);
}
Using T-shirt sizing hasn’t been huge issue in my experience. It’s more about “let’s add another font-size and especially another line-height”. Then it needs some search and replace in the code base.
I think adding new line-height for every font-size stems from design tools where line-height unit is px
or pt
.
At least I pretty much always get handed values like 16 / 24. Which means 16px font-size and 24px line-height.
But since using relative units are preferred for better accessibility, developers convert these as follows:
Then we need to account that some of the font-sizes are larger on bigger screens, there are some uppercase subtitles etc.
As a summary, there is nothing wrong using T-shirt sizing. It’s more about fragile system for typography, too many ways to mess it up with too many variations, and collaboration between developers and designers.
I’m open for new ideas, fine tuning current approach, and test something like typography presets.
Since font-size, line-height, uppercase, and letter-spacing walks hand in hand, it makes perfect sense to bundle them together as typography presets.
body,
.text-preset-1 {
font-family: var(--font-family-sans);
font-size: var(--font-size-lg);
line-height: var(--line-height-md);
}
h1,
.text-preset-2 {
font-family: var(--font-family-serif);
font-size: var(--font-size-3xl);
line-height: var(--line-height-sm);
}
h2,
.text-preset-3 {
font-family: var(--font-family-serif);
font-size: var(--font-size-2xl);
line-height: var(--line-height-sm);
}
...
.text-preset-7 {
font-family: var(--font-family-serif);
font-size: var(--font-size-sm);
letter-spacing: var(--letter-spacing-sm);
text-transform: uppercase;
}
7-9 presets should be enough for most sites and applications. In this system, named from 1 to 7, presets are not necessary in font-size order anymore. Adding new option in the end with number 8 would do the trick no matter what is the new font-size.
Couple of notes, me thinking out loud:
text-1
, text-2
etc.text-100
, text-200
, and then we would be able to add new preset in between (text-150
) and keeping the font-size order.body
, h1
, h2
etc. with presets so we would have defaults for HTML elements also..font-semibold
.The key idea is that developers and designers would quickly see that here are all the typography presets what we have in this project.
And stick using only those with new components, sometimes adding a new one.
Maybe clamp() for some day but would need more testing with user zooming or user changing default font size. In current method I change the font-size in the variable itself:
:root {
--font-size-sm: 0.875rem;
--font-size-md: 1rem;
--font-size-lg: 1.125rem;
--font-size-xl: 1.25rem;
--font-size-2xl: 1.5rem;
--font-size-3xl: 2rem;
--font-size-4xl: 2rem;
}
@media (min-width: 56em) {
:root {
--font-size-xl: 1.5rem;
--font-size-2xl: 2rem;
--font-size-3xl: 2.5rem;
--font-size-4xl: 3rem;
}
}
I’d need to test does that make sense when using using presets.
As a conclusion I like the presets idea. Let the test begin!