Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Loading…

Add rem unit mixin for font-size #187

Closed
wants to merge 2 commits into from

9 participants

@renaudleo

This mixin allows easier use of rem units when working with font-size. Rem gives user resizable text, just like em units, without the hassle of compounding font-sizes. More info about the advantages of using rem over em or px can be found here: http://snook.ca/archives/html_and_css/font-size-with-rem

As rem is not supported by IE8 and lower (http://caniuse.com/#search=rem), we still need to provide a pixel fallback, hence the need for a mixin. The easiest way to work with this is to set font-size: 62.5% on the html or body tag, wich gives us a nice 1rem == 10px relation to work with.

The usage is:

h2 {
  @include rem(18);
}

wich outputs:

h2 {
  font-size: 18px;
  font-size: 1.8rem;
}

Let me know what you think!

@plapier

I like the idea of this. I guess the bourbon docs would have to enforce the use with the body set to font-size: 62.5%. I wonder if we can tie this more tightly together? Is there ever a case where you would want to change the body font-size to something different with the use of this mixin?

@renaudleo

Yeah, the docs would have to clearly state that you need to set the font-size to 62.5%.

Maybe we could add a second argument to use as a modifier for someone who wants to use the mixin with a different base font-size. The thing is you'll have to pass it along every time you call the mixin, so I doubt anyone would want to go that way.

@wingrunr21

I'd like to +1 this.

One caveat with setting font-size to 62.5% is that it affects a lot of bourbon/neat's default calculations. If people are going through and moving to rems then they may have to do that anyway, but it would be nice if the docs gave a warning.

@renaudleo

Maybe the ideal way of dealing with this is assuming the base font-size is the default 100% and change the rem calculations according to this. The only caveat is you'll see all kind of weirds font-size when debugging, but you'll still have the pixel fallback, wich should be enough to understand what's going on.

@kerns

Just curious what the status of this rem mixin proposal is ...and in general terms, wondering which elements (mixins) already in bourbon or neat could help someone looking for an air tight, modularly scaled rem based workflow.

@renaudleo

What do you guys think of this update? I changed the mixin so it assumes you're using the default 100% font-size so it doesn't break other bourbon/neat's default calculations as @wingrunr21 pointed out. The px-to-em mixin, for example.

Still, I added a second param to the mixin to allow someone using a different % font-size to use it.

So now, doing:

h2 {
  @include rem(18);
}

would output:

h2 {
  font-size: 18px;
  font-size: 1.125rem;
}

If your base font-size is 62.5%, you could call the mixin that way:

h2 {
  @include rem(18, 62.5);
}

which would output:

h2 {
  font-size: 18px;
  font-size: 1.8rem;
}

I think it will make it easier for someone to just start using the mixin on an existing project without having to add font-size: 62.5% on the html tag and having to rewrite all of the font-size previously set.

Let me know what you think. If this version of the mixin is fine for everyone I could rewrite the pull request's history.

@kerns

I like it – but it raises broader questions for me about bourbon's "typography toolchain"...for lack of a better word.

Because I took some things with me from Compass when I left,...some of which has been mixed together with my current bourbon/neat based workflow – it's not entirely clear to me what Bourbon's default (or recommended, or assumed) tools for working with things like vertical rhythm and modular scale are...or if there are any.

Point being, is there not a $base-font-size variable in a general config or settings .scss file, and if so, couldn't/shouldn't you use this as the basis of the calculation? In either case, providing a second param or override seems like a good idea. I'm just taking the opportunity to better understand what the default tools are, and to perhaps get on board with those.

For anyone interested, the Compass approach to VR is detailed here... and it is exhaustive. Some might argue, unnecessarily bloated. http://www.youtube.com/watch?v=ls3Clk-kz3s

@mkitt

It feels like this should be broken out to a function for rem and a mixin for font-size using the rem function. The function would better match what is currently in _px-to-em.scss and allow users to actually use a rem based workflow in other properties.

So ultimately you end up with something like:

_px-to-rem.scss

@function rem($pxval, $base:16) {
  @return ($pxval / $base) * 1rem;
}

_font-size.scss

@mixin font-size($pxval, $base:16) {
  font-size: $pxval * 1px;
  font-size: rem($pxval, $base);
}

I also agree with @kerns in having the ability to configure a $base-font-size variable. This would make the $base parameter default to $base-font-size instead of 16 and allow users to adjust the defaults globally across the project. If going down this path, it would make sense to change the default within the em function as well.

@kerns

I'd love to hear from @plapier at some point with regard to Bourbon's broader approach to managing typography. Is the official view that everything needed is already in Bourbon? Or are there things on the drawing board planned for a future release?... Or is the idea that it's outside the scope of Bourbon, that it's a BYOTT affair. (bring your own typography toolchain).

@kerns

@renaudleo Have you looked at this?,...maybe useful just to compare approaches. https://github.com/ry5n/rem

@wingrunr21

ooo I like that. I was in the process of writing my own mixin library around rem.

@renaudleo

@kerns I get the point of using something like https://github.com/ry5n/rem, but, from my point of view, it's a little bloated for what Bourbon aims to be. Remember that Bourbon is not quite a replacement for Compass, but more of a lightweight toolbox.

There is no configuration file at all in Bourbon at the moment, and that's one of the things I actually like about it. I get that with Neat, for example, it's absolutely required, but I feel the goal of Bourbon is to keep things simple. If someone absolutely wants to set a $base-font-size value, it's quite easy to simply add a wrapper to the original mixin:

$base-font-size: 62.5;

@mixin _rem($font-size, $base-size: $base-font-size) {
  @include rem($font-size, $base-size);
}

I think @mkitt suggestion could be a good way to go, with a rem function and a font-size mixin.

What I like about this:

  • You can use the rem function with other properties (which I don't really do, but still)
  • You still have a font-size specific mixin, because that's most likely the way you'll use rem reccurently

I don't mind making the changes. @plapier, what do you think?

@kerns

@renaudleo Cool. I'm down with and fully support Bourbon's aim to be lean, and to not try and replace (or become) Compass. And if that means doing without a sanctioned/supported default workflow for my particular pet interest, so be it.

Still, I can't help thinking that if Bourbon were built today, a rem based typographic workflow, and a best practice approach to maintaining font proportions and vertical rhythm across breakpoints would probably be included. These are not optional or ancillary needs – rather the opposite. And arguably more fundamental and universal to every project, when compared with for ex., timing functions.

I know if the crew at thoughtbot put their heads together they could do something both simple and brilliant... maybe even as a standalone project, as with did with Neat. They could even call it "Straight". / @kaishin

@wingrunr21

I agree. I am actually of the opinion that just a rem function and font-size mixin would be inadequate. You also need to worry about things like line-height, margins, etc.

I found this article to be good regarding the subject in general: http://gregrickaby.com/2012/10/web-typography-using-rem.html

@plapier

I've been trying to get my thoughts summed up on this but I find it hard to sum up what I'm thinking in a concise manner. My thoughts right now are that a more comprehensive solution would live outside of Bourbon, and that if we do include a rem solution in Bourbon, that it be very simple.

Things that worry me:

  • Incompatibility with Neat. Changing the html font-size to something other than 100% will cause issued with Neat's calculations.
  • The addition of adding a global default variable.

Pertaining to this:

If your base font-size is 62.5%, you could call the mixin that way:

h2 {
@include rem(18, 62.5);
}

I would hate to have to pass that second variable every time I call the mixin, If I changed the base font-size. This leaves two options, as discussed above.

  • Option 1: Add a default global variable that can be changed.
  • Option 2: Letting the user create a wrapper mixin.

Option 1: If we did include a global variable, the mixin would work as follows:

$rem-base-size: 62.5%;

html {
  font-size: $rem-base-size;
}

h2 {
  @include rem(18);
}

Again, I hate the idea that this would screw with Neat and it's calculations.

Option 2: If a common case is that a user will be creating a wrapper mixin, I think there is fundamentally an issue with the original mixin, revealing that it wasn't designed for real-world popular use-cases. If we assume that 100% font-size will be the default in most cases, I think this approach will help simplify the mixin.

Both the above approaches have their own set of drawbacks.

@plapier plapier closed this
@plapier plapier reopened this
@plapier

Heh, wrong button, I didn't mean to close the issue.

The current implementation that @renaudleo is proposing is simple, easy to understand, and minimally a good start for providing a rem fallback in Bourbon.

I need to think about @mkitt's proposal more thoroughly. Is there a case where a user would want to convert px-to-rem outside of your proposed @font-size mixin?
Example:

div {
  width: rem(18px);
}

I think @mkitt's proposed font-size mixin should be renamed to rem because it's tied to the rem() function.

@mkitt

While I personally haven't used rem measurements outside of setting font-size, it doesn't mean it won't come up in the future. From the link @wingrunr21 points to above, the author is using rems to set margins, so evidently it is happening in the wild.

Having a rem function that outputs a measurement (similar to the pixel to em function), and then be shadowed with a rem mixin that outputs font-size might be a bit confusing. Especially if down the road, we all start using rems in everything. Unlikely yes, but I never thought I'd be using em measurements in media query breakpoints either. Perhaps rem and font-size are not the appropriate mixin names here? Man, naming stuff is hard.

I really appreciate that Bourbon does not have a crazy configuration file to tune up before each project. It seems though, it's inevitable for a few of these default global variables to start popping up in a few places. Especially when talking about mixins and functions for measurements. In essence, in the the pixel to em function, since we can't override 16 for the $base parameter, we're already left with having to create a wrapper function if the base size is anything but 16 or be incredibly verbose every time we call the function. I don't have a better idea other than having a $base-font-size: 16 !default global variable at the top of the file that can be overridden prior to any mixins/functions being called.

@plapier, I keep going back to your above statement and couldn't agree more...

My thoughts right now are that a more comprehensive solution would live outside of Bourbon, and that if we do include a rem solution in Bourbon, that it be very simple.

@tobiasbrummer

I don’t know if I’m doing it wrong but I’m using rem for nearly everything by now. I like it to have a consistent way of dealing with units.
I never change the font-size of html, so I like the idea of a simple px-to-rem mixin like @plapier’s last proposal.

@lmartins

I think the approach of using rem units for margins, paddings and widths makes, in a way that makes your layout specifications tied in with font-sizes. That being said, i really like the simpler approach followed by Bourbon, but still, I don't think that something like https://github.com/ry5n/rem would be too much bloat.

@Tokimon

I like the currently implemented rem() inclusion, but i have a suggestion to improve it:

@mixin pxrem($prop, $values) {
    $rems: ();

    @each $val in $values {
        $rems: append($rems, if(unit($val) != "px", $val, (strip-units($val) / 16) * 1rem));
    }

    #{$prop}: $values;
    #{$prop}: $rems;
}

The other one seems to be loop in loop which can be tedious to wait for.

@rawtaz

Rem support is needed, one way or the other :)

@plapier

We've included rem support, but it's not yet documented. The source can be found here: https://github.com/thoughtbot/bourbon/blob/master/app/assets/stylesheets/addons/_rem.scss

And the feature will be available in the upcoming version release.

@Tokimon Can you create a PR or issue with your suggestion? I'm closing this issue.

@plapier plapier closed this
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Commits on Feb 18, 2013
  1. @renaudleo
Commits on Mar 14, 2013
  1. @renaudleo
This page is out of date. Refresh to see the latest.
Showing with 9 additions and 0 deletions.
  1. +9 −0 app/assets/stylesheets/css3/_rem.scss
View
9 app/assets/stylesheets/css3/_rem.scss
@@ -0,0 +1,9 @@
+// Convert pixels font-size value to rem while keeping a pixel fallback
+// This mixin assumes the body font-size is the default `100%`
+// If not, you can use the optional $base-size param
+// eg. for a body font-size of `62.5%`, use `@include rem(24, 62.5)`
+
+@mixin rem($font-size, $base-size: 100) {
+ font-size: $font-size + px;
+ font-size: ($font-size / $base-size * 100 / 16) + rem;
+}
Something went wrong with that request. Please try again.