The rem
font-size unit is similar to em
, only instead of cascading it’s always relative to the root (html) element (more information). This has pretty good modern browser support, it’s just IE 8 and down we need to provide px
fallbacks for.
Instead of repeating ourselves everywhere, we can use a LESS or SASS mixins to keep it clean. These mixins assumes:
html {
font-size: 62.5%; /* Sets up the Base 10 stuff */
}
.font-size(@sizeValue) {
@remValue: @sizeValue;
@pxValue: (@sizeValue * 10);
font-size: ~"@{pxValue}px";
font-size: ~"@{remValue}rem";
}
@mixin font-size($sizeValue: 1.6) {
font-size: ($sizeValue * 10) + px;
font-size: $sizeValue + rem;
}
Usage
p {
.font-size(13);
}
p {
@include font-size(13);
}
(Thanks Gabe Luethje)
Another SCSS one with a different approach by Karl Merkli:
@function strip-unit($num) {
@return $num / ($num * 0 + 1);
}
@mixin rem-fallback($property, $values...) {
$max: length($values);
$pxValues: '';
$remValues: '';
@for $i from 1 through $max {
$value: strip-unit(nth($values, $i));
$pxValues: #{$pxValues + $value*16}px;
@if $i < $max {
$pxValues: #{$pxValues + " "};
}
}
@for $i from 1 through $max {
$value: strip-unit(nth($values, $i));
$remValues: #{$remValues + $value}rem;
@if $i < $max {
$remValues: #{$remValues + " "};
}
}
#{$property}: $pxValues;
#{$property}: $remValues;
}
So you can do:
@include rem-fallback(margin, 10, 20, 30, 40);
and get:
body {
margin: 160px 320px 480px 640px;
margin: 10rem 20rem 30rem 40rem;
}
I fond less escaping ugly so in cases like this I use
font-size: @pxValue*1px;
Defining both the px value and rem value would the browser show both or would it cancel the one it dosent need.
Also if the browser supports both rem and pixels which one would it use in that case.
Thanks,
Raj
It would use the last declared font-size in your css (css rule). Which is why it’s always good to arrange font-size declaration in px then rem
This way, if rem is supported, it would override px.
and if you really, really lazy (like me) throw in a little love for the line-height & add a basic 1.5 multiplier
SASS is just öwesome
a quick node remember to put in the value as its an em not px ;)
.foo{ @include fontsize:(1.5, 2);
Ha! I knew it was only a matter of time before we would start seeing preprocessor code here.
Thanks Chris and Gabe.
For more robust sizing, These are the mixins I use:
Rem by bitmanic and, in extreme cases, I use Scale, by mrdanadams.
Keep ’em coming.
Don’t forget Stylus!
Mixin:
Usage:
*correction
Tab spacing issue.
*a more transparent method below
usage
yields
Thank you for this!
Strangely it was outputting higher values (240px / 24rem instead of 24px / 2.4rem) so I modified it slightly for my uses:
Surprised no-one commented when you fixed the math.
I’ve been using rems haphazardly, but now trying to implement them properly before my next update.
Is the value in the top example wrong?
If $sizeValue: 1.6, then the value should be font-size(1.3) not font-size(13). That would explain Jonah’s issue.
SASS noob so apologies if I’m completely wrong.
Line-height would be best applied unit-less, no?
Shouldn’t the mixing be more like this:
@mixin font-size($sizeValue: 1.6){
font-size: ($sizeValue) + px;
font-size: ($sizeValue/10) + rem;
}
Hi.
I aded the mixin as yo wrote but in the ouputet code, there only appears:
Shouldn’t it be
?
My Mixin:
And the included snippet.
Where is the error?
I’ve just created a collection of {less} mixins to help you converting pixels values to rem. The collection include support for font, margin, padding and position properties. I created them because it seems there’s nothing similar to support coders like me, that make heavy use of rem units Find out more at: https://github.com/christopher-ramirez/remixings
For those using Sass, I wrote a mixin to handle rem conversions a while back (originally forked from @bitmanic’s). I stumbled on this post looking for something unrelated, but thought others might find it useful.
Nice mixin Ryan. Just gave it a whirl for the first time and it works very nicely. I particularly like the fact that it accepts both rems and pixels as arguments. Many thanks.
Any word on when this may be rolled into Compass?
Hello,
I was wondering if it wouldn’t be better to invert your solution to
I just assume that most of us think and work on our designs in pixels (especially with Photoshop) so it might be more intuitive to provide the pixel value and then calculate the rem rather than the other way around.
It’s a matter of preference of course. Maybe if (when) I get as advanced as you I’ll start thinking in rems? :) (binary anyone?)
Hi,
Just wondering if anyone has converted this code to work with stylus, I have taken and tried to convert but not having any luck.
Thanks
Hey everyone!
What about a mixin with body font-size at 100%?
Would you just divide by 16 instead?
Sorry but not a hawk at math
Hey guys,
Are there any thoughts about using
em
as a fallback instead ofpx
, and then using two separate mixins? A lot of my site work now only usesem
s, andpx
in rare cases, so I’m thinking about a mixin like this:.font-size(@sizeValue, @baseFontSize: 16){
@remValue: @sizeValue;
@pxValue: (@sizeValue * 10);
@emValue:((@pxValue / @baseFontSize));
font-size: ~"@{emValue}em";
font-size: ~"@{remValue}rem";
}
@Sean The only advantage of rem over em is that it is more predictable, being relative to the font-size of rather than the font-size of the current element. If you’re going to go ahead and deal with ems, just use ems alone. The whole reason for fallbacks for rem is that rem isn’t well-supported by older browsers. ATM, it’s a case of ‘choose one’: use rems for predictability and maintainability of code, but have to provide fallbacks in px, or just go with ems and mind your font sizes.
Gah, stripped tags. That should read: “em is that it is more predictable, being relative to the font-size of html rather than the font-size of the current element.”
I am a noob to Sass and have not implemented much beyond the basic functionality of mixins and variables. This is an awesome/efficient use of writing my rem fallback for font size, but, does anyone have suggestions as to how I might create something a bit more universal? i.e. I want to use rem (with a base sizing as shown above/as in http://snook.ca/archives/html_and_css/font-size-with-rem) and not have to write a fallback for things such as line height, padding, margin, text-indent etc.?
@Peter Marty I’ve written a Sass mixin for that kind of general use: https://github.com/ry5n/rem.
I have a solution for outputting rems with a px fallback on any property:
https://gist.github.com/4153104/a5f13471af86e9835f18beda817ed772fcd9973a
One of the advantages or rems is that you can rescale the whole style by changing the base-size on html. However, when using this mix-in this would break the px-values.
After some thinking I came up with this piece of code which allows you to add font-sizes relative to the base font-size and lets you change that base whenever needed (either with a redesign or when using different fontsizes for different media-types)
A little late but I just read this and created something for Sass that plays nice with the vertical rhythm tools supplied with Compass.
https://gist.github.com/4526784
It also contains a
rel()
function for calculating px to em for everything else.. .. i also don’t get comfortable with the 62.5% value… the browser is set to 100% by default so why not leave it like that and just change the divider to 16 when the result is the same…. :)
I’ve found that functions keep the styles more readable than mixins, so I wrote a few, and I’m pretty happy with the results. Unitize is a SASS partial that turns:
into:
I like the idea of this mixin, but i’m finding that this cuts out using shorthand.
font: italic 100 2rem/2 $font;
How can we apply this technique without having to undo the shorthandedness of it:
font-size: 2rem;
font-size: 20px;
font-weight: 100;
line-height: 2;
font-family: $font;
etc
I agree, mixins are supposed to save time. I think the best solution is just go with rem for everything and use this Rem polyfill.
What I use for px2em (can’t remember whom to give creds about that) is:
$font-size: 1em !default;
@function em($pxval, $base: 16px) {
@return ($pxval / $base) * $font-size;
}
p { font-size: em(22px) }
For stylus fans I created a small script, based on what Karl Merkli did. Script
// License MIT
// Author: Jorge Avila jorge.e.avila@gmail.com
I got a basic Stylus REM mixin going:
View on github
Forgot to add the result, here it is:
Thanks for the post. This inspired the following mixin that will take a list of whatever properties with an rem/em value and create a px fallback.
Usage:
Other:
Notice the “* 16px” in the mixin? If your base em unit is not 16px, change that.
If anyone is looking for a more comprehensive / refactored version of my mixin above, I hope you find the following useful. It includes a strip-unit() function, an rem() function, and a similar rem mixin to the above.
Usage:
Output:
Sorry, math mistake. Line 8 of @function rem should be…
For those interested, I created a family of functions to handle dimension calculations. The rem function and mixin are included.
Behold: sass-dimension
A handful of handy functions that provide a common, convenient interface for dimension calculations.
I’ve also started on a grid system, because it seemed to be a good test case for the dimension functions. I must admit that I’ve not used enough of the other grids to know all their merits or if mine is better, but I’m starting to prefer it over Susy or Foundation (although certainly not production-ready).
Can someone please tell me what the below line of code does?
Scratch my previous question. Just understood what strip-unit function does.
For me, It is easier to pass a pixel based parameter and have Sass convert it to Rem.
I can still think pixel but my code outputs Rems.
This ought to return
If px fallback are not needed for the website you work on, Karl’s mixin can be shortened to
There’s a similar emCalc function available in Zurb’s Foundation but this one is way more powerful!
That’s exactly what the library I posted does, except you can pass any type of unit to the mixin and it will output a px fallback with an rem value also set.
In other words, if 1rem = 1em = 16px…
Would output:
Notice that px, rem, and em units are passed to the mixin, but only px fallbacks and rem’s dimensions are created.
I actually renamed the sass-dimension library to sass-unity, because it’s all about having a common interface for calculating/converting units. It has a “unity” function that normalizes a list of units:
I know it’s easier to think in pixels right now, because we have for so long, but we might ought to be thinking in scales from the conception of the code. We might ought to be thinking, “This box should be 4 times a variable baseline (16), not always 64 (4×16).”
It’s been difficult for me to know what the devices will expect of us. DPI is one of the marketing battles, and readability is slightly important, so I think even those of us that haven’t converted have a sneaking suspicion that pixels are a little too rigid; however, I also feel that em’s are too unstable to use for dimensions (mainly height and width). With rem, we can have a pivotal anchor, rather than binding (px) or unpredictable (em).
Based on Karl Merkli’s approach above, this little ditty allows base-10 calculations while maintaining the browser default font-size (the assumed 16 pixel default)…cause math sucks. It also does not require a ‘strip-unit’ directive.
See the gist.
You should multiply the unitless value by 1 unit instead of appending the unit directly which results in a string.
I wrote a short blog post about it today.
Chris I think in usage there is error no ? Should be :
.font-size(1.3);
instead of
.font-size(13);
Isnt it ?
Because it looks gigantic in my website if 13. And mixin mutliply by 10…
Or I am missing something here ! :D
@migswd: to use .font-size(13), you need to adjust the mixins into:
Hey guys! I found the rem-fallback mixin really awesome, but it didn’t handle values like “auto”, would turn “em” values into “rem”s, and I’ve no idea how it would handle a percentage. To compensate, I modified the mixin and made it a little more terse. Hope it helps some other folks out there!
Hey – Correct me if I’m wrong. But shouldn’t the example less mixin be:
and
The example uses px but the the mixin is multiplying the value instead of dividing it.
Victor – correct for the less mixin.
However, WHY are we setting html to 62.5%? I could understand it if we were having to do aritmetic on paper or with a calculator – we are not doing any arithmetic – less, sass or stylus is doing the work.
All we need to remember is, that no matter what we set our HTML to the pixel value will equal 1 rem.
16px (100% on html) means 16px = 1 rem
Therefore, our mixin (for less) becomes:
Do we need to make things so complicated? Or am I totally missing the point here?
My attempt to less mixin using some variables.
Old topic but perhaps useful to someone else:
@mixin rempx($value){
font-size: $value + px;
font-size:($value / 10) + rem;
}
p{
@include rempx(16);
}
So the examples assume that you want to set the paragraph to font size 130px?
Great work here, as always, and thanks for your constant inspiration! I have a question about responsive development with rem:
Snook’s famous article shows changing the root font-size at each breakpoint, but a function like this would have to be adjusted each time, because it uses 1.6 as the base, correct? How can we build something like this that will also allow for changing the root font-size at different resolutions?
I think you can use media queries to adjust the root font-size easily.
Hi guys just wanted your opinion on this sass mixin, with it you dont have to set the html font-size to 62.5%
Thanks. Makes perfect sense. Awesome
Dat SCSS include didn’t work fer me. But this one did:
@include font-size(1.4);
What’s the dilly?
The example @include is wrong, the mixin function in the example goes on the basis you enter a rem value, not a px value(like the example @include did). To use px in your @include statement your need to adjust the base value from 1.6 to 16, divide rem by 16 and take out the * 10 part for the px’s ^^
Hi,
I found a scss code on the web and customized it.
First:
With the mixin we can convert this:
To:
But i added some features.
1. Convert it only to pixels.
To:
Convert it only to rem
Convert it to pixels and rem.
But when i give each variable the value ‘false’, then it will give me an error (on codepen.io).
Its mayby not the most wanted feature, but it is for a css framework. And it is mayby useful for others, or for learning scss (how to use the if-else statements to build advanced scss mixins.)
~ Sorry for my bad English.
Sorry fogot to put the codepen link.
http://codepen.io/cyrildewit/pen/YwvErx
sass version of px to rem…
sass version
less version
The LESS mixin made my fonts become huge, so I changed it around.
From this:
@remValue: @sizeValue;
@pxValue: (@sizeValue * 10);
To this:
@remValue: @sizeValue / 10;
@pxValue: (@sizeValue);
And kept the rest as is.
Hi, your mixin is usefull, but I’m using my own.
My mixin is can set perfect linę-height and max-width counted by diffeent font-size. It’s really usefull and easy for development, because to active option we need to write 1 or yes :)
I think this is my best mixin.
Hi all,
I’m using Karl Merkli’s approach.
I have a question, if my 16px font-size becomes 14px on mobile devices, how can I calculate the rem on 14px?
Thanks
Max