Mixins for Rem Font Sizing
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;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.
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.
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
emas a fallback instead ofpx, and then using two separate mixins? A lot of my site work now only usesems, andpxin 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)
@basefont: 16; html { font-size : ((@basefont * 100) / 16) + 0%; } .font-size (@size) { font-size: (@size * @basefont) + 0px; font-size: @size + 0rem; }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
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) }