DEV Community

Cover image for Convert px to rem Using Sass - 3 methods
Nikola Betica
Nikola Betica

Posted on • Updated on

Convert px to rem Using Sass - 3 methods

By now, you probably figured out what rem units are and why you should use them. But, the tricky part is to calculate them (at least, in your head). Luckily, using Sass, it's really easy to convert any value into rem, and we can achieve that in 3 ways or methods, using mixins and functions.
 

Method 1 - using a @mixing with predefined property

Let's say we have a 400px wide div, but we want to convert that width value to rem. The easiest way would be by using a mixin with predefined property. We know 1rem equals to 16px, and our div is 400px wide, so the basic calculation is: 400 divided by 16. To calculate it with Sass, we could create a simple mixin like this:

@mixin width($value) {
    width: ($value / 16) + rem;
}

div {
    @include width(400);    
}
Enter fullscreen mode Exit fullscreen mode

This method works well, but the problem is - you have to define a new mixin for every property. That could easily spun out of control. But if you only have a few mixins, it could work. After all, it's the easiest method.
 

Method 2 - using a @mixing with 2 arguments

To avoid creating a new mixin for every property, we could create a mixin with 2 arguments - CSS property and value. Note that a property statement is not a number, so we have to convert it to string by wrapping it into #{}.

@mixin toRem($property, $value) {
    #{$property}: ($value / 16) + rem;
}

div {
    @include toRem(width, 400);
}
Enter fullscreen mode Exit fullscreen mode

This method is much more flexible, but for every new CSS property we have to use a new @incude call. Unfortunately, we can call only one set of arguments per @incude. That could potentially lead to a readability problem, for example:

@include toRem(width, 400);
@include toRem(height, 400);
@include toRem(font-size, 16);
@include toRem(margin, 20);
//etc
Enter fullscreen mode Exit fullscreen mode

 

Method 3 - using a function

Third method is by using a Sass @function. Unlike mixin, which in previous methods "generated" CSS, our function will only calculate the value. In a function, we have to use @return rule to indicate the value to use as the result of calling that function. We can use that function with any property.

@function toRem($value) {
    $remValue: ($value / 16) + rem; 
    @return $remValue;
}

div {
    width: toRem(400);
    height: toRem(400);
}
Enter fullscreen mode Exit fullscreen mode

Although this method surely seems like a number one go-to method, remember that a function only generates a value.
 

Which method to use?

Well, I'd say, try all three. They all have their advantages and limits, so check a pen below with all of the examples, and experiment... It's up to you to decide which one suits your purpose the best.

If you liked this article, consider buying me a coffee.

Discussion (5)

Collapse
rekomat profile image
René Keller

Thanks Nikola! No matter which of the three methods you prefer, I would suggest two improvements.

  1. Convert the value instead of adding the unit.
// Add unit to value
font-size: 1 + rem + 1rem; // → string '1rem1rem'
// Convert unit
font-size: 1 * 1rem + 1rem; // → 2rem
Enter fullscreen mode Exit fullscreen mode
  1. Use math.div for division instead of / operator as using / for division is deprecated and will be removed in Dart Sass 2.0.0.
@use 'sass:math';

@function pxToRem($pxValue) {
    @return math.div($pxValue, 16px) * 1rem; 
}

div {
    width: pxToRem(400px); // → 25rem
}
Enter fullscreen mode Exit fullscreen mode
Collapse
itpretty profile image
itpretty

Many thanks for the inspiring methods :)

Wonder if would be possible to make the 16 in $remValue: ($value / 16) + rem; dynamic, say some var --baseline defined at :root? The scenario is 16 can change based on @media query of CSS.

Regards :)
Riting

Collapse
safderareepattamannil profile image
Safder Areepattamannil

Great article! If you use visual studio code there is a great extension called px to rem & rpx (cssrem) that I use regularly for dynamically converting sizes.

Collapse
canadianeagle profile image
T

This was a very clutch suggestion! Thanks

Collapse
sheikhrashed profile image
Sheikh Rashed

very informative, I already using method 3