Responsive typography made easy
Edit July 20th 2015: If you want your typography to scale differently (e.g.: Your headings and your paragraphs don't need to just scale up by 20% on a different resolution, you want them both to have a different size), there’s a great article on Smashing Magazine about that: Responsive Typography with Sass Maps
Font sizes should differ on different devices (smartphone/tablet/desktop) because people read from these devices at different distances: you hold your phone closer to your face than your desktop screen. For more information on this, check responsive typography, the basics.
But what’s the most practical approach to do this? (according to me)
- Use
rem
’s (and a Sass mixin for apx
fallback) - Switch the
html
’s default font-size at different resolutions (since we're usingrem
’s all font sizes will decrease/increase with it)
Note: We’re using rem
’s because em
’s can be tricky:
One of the problems with using "em" as font sizes is that they cascade, so you are forever writing rules that select nested elements to reset them back to 1em; CSS3 now has rem ("root em") to prevent that issue. Just declare a px fallback and you can use it today. Snook shows us they way.
— css-tricks
Learn more about rem
’s at snook.ca
Defining font-sizes with rem
's
I put my font sizes in variables to ensure consistency through the whole website:
$font-size-xs: 11px;
$font-size-s: 14px;
$font-size-m: 16px;
$font-size-l: 18px;
$font-size-xl: 24px;
$font-size-xxl: 36px;
This mixin converts the pixel font size to a rem
format, with a px
fallback
@mixin font-size($px, $base: 16px) { // 16px is the browser default
font-size: $px; // px fallback
font-size: ($px / $base) * 1rem; // calculate rem font-size
}
Mixin usage:
h1{
@include font-size($font-size-xl);
}
Mixin output:
h1{
font-size: 24px; // overwritten by rem declaration below, IF rem's are supported
font-size: 1.5rem;
}
Resizing font sizes at different resolutions (mobile first):
html{ // Smallest resolutions
font-size: .8rem;
}
@media only screen and (min-width: 480px) { // 480px and up
html{
font-size: .9rem;
}
}
@media only screen and (min-width: 768px) {
html{
font-size: 1rem;
}
}
That’s all Folks!
Yup, that’s how easy it is, desktop screens will now have the sizes defined in your variables. Smaller screens will have smaller font sizes, creating a better reading experience. Try to reach a line lenght of ~50–60 characters for body copy on each device.
Written by Kenny Brijs
Related protips
6 Responses
I'm going to try this on my next project, thanks Kenny!
Glad to hear that mattquirk, good luck ;)
And on the px fallbacks? Surely they'll get the same font-size regardless of the font-size on the html.
Maybe you should pass a different $base instead of changing the font-size on the html.
Yes, browsers not supporting rem's wont get responsive type, but that's not a bad thing per se because most mobile browsers support it and old desktop browsers will just get te "regular size" with pixels, which they would also get if they supported rem's
The thing with changing the $base—if you mean the base font-size—is that you can't change that with media queries. The $base variable is set in SASS (or LESS) which is then compiled to CSS. The media query logic is executed in the browser (the CSS) and there you can't change the SASS/LESS variables when the media query detects a certain screen size.
Is this an answer to your question or have I misunderstood something?
Grtz ;)
Tried the code examples. Too bad it didn't work. Regardles of the browser window size, the fixed pixels values were always used. Tested with Safari 7.0.5. - Either I did something wrong (probably) or this article needs clarification :-)
Hi moonbeetle ;)
Can't see your code, but check out this article: http://snook.ca/archives/html_and_css/font-size-with-rem
Once you get it working like that you should be able to figure out the rest, the code in this article is just an automation of the principle explained there ;)
Hope it helps
Grtz!