I had the following things to keep in mind:
- the designers provided me font-sizes defined in
px
while I wanted to userem
. - There were multiple themes, so the font sizes and line heights differ per theme.
At first I had to write a mixin that returned font-size
and line-height
properties, and converted pixel values to rem values:
@mixin fontsize-lineheight($font-size, $line-height, $base: 16px) { $remsize: ($font-size / $base); font-size: #{$remsize}rem; line-height: $line-height / $font-size; }
However I wanted line-height
to be unit-less, so I had to convert the variables to unit-less values using the following @function
:
@function strip-units($value) { @return $value / ($value * 0 + 1); }
(source: this Stackoverflow answer)
So the final result of the mixin was:
@mixin fontsize-lineheight($font-size, $line-height, $base: 16px) { $remsize: (strip-units($font-size) / strip-units($base)); font-size: #{$remsize}rem; line-height: strip-units($line-height / $font-size); }
Now this mixin was ready to use for every heading:
h1, .h1 { @include fontsize-lineheight(30px, 40px); @include media-breakpoint-up(md) { @include fontsize-lineheight(40px, 50px); } @include media-breakpoint-up(lg) { @include fontsize-lineheight(60px, 72px); } } // ....and so on
This still looks quite repetitive, so I made a map containing lists for the font sizes and line heights, like this:
// font-sizes, from left to right: // lg md sm $heading-sizes: ( h1: 72px 48px 36px, h2: 48px 32px 30px, ... ); $heading-lineheights: ( h1: 72px 48px 36px, h2: 48px 36px 30px, ... );
Every entry in the map can be accessed with map-get
, for example:
$font-size-h1: map-get($heading-sizes, h1);
And every entry in a list can be accessed by its index (1-based) using nth
, for example:
$font-sizes-h1: map-get($heading-sizes, h1); $font-size-h1-md: nth($font-sizes-h1, 2);
So all of the above can be combined into the following mixin:
@mixin heading($heading) { $sizes: map-get($heading-sizes, $heading); $line-heights: map-get($heading-lineheights, $heading); @include fontsize-lineheight(nth($sizes, 3), nth($line-heights, 3)); @include media-breakpoint-up(md) { @include fontsize-lineheight(nth($sizes, 2), nth($line-heights, 2)); } @include media-breakpoint-up(lg) { @include fontsize-lineheight(nth($sizes, 1), nth($line-heights, 1)); } }
So putting everything together the final result is:
@function strip-units($value) { @return $value / ($value * 0 + 1); } @mixin fontsize-lineheight($font-size, $line-height, $base: 16px) { $remsize: (strip-units($font-size) / strip-units($base)); font-size: #{$remsize}rem; line-height: strip-units($line-height / $font-size); } @mixin heading($heading) { $sizes: map-get($heading-sizes, $heading); $line-heights: map-get($heading-lineheights, $heading); @include fontsize-lineheight(nth($sizes, 3), nth($line-heights, 3)); @include media-breakpoint-up(md) { @include fontsize-lineheight(nth($sizes, 2), nth($line-heights, 2)); } @include media-breakpoint-up(lg) { @include fontsize-lineheight(nth($sizes, 1), nth($line-heights, 1)); } } $heading-sizes: ( h1: 72px 48px 36px, h2: 48px 32px 30px, h3: 36px 30px 24px, h4: 30px 24px 20px, h5: 24px 20px 18px, h6: 20px 18px 16px ); $heading-lineheights: ( h1: 72px 48px 36px, h2: 48px 36px 30px, h3: 42px 36px 30px, h4: 36px 30px 24px, h5: 30px 24px 21px, h6: 24px 21px 18px ); $headings: h1 h2 h3 h4 h5 h6; @each $heading in $headings { #{$heading}, .#{$heading} { @include heading($heading); } }
If you have any reactions please leave them in the comments section below!