Richard Rutter’s guide for setting the font-size
of an element is interesting: he argues that we should use both em
and rem
units depending on the relationship it might have with other elements on the page:
Take the example of a pull quote containing two short paragraphs. The spacing between the paragraphs will depend on the size of the paragraph text, so you could feasibly set that spacing in either rems or ems. Should you decide during your design process that the pull quote should be set a bit larger, then the spacing between the paragraphs must also be increased. Therefore the paragraph spacing is directly related to the paragraph text size and therefore be considered local sizing within a component. Hence you should use ems in this case.
This compliments the method that Chris described a couple of years ago:
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 inrem
. Actual text elements (h1, h2, p, li, whatever), if you size them at all, are sized inem
, and thus become relative to the module.
Breaking that up a bit: first we’d set the font-size
of the document element with px
:
html {
font-size: 16px;
@media screen and (min-width: 900px) {
font-size: 18px;
}
@media screen and (min-width: 1200px) {
font-size: 20px;
}
}
Next up we’d style all our little textual elements, such as paragraphs, headings or blockquotes, with em
s. This is because they share a relationship with one another:
h2 {
font-size: 2em;
}
pre {
font-size: 0.8em;
}
And finally we style the modules that those bits of text sit inside with rem
s, so we can easily adjust all of the text within them:
.module {
font-size: 1.1rem;
}
.another-module {
font-size: 1.3rem;
}
…which ends up working something like this in practice:
See the Pen Em AND Rem by Chris Coyier (@chriscoyier) on CodePen.
What do we accomplish by doing this? Why can’t we just stick to rem
or em
to keep things simple? Well, with this method, each module instantly becomes compartmentalised and easier to style for the future. But also we can quickly adjust the font-size
of every module without having to change large portions of the codebase. If we notice that the font-size
of the whole website needs to be bumped up then just need to change a single value.
em
and rem
values are useful for two different jobs, and if we utilise them in the way in which they were designed then our work can become a bit more maintainable and flexible.
How about 100% on :root instead of 16px? Isn’t it best practice to get away from pixels altogether?
Also, isn’t it better to utilize rem’s by referring to the :root element, not the html element?
100% will match whatever the user has their font set at in their browser (which defaults to 16px in most browsers). I guess it’s a matter of how much control you want over the root font size.
Can you elaborate on why setting it on :root is better than on html? I’m curious about this.
The :root selector matches the document’s root element. Apparently, the html element is the same as the root element 99% of the time (not always). I have read that it is even better to set the :root to a percentage such as 100% (or 62.5% for the sake of doing math later on since then 1 rem would then equal 10 px) and then set html to 1 rem:
:root { font-size: 100% } or :root { font-size: 62.5% } // 10px
html { font-size: 1.0rem } html { font-size: 1.6rem } // 16px
Do. Not. Do. That.
@Anonymous
Why? Is it something to do with
:root
, or are you disagreeing with changing the font percentage to62.5%
?Don’t do it, because if you never set a fixed size for the font, you are totally dependent on whatever the user has set for their font size. 100% (or 62.5%) is a percentage of something, so you might as well describe what that something should be, rather than let the user decide.
@Jake amazing, you really want to deny the user the right to change his default font size?
I don’t want to get into a comment war. Most modern browsers encourage the user to zoom the whole page instead of just the font size — they have to dig a little deeper to change just the font size. With that in mind, even with setting the top-level font declarations with a non-relative unit, the user can still zoom in and out. You are just setting a default size.
What I (and others) are saying is that it doesn’t make sense to set the font to a relative size, but not declare what it’s relative to. Most developers take a lot of care with their design, why would they leave this detail to chance?
@Jake people with disabilities now how to change their browser settings, and can define once and for all a larger font size. AFAIK, zoom is site based, so they have to repeat zooming actions on every new visited site, really a pain for them.
This is not a detail at all, and there is no “chance” involved here, just accessibility, one of the main W3 design principles: https://www.w3.org/Consortium/mission.html#principles
@Jake, @nhoizey is absolutely right here.
Let’s have a closer look regarding the topic mentioned about persons with disabilities and why it is important to help everyone out there enjoying your content.
Following the guide for enlarging text and images of the official Web Accessibility Initiative (WAI) hopping to the chrome help page perfectly points it out:
From Chrome Help
With this in mind and some personal experience while improving a site for accessibility reasons (including optimizations for the most used screen reader), i think it’s worth knowing that the usage of the Internet Explorer series mostly starting with IE8, is not uncommon. Providing features like more specific settings for ignoring font styles and interacting seamlessly with screen readers, it makes it very easy to work with.
No one really answered with a reason you shouldn’t set a font percentage on the root… In my limited testing, user’s font size preferences will still adjust the overall scale of the text with a setup like this:
Something like this allows you to work with
rem
units in an understandable way since 1rem is essentially equal to 10px, and allows for everything to scale nicely with user’s font size preference, e.g..container { padding: 2rem; }
instead of.container { padding: 20px; }
@Shaw using
font-size:62.5%
on html was an interesting idea back in 2004, but Richard Rutter himself changed his mind in 2007 and usedfont-size:100%
even if it seemed more difficult (it isn’t anymore with preprocessors).As I see it, using
font-size:62.5%
might lead to some elements in your pages using a10px
font-size because you forgot to set a higher value, or it is a 3rd party content you can’t control. Usingfont-size:100%
, or —even better— nothing at all, is safer IMHO.@nhoizey Forgetting to set a higher value isn’t really an issue when you set the desired
font-size
on thebody
as in my example. Everything should follow at least thebody
‘s base size unless it’s reset somehow, but I avoid including unknown CSS in my sites.The links you sent do not reference using
rem
units at all since they weren’t really around in 2004/2007. Using the font percentage on HTML was a bit hacky due to the variance ofem
units, but withrem
it makes extremely easy to do reliable padding & margins relative to the user’s font setting.From the Mozilla docs on
rem
units, ‘This unit is practical in creating perfectly scalable layout.’, which is exactly how I use it. I have not experienced any issues usingrem
, and the layout & text scale great with the user’s font and/or zoom settings. Unless there are some accessibility concerns in specific browsers, I don’t see any reasonrem
units can’t be used in this way.I found this article against using
rem
, claiming thatpx
units are scalable However,px
do not scale with the user’s font size setting, though they do change with zoom.Out of curiosity, how do you handle scalable layouts that support user
font-size
and zoom changes, as well as mobile devices?Has anyone ever been able to bump up the font size of an entire webpage without having to go through the entire CSS file and redo lots of small pieces anyways?
Like you decide you need a 16px body instead of a 14px, but then you find that some menu sizes really should stay the at 14px, and footnotes need to go from ~12px to 14px, not 13.7px. It’s always a process of discovery, finding out that some things were proportionally sized that didn’t need to be, and somethings don’t scale well at all sizes.
It’s always been a nice dream to radically alter a website through a single line of CSS and lots of proportional sizing, but after years of never seeing it succeed I’m starting to think it’s a pipe dream.
My own goal when writing CSS isn’t to let me alter the whole design with a single variable, but to make it easy to see where all the changes are if I do make a radical change. It’s just writing maintainable, debuggable CSS.
Site-wide flexible font-sizes are a GREAT example where the practicality overshadows the possibility. Sure, it may be possible to be ultimately flexible, but for most sites there are simply too many variables.
I will say this, though. Forcing yourself to have fewer variables is never a bad thing. It can help you to concentrate your design into something simpler and more digestible, so maybe striving for flexible global font-sizes is not a bad thing.
I completely agree with you, when I work on commercial product I never have just a few set of font-size and some set of sizes has to behave differently depending where they are. As every CSS size property has an impact on your layout, is it going to work on a buttons, inside a column or inside a specific layout/container? It’s difficult to tell this, we need to think all these scenario plus media query. I think REM can work well on simple layout like an article page or a simple blog.
I agree with the comment above, although its often used as an example – I don’t think changing one number to affect the entire document is much of a real world example. I stick to em’s for units which should relate to typography, padding on buttons, margin on P’s and headings etc but prefer not to use it for font sizes. Also we use inline-blocks for our grid layouts which rely on font-size: 0 (yes we could avoid that by doing strange things in the html but its less practical) and therefor the em cascade gets destroyed. I can see how setting a font size in rem on the block (BEM block not display: block) and then all the children/elements in em’s would keep everything modular
Nooooo, please!
Baseline grid. I use EMs for things like my font size or sizings that don’t affect the baseline grid so that it’s compartmentalized, but when talking about vertical spacing (e.g. line-height, margin) I’ll generally use REMs unless I don’t consider it as something part of the baseline grid (e.g. the menu).
Why would you use a unit for line-height/margin that is unrelated to the content? surely line-height 1.3 would be far more appropriate/versatile than a magic number :/
This is an interesting read, Rob. It’s nice to see some discussion around this subject.
I’ve done some experiments with mixing ems and rems myself. However I’m not sure if the “complexity” that it adds makes it worth the effort. By “complexity” I mean, difficulty to understand units and how they respond to where they are. You’ll always have to be aware of the context in order to take full advantage of this technique.
In theory the flow/rhythm of the document should follow a no-nonsense sizing scale and that should be enough for most cases.
The great deal of using font-size based scaling is to take advantage of an accessibility property (that takes user input into account – the zoom) as opposed to arbitrary pixel values. Changing the document flow by setting a very small font size to a component can cause a lot of readability issues (talking about DOM, literally a waterfall of problems) which is kind of a deal breaker in my opinion.
There seems to be so many conflicting theories on how to set up an HTML document. Some advocate using px’s, others percentages, and yet others rem’s and em’s or combinations of all the above.
Personally, I would like to believe that setting up either :root or html at 100% and then using rem’s would be the ideal way for more control of layout and nesting and be mobile friendly as well.
Why set it to
100%
instead of just letting the default work as is, without anything in the CSS?What do you think of this:
Is it bad practice to use rem for everything (with px fallback)?
I even use it for containers, paddings, margins,…
From a styling point of view, using rems is no different to pixels (the browser still computes a px value) the main difference is you loose relative sizing. For example you may have a title, with font-size 30px and margin-bottom: 30px and another title at font-size 20px – its unlikely you want the margin-bottom to also be 30px (as the spacing would normally be relative to the size hence unitless lineheights). Instead margin-bottom 1em may be better as its a relative unit.
A quick example of a ems and rems in the real world:
Padding on the button is set relative to the font size which means you only have to change one value and the buttons remain consistent
Also, don’t forget em’s for media queries
http://blog.cloudfour.com/the-ems-have-it-proportional-media-queries-ftw/
Check out the note at the top of that article.
This is one of my favorite examples of a concept that gets stuck in the GlobalDeveloperConsciousness™
@Chris I believe Lyza is right when she states “the zooming behavior has […] been made consistent”, but is doesn’t mean users changing their browser default font size should not be taken into account any more… These are two different topics that both require
em
based MQs.It would have been nice to have a full article on this subject (typography and units), since there is nothing really new in this one.
I recently read a series of posts on it (written by Zell Liew), and already knew a little about modular scale, “responsive” viewport based font-size, vertical rythm, etc… This prompted me to learn more about it, and I was disapointed a little to find anything synthetic here on CSS-Tricks (please take it as a compliment, because it is a gold mine 99% of the time).
I also wonder what’s the difference to set global font size at :root insteaf of html, or even of body. I avoid to change the global font size at all for most of my projects, so it’s not really a problem to me, but I can see there is one by fixing it with pixels for users which are setting a font size in their browser. Ok, there should not be so many people to do it, but we have to presume that they did it for a good reason, which we are totally ignoring by setting a unit that is (at least) non relative.
I am not convinced by the idea to set module’s font size in rem. Why not let it in set with em, therefore linked to a root font size ? Imagine we use BEM, and we set a font-size in rem for each block. A button would be a block. A secondary block with a smaller font-size as root font size, and containing this button, would display it too big.
About changing font-size responsively with a single declaration, Mike Rithmuller Mike Rithmuller wrote a year ago about a method for responsive typography based on viewport width, with min/max values in pixels (eventually different for multiple viewports). It’s not ideal since we don’t always need to reduce/increase font size to be responsive, but instead we prefer to change layout.
very good
Re: { font-size: 62.5% }
Short: save yourself some problems, just set root to px.
Long: I just had a call from a designer wondering why his design is all messed up … having his browser set to 10px. I found this page looking for why use CSS rem and checked some pages for reference.
Browser preferences seem to be a forgotten feature and respecting them is too. Zooming works fine with absolute values on root, it just ignores that we could respect the settings.