Me, for the last year or so: “rem
‘s are so cool! I’m gonna size everything with them, that way I can adjust the font-size on the root element and everything will scale with it!” It was a nice dream. And it wasn’t a disaster. That’s what I’m doing right now here on CSS-Tricks and this is how it plays out in a very simple scenario:
That comes from essentially:
/* Document level adjustments */
html {
font-size: 17px;
}
@media (max-width: 900px) {
html { font-size: 15px; }
}
@media (max-width: 400px) {
html { font-size: 13px; }
}
/* Type will scale with document */
h1 {
font-size: 3rem;
}
h2 {
font-size: 2.5rem;
}
h3 {
font-size: 2rem;
}
I admit that I like that simplicity, but I’m starting to think it’s a little too dreamy for all but the simplest of sites. The main issue: you just can’t expect type that you set at one screen size to look just right by simply scaling it down entirely proportionally. Big type might get too big scaling up. Small type might get too small (a common one that gets me). Or even the reverse of either, where big type might not get small enough.
If any of those things happen, then you’re making @media query specific adjustments which not only gets confusing but isn’t very efficient (adjusting size just to adjust it again to fix it).
So here’s my idea: you still keep px
size adjustments at the document level so you can make easy/efficient sweeping size changes. But then each module on the page has a font-size set in rem
. Actual text elements (h1, h2, p, li, whatever), if you size them at all, are sized in em, and thus become relative to the module.
This way you can adjust font-size at a module level, which is pretty easy. The chances the type within a single module have good proportions and can scale together nicely is high. So that would play out like this:
You can play around with the idea here by adjusting the sliders:
See the Pen Em AND Rem by Chris Coyier (@chriscoyier) on CodePen.
At a certain medium size, everything looks fine. Scaling up, you can get to a point where the main articles are a good big size, but the sidebar stuff doesn’t need to be that big. With this system it would be easy to target them and notch them back down. Scaling down, those sidebar modules get a bit too small too fast, so you could notch them back up easily. There might even be sizes where you equalize things because you’ve gone single column (or the like).
This is how it would go down:
/* Document level adjustments */
html {
font-size: 17px;
}
@media (max-width: 900px) {
html { font-size: 15px; }
}
@media (max-width: 400px) {
html { font-size: 13px; }
}
/* Modules will scale with document */
.header {
font-size: 1.5rem;
}
.footer {
font-size: 0.75rem;
}
.sidebar {
font-size: 0.85rem;
}
/* Type will scale with modules */
h1 {
font-size: 3em;
}
h2 {
font-size: 2.5em;
}
h3 {
font-size: 2em;
}
I put “idea” in the title because I haven’t actually built a site doing this yet, but it makes sense to me and I’d surely try it.
Hm… good plan. I actually just use em’s and percentages – no pixels (unless borders are involved) and no rem’s. This sounds better.
Definitely worth noting browser support for rem. If you need to support IE8 and below, this idea can’t even be considered.
It can be accomplished with px fallbacks for rem. You would just need to include the rem/px fallbacks for modules in your @media declarations.
Leave yourself a little not that they can be removed when IE8 no longer needs to be supported and you can use this today.
Fortunately XP is died today
@Legomushroom That means nothing, we still need to support those users.
sure we are, but this will change very soon
Lets just stop supporting IE8 shall we? Its 2014.
Yeah, we can all certainly stop using IE8, but too many other people will just continue to use it. If you install Windows 7, not even XP, you’ll end up with a vanilla version of IE 8 or even IE 7 potentially based on which install you have. Not out of the woods yet :)
I work for a company whose clients are large staffing firms, who themselves rely on large IT departments to handle all their tech support. When you get into environments of that scale, upgrading is extremely difficult, time consuming, and most importantly cost ineffective. As a result, we supported IE8 until last month.
Some government agencies still uses IE6. Just think about that.
btw, the UK government just spent 5.5m GBP on getting extended support for XP
http://ccs.cabinetoffice.gov.uk/i-am-buyer/categories/ict/special-agreements/custom-support
Target features not browsers. Everything can be considered with correct fallbacks. Do not sell yourself short in what you can do. Plan for the future while minding the past.
Hmm. This sounds fairly promising, I’ve been grappling with the same struggle.
The problem I tend to encounter is that, as you said, the big text doesn’t get small enough when you scale down – and I’m not sure this would solve that. Though I think I’m just being lazy and it would only take a simple heading mq adjustment to change that ratio.
In my dreams though, everything is as simple as tweaking one number.
I like this idea a lot. Anyone whose worked on modular “widgets” should be able to see the benefit.
Add into this the ability to style modules differently in contexts (sidebar, main body) and it greatly reduces the need for duplicate css.
Thanks, Chris! Looking forward to adapting a similar approach.
I’ll sure give it a try on my next full site. That client is a font snob by his own admission, so he’s the perfect guinea pig.
Setting your font-size at document level using an absolute unit overwrites the user’s browser settings so it’s safe to say this is a bad practise.
Instead, use a relative unit, like so:
html { font-size: 100%; }
.I agree with Tim, leave the html alone. Here’s the source for that: http://filamentgroup.com/lab/how_we_learned_to_leave_body_font_size_alone/
Also they mention/link to why you should use EMs for media queries: http://blog.cloudfour.com/the-ems-have-it-proportional-media-queries-ftw/
The biggest factor there was that px media queries didn’t work when the browser zoomed but ems did, which isn’t true anymore. I switched all my media queries to ems for that reason, which is fine, but I think in general I’m more comfortable with px there.
Chris, it take a little time to stop using px. It is a switch from the whole design based on pixels, to the whole design relative to the base font-size.
It is a switch from absolute to proportional. The same switch as from photoshop to illustrator.
+1, stop using pixels, it is bad :).
It can also have accessibility issues for old IEs, but the main problem is – as Tim says – that is overwrites the user default values. Respect the user, use percents, or don’t use anything :)
@Nico
Who are these users changing default font values?
I know a few legally blind people. 1 zooms in his entire screen (OS X ctrl + mouse wheel). All the rest use ctrl-+ which zooms everything, not just fonts.
Does anyone have actual statistics on this?
Use % at the root – same concept.
If it’s the same concept, dont promote use of an absolute unit, like pixels, at the root element.
Basically you’re advising developers to screw people with bad vision that didn’t found the zoom option.
If you’re not willing to change it, at least mention the benefits of percentages it in the article. Please.
I don’t agree here. Yes, it’s obviously nice to consider the user’s settings. But the correct answer is way more complex. Why? Well because:
It’s safe to assume users are bumping up their text sizes to be able to read 10px body text. But it’s impossible to tell if the user actually wants the bumped up text size if your site is set to 20px.
I really like this idea. I think as browser support becomes a little wider this will be the way forward. Cheers for the incite.
Once rem is available, I think it wrong to use px for anything else than borders or seperators. It should not be used for fonts anymore. My rational :
Rem makes it possible to handle both : browser zoom && user font-size setting.
– with zoom we want to make everything bigger.
– with font-size change, we want only the fonts bigger.
To make only the fonts bigger mean that the layout wont get larger or narrower.
When the font-size setting is changed then all “em” sized stuff are changed, but not the rems.
From that I have the following basic strategy :
– em for fonts and anything that is relative to fonts.
– rem for widths. All the stuffs that shouldn’t get change when the user font-size is changed. So generally it is the layout width, the columns and blocks width. Generally, we want the container to expand down, but no get larger.
-px almost bannished, and used only for borders, because we want usually round numbers for those.
Super simple strategy, and works well for me on IE9+ browsers.
Also it opens up the doors for manipulating the font-size programatically.
Yes, exactly!
I have been doing that for a 3 years or so, except i use(d) em’s only, when rem was not an option. Borders, text-shadows and generally all that is 1,2 in px and border-radiuses in px too. Well one could use em on border-radius, but it s best not to.
I’ve been thinking about the same thing lately!
Using rems for everything seemed like a genius idea, until I started working with them on the big-scale sites. With ems, I could adjust only the parent container of a module and the rest of the blocks would resize accordingly. But with rems I have to override rems for every nested object. And it basically overcomes all of the benefits of rems.
I’m definitely going to try this new approach on my next project, because it combines everything that I like about the rems (dependent only of the root’s font-size) and ems (it scales more easily).
Interesting idea – I’ve avoided using rems to this point preferring percentages and ems. I like the concept of this though, and I think I’ll experiment with it on my next site.
Thanks Chris!
Awesome idea. I made the switch to using
rem
s for all font sizing and spacing, but have struggled with the scalability. By setting actualfont-size
withem
, the container / module can really determine the sizing while keeping spacing consistent withrem
s. A+ idea.This is really great! Now I need to go try it out. Thanks Chris!
Tried out this method on the current site I’m working on and ran into a few small issues with my current setup. Using LESS, I have several main variables for font size.
Setting 1rem equal to 10px allows for easy calculations regarding font-size or margin/padding ( Method based on The Golden Ratio and REMS )
However, when I switched to using
em
forfont-size
andrem
formargin
/padding
, there were a few modifications I needed to make.This allows me to fall back to a fixed size with the
@font-size-body
variable, like when using an inline-block grid and font-size: 0.1px to remove spacing, while still allowing for easily scaling font-size for modules or media-queries.Just curious: why
html {17px}
Rather than, say16px
?I am not too particularly keen on overriding the default font size of the user’s browser settings. I imagine most of the users do not even touch that setting though. Hence, leaving it as,
font-size: 100%
is the best thing that we could do.The idea of using
px
,rem
andem
together for setting font-size might seem a bit overwhelming to a beginner. Hence, as an alternative I use onlyem
s to set font-size(s) which means that we can resize the text by simply changing thefont-size
of thehtml
element.Here is, how it is done,
That’s it! By simply changing the
font-size
in%
for thehtml
element, we can scale up/down the text based on the media queries.What about Vertical rhythm and tools like Compass? I really use Compass just for this these days (gulp for prefixes). How to make it usable?
Regarding the CSS-Tricks redesign, why are you making your font sizes smaller for small/mobile screens? Doesn’t it make sense to make them bigger/easier to read?
I initially thought the same but that doesn’t take into account the fact that mobile devices are typically much closer to the user than traditional computers. http://ia.net/blog/responsive-typography-the-basics/
Nice idea. I guess you also need to take into consideration vertical spacing such as margins and padding. Increasing the modules font-size without using ’em’ for these properties could lead to interesting results.
So far, I’ve been using % for scaling up or down the font size. This approach seems interesting. Gonna to try it.
In Neverland EM or REM is used for everything !
For EM case, I think is bad idea to apply font-size to the parent of element text.
One day we should consider full EM/REM design.
1) Never take control of the font-size away form the user. Many people with disabilities set their own base font size in the UA.
2) That being said, designers have been taking away control from the user since forever. Still, it is never to late to start now.
3) I never understood the necessity for REMs. What you propose here can just as easily be done with EMs:
rem, by my understanding, just makes doing the math easier. A rem is always based off of the HTML size, if I remember correctly, so no mater how many elements in you are nested, it behaves the same and predictably. Think of it as declaring a scope for what em uses to base it’s math off of. Where as, nesting em can start to have unwieldy consequences as you nest more and more elements.
In simple sites, a relative non-issue, but in some of the more complicated ones managed by lots of people, em becomes a real pain.
Rem are not affected by the change of the user font-size setting. (and there is no compounding)
That is the reason why I suggest strongly to use it for all width. Thay way, the user can request a bigger font-size, without to make the website larger. That way, bigger font but no horizontal scrollbars.
@olivvv: maybe I misunderstand you, but
rem
s are affected by changes in the user’s font-size setting, just likeem
s. That’s why they’re useful. The user can change their font size and the elements will scale up and down accordingly. That way you don’t have columns that are too narrow or too wide, like you would withpx
-based layouts.The one important thing with
rem
-based layouts is to always userem
– orem
-based media queries as well. Forrest Galloway has info on that in a comment below — as a user scales up their font size (or zoom setting) they get the tablet version, then the mobile version, which is probably better UX anyway.Slightly off-topic, but if you’re scaling font-sizes up and down, you might want to play around with the letter-spacing as well.
Big type can – and often does – look prettier with a little less space between the letters. It can also improve readability.
Use relative units for good results, go font-autism-subpixel-crazy for great results.
Amazeballs! Love it.
We used a technique similar to this article for the recent redesign of http://www.nationalguard.com. We have a few PX declarations but mostly EMs, they work great for modules and layouts (for scaling down the aforementioned modules)! To make the site responsive we used the the standalone version of fittext and attached it to the html element alone. The font-sizes cascaded beautifully.
If JS is off, use a PX based font-size on html element and fixed width on body. It is possible to mimic fittext’s behavior with a Sass mixin and MQs, not sure if it would be advisable, it would be a lot of lines of CSS.
It has an interesting benefit/side-effect for Accessibility, increasing the font-size in the browser eventually displays the mobile experience with large text, which we feel is a better experience than just an inflated desktop.
I agree with changing the route em size at breakpoints but I still don’t really see any benefit from sizing components in ems or rems, for me its:
Rems for text
Ems for things that have a relationship to that rem (eg padding on a button should be relative to the text size of the button) also ems for margins on text based things
% for layout
% or PX for gutters/margins on layout elements – Gutters between columns for example have no relationship to the size of a
<
p>
Here’s a method I’m using on my website:
Set a base viewport unit (vw) font size for :root, then change all other sizes via percentage, here’s an example:
https://github.com/sparanoid/sparanoid.com/blob/master/_app/assets/less/app.less#L2
Hi Chris – I really love the tight modular approach, but there are a couple of things I think are really important to consider:
1) EMs for media queries work more reliably as some browser/hardward combos (Samsung touchscreen laptop is one I’ve heard) are starting to report actual resolution of their hi-res screens – and em-based layouts work great, but px based ones suddenly appear the size of a postage stamp. I think this will only increase in frequency over time, so given the fairly easy swap between the two it might be worth sticking with EMs for MQs as well.
2) Filament group is right about sticking with 1EM for body text. They (device/os vendors) put a lot of effort into determining what a decent readable size is on their particular device, and if you leave it at 1EM it will always just work.
3) Making judgements on relative size in the modules all over the place can have the effect of really fragmenting the design experience. When relative size is very different it slows down comprehension with users about which element is more important than another, as that hierarchy isn’t maintained.
It’s not that the modular code approach isn’t really smart – but I think it’s really important to consider the whole of the design and its cohesion rather than focus on tweaking each module. Of course, I would totally go for this approach from a coding perspective just to make all the modules of CSS more portable and ‘SMACSSy’ – but as a designer I would just want to be more considered about how much gets changed and where.
OK. One other thing about REMs vs EMs. I’ve never adopted REMs in part because of IE8- (and all the sample code I use for my RWD workshops is responsive back to IE6), but the need for REMs is much less if you just make sure you don’t apply font-size changes to containers – only to elements themselves. That way you’re alway calculating on the base HTML font size – and you could achieve a lot of the same overall flexibility that way to change the base and have it ripple across.
We actually have a similar system in a big responsive project in use. First, we strictly modularized all UI components on the page with BEM class naming. Then we distinguished between modules corresponding to page sections and smaller modules. Page sections were allowed to override their font size with REM. Smaller modules (like buttons, form elements, headlines, etc.) are always sized with EMs. This way we could use the small modules in a very flexible way even in different sizes. The sizing is controlled via the page section modules through their REM base font size.
The end result was a highly flexible and modular UI component system.
I like
rem
units because they make math easier.So, why not set the root element’s
font-size
to10px
? This way1rem
=10px
,1.2rem
=12px
, etc.Also, I thought overriding the user’s browser settings with
px
units was frowned upon by the community. Has this ethos changed?Or, if not concerned with easy math, why not set the root element’s
font-size
directly with arem
unit and allow the user to maintain control?I’ve been using this process with Atomic Design on my company’s large enterprise application. It’s great because you can define a Sass or LESS partial for a module (in Atomic Design they’re called Molecules or Atoms), which defaults to font-size: 1rem, then at the Page level I can override that with a font-size: 1.2rem, etc.
That way I can scale a widget across an application based on it’s context.
A module’s font-size get
rem
, and so do the page grid framework. I use Susy, which natively uses rems this way. They’re great for grid frameworks because you want to make sure columns and gutters across the entire page remain consistent, regardless of which module they’re in.I’d like to reiterate thinsoldier’s questions:
“Who are these users changing default font values?
Does anyone have actual statistics on this?”
Is it even possible to sniff out the default font size from a user’s UA? If so are there any stats available and is so where can they be found?
Thanks
What’s your opinion on setting the base font in px and the rest in percentages?
i agree with you :-)
like the slider demo to increase font size
It’s so much simpler to Use Percentages +/- 100% = Works Everywhere; this way you don’t dang O’ rem’ em headaches! Don’t even get me started on the cross-platform compatibility.
It’s just that simple folks…
Typography in % and em’s are the same – it still affects the cascade, since 100% of 300% is still 300%. Likewise 1em @ 3em is still 3em.
See for yourself
Little tip for the CodePen demo thingy: if you bind the callback to the “input” event, the font-sizes are updated as you drag the range up and down. Supercool.
I use similar technique in Kendo UI Mobile for quite some time. However, we need components to be resizable and base mostly on em.
Using ems and rems and font-size on root is also the only way to simulate the missing scale 1 auto sizing in Windows Phone 8 where no devicePixelRatio is available (WP8.1 has devicePixelRatio, but still doesn’t do auto sizing).
I think this is a good idea but I was just wondering why you are not using points (pt) for the text. Isn’t that better for printing pages?
hey chris, we’ve actually been using this technique in a HTML5-video player for two years now. The root-adjustments are done with JS in our case as we want the player to zoom to the window. We decided to use px for root and ems for everything else but the same thing could have been done with rems of course.
The beauty of this project was, we don’t have to care about older browsers, those are served with the weird old step-oncle (Flash).
here is the result: http://www.heliview.de/?uid=Q5ZPL5
There is one major problem with (r)ems though: FF/Chrome/IE/Safari tend to use their own algorithm for rounding values which results in small but visible differences in calculation and you cannot define minimum values for things like borders. That’s why we decided to use px-values for those… and ran into the next issue when the user zooms in or out (desktop only). px values are actually zoomed in modern browsers.
so… dear CSS-WG/W3C: we love what you’ve done with the place, but that one room still needs a new paintjob…
@Tim Severien and % vs. px: It really depends on the use-case! If you need to be in full control you NEED to use pixels. for websites: yes you are right – but for apps that’s another story.
I like this idea. At the same time it makes me a bit uncomfortable to be teaching students about fonts and units these days. When I teach new web design students about px, %, em and rem they get confused sometimes. Imagine explaining somebody new in the web field to use 62.5% on the html, rem on the modules, em on the elements and px for some other things :). Thanks for the tip though, I like it!
@Paul d’Aoust
yes, you are right, I messed something in my tests and talked too much since then.
Then what I want to achieve works with widths set in px.
In that case I dont this really the point of rems when ems are already available. The only difference I see is that there is is no compounding with rems. Me going do redo tests and stop talking crap.
@olivvv heh, no worries; I think I “mess something in my tests and talk too much” a few times every day (mostly when I’m talking to co-workers). But yes, you’re correct —
rem
s are great cuz, likepx
s they don’t compound, but likeem
s they’re relative to some font size somewhere (in this case the root element’s font size).Now if only I could actually use
rem
s… we’re still seeing 9% IE8, and it’d be irresponsible for us to drop support for a browser until it hit about 2–3%. Sigh.I’m a total noob, but figured I’d try this out for my next site… cause, why not. Curious though… can we mix this with the Golden Ratio to make this work while making fallback easy and addressing the whole px vs % vs em document level settings debate above (which I am just no qualified to understand)?
So, could I set font-size to 62.5% and keep the fallback values for my modules? For type… I guess I’d still have to divide things out… but at least i’d only be dividing by the 1.6rem/16px to em and I’d know 1em is 16px right?
Ive used em’s for years on new projects and was taught to do so when I landed my first job at an agency. The idea of rems is great as they go of the document but the browser support isnt there for us to use them on all projects, see caniuse website: http://caniuse.com/#feat=rem
I was always taught the font-size:62.5% trick to get em’s to be as close to relevant px dimensions as mentioned in the comments above 1.6em = 16px, 2.0em = 20px so on and so forth.
Why don’t you use
:root
pseudo-class to set font-size of root element?Interesting article.
I saved the graphic and noticed that it is a SVG graphic. I made an example pattern of this tutorial and embedded the SVG, whereupon I noticed it isn’t responsive.
I opened the SVG and changed the header thus:
hmmm… Can’t figure out this code interface. Some clearer UX directions needed.
Great idea Chris. I’m implementing this on a current project with good results :)
That’s cool, but i think your idea can make better with this trick:
% at the Root like:
html{font-size:62.5%;}
,rem
(with trick) for Components like:.article{font-size:20px; font-size:2rem;}
and
em
for Text Elements like your exampleThe only issue with this is that everything is equivalent to font-size: 10px by default.
I am still saying no to
rem
because of browser support. But I think it is OK to useem
all the way down from the root element.I just don’t understand one thing.. Why would you scale your text down on a smaller screen instead of scaling it up?
Jos –
I agree. I’ve found it generally best to leave the body copy alone at ‘1em’ (or 100%) so that the device/OS can specify what it wants as it will generally render well and be very readable on any device no matter what size or resolution. The only caveat is some fonts tend to render a bit small (like Garamond) so I tend to size that up a tiny bit on all screens anyway.
What I think does need to get smaller are headings relative to body copy size. It’s much less clunky and still very clear if you bring the heading sizes down proportionally to the size of the screen. I wrote about it for Typecast here: article on Typecast blog