DEV Community

Nic
Nic

Posted on • Originally published at blog.nicm42.co.uk on

Converting px in SCSS

A lot of the time in designs they give the font-size, line-height and letter-spacing in px. Which isn't helpful as they mean having to get the calculator out to convert them to more useful units. But a combination of Sass functions and mixins can do the calculations for us.

Converting font-size

Here we want to use rems. This function is from https://dev.to/rekomat/comment/1ib3b:

// From https://dev.to/rekomat/comment/1ib3b
@function pxToRem($pxValue) {
  @return math.div($pxValue, 16px) * 1rem;
}
Enter fullscreen mode Exit fullscreen mode

This is literally doing the same calculation as we do on the calculator: font-size divided by 16px and then written in rems. If your base font size has been set to 10px (for example) then you'd need to change the 16px in the function to be 10px.

You can use this function to convert anything from px to rem, not just font-sizes.

Converting line-height

Here we do exactly the same as on the calculator to get a ratio:

@function convertLineHeight($fontSize, $lineHeight) {
  @return math.div($lineHeight, $fontSize);
}
Enter fullscreen mode Exit fullscreen mode

Converting letter-spacing

And again it's the same calculator calculation and expressed in ems:

@function convertLetterSpacing($fontSize, $letterSpacing) {
  @return math.div($letterSpacing, $fontSize) * 1em;
}
Enter fullscreen mode Exit fullscreen mode

Using the functions

To use those three functions we'd do this:

p {
  font-size: pxToRem(24px);
  line-height: convertLineHeight(24px, 30px);
  letter-spacing: convertLetterSpacing(24px, -0.48px);
}
Enter fullscreen mode Exit fullscreen mode

Which is fine, but we have to give all three of them the font-size. We can use a mixin to make this more efficient:

@mixin textUtils($fontSize, $lineHeight: 1, $letterSpacing: 0) {
  font-size: pxToRem($fontSize);
  @if $lineHeight != 1 {
    line-height: convertLineHeight($fontSize, $lineHeight);
  }
  @if $letterSpacing != 0 {
    letter-spacing: convertLetterSpacing($fontSize, $letterSpacing);
  }
}

p {
  @include textUtils(24px, 30px, -0.48px);
  //@include textUtils(24px, 30px);
  //@include textUtils(24px);
}
Enter fullscreen mode Exit fullscreen mode

This mixin is set up so it needs the font-size, but it doesn't matter if you don't give it the letter-spacing, because that could be 0. And just in case, it also works if you don't give it the line-height.

Top comments (2)

Collapse
 
webjose profile image
José Pablo Ramírez Vargas

What's the meaning of the 16px constant? Is it really constant, or is just the "popular" value?

Collapse
 
nicm42 profile image
Nic

16px is the default size of text in most browsers, so that's what the designs will have assumed is the case.