One of the most important components of responsive design is responsive typography. Web designers have many different approaches to implement responsive typography. Some designers use external libraries and some do it natively. In this post I will discuss all native techniques used by web designers to get responsive typography.
There are basically three ways to get responsive typography: CSS Media Queries, CSS Responsive Units and CSS Relative units.
Responsive Typography Using CSS Media Queries
A responsive website is designed to fit across multiple screen sizes using media queries. Similarly we can use the media queries to declare different font size for different screen sizes.
An example of responsive heading using media queries:
@media screen and (min-width: 1200px)
{
h1
{
font-size: 100px;
}
}
/* viewport-width >= 992px and viewport-width <= 1199px */
@media screen and (min-width: 992px) and (max-width: 1199px)
{
h1
{
font-size: 80px;
}
}
/* viewport-width >= 768px and viewport-width <= 991px */
@media screen and (min-width: 768px) and (max-width: 991px)
{
h1
{
font-size: 60px;
}
}
/* viewport-width <= 767 */
@media screen and (max-width: 767px)
{
h1
{
font-size: 40px;
}
}
Responsive Typography Using CSS Responsive Units
There are some CSS units which depend on viewport size. Therefore they scale according to the viewport size.
These units are: vw, vh, vmin and vmax.
1vw = 1% of viewport width
1vh = 1% of viewport height
1vmin = 1vw or 1vh, whichever is smaller
1vmax = 1vw or 1vh, whichever is larger
An example of responsive heading using using CSS responsive units:
{
font-size: 5vw;
}
CSS responsive units are not yet supported by all browsers. Therefore its very risky to use it. All websites I have seen till now use media queries to implement responsive typography.
CSS Relative Units with CSS Media Queries
em and rem are called css relative units.
em is relative to the font size of parent element. 1em is equal to the current font size of parent element. 2em means 2 times the size of the current font. E.g., if an element is displayed with a font of 10 px, then ‘2em’ is 20 px. We can achieve responsive typography by just changing the parent element’s font size using css media queries for different viewport sizes.
<html>
<head>
<style>
@media screen and (min-width: 1200px)
{
body
{
font-size: 12px;
}
}
/* viewport-width >= 992px and viewport-width <= 1199px */
@media screen and (min-width: 992px) and (max-width: 1199px)
{
body
{
font-size: 10px;
}
}
/* viewport-width >= 768px and viewport-width <= 991px */
@media screen and (min-width: 768px) and (max-width: 991px)
{
body
{
font-size: 8px;
}
}
/* viewport-width <= 767 */
@media screen and (max-width: 767px)
{
body
{
font-size: 6px;
}
}
h1
{
/*parent element is body*/
font-size: 2em;
}
h2
{
font-size: 1.5em;
}
h3
{
font-size: 1.3em;
}
</style>
</head>
<body>
<h1>Hello</h1>
<h2>Hello</h2>
<h3>Hello</h3>
</body>
</html>
Problem with em is that em sizing is nested(depends on parent element). Thus, if you have elements with 1.5em and then nest some HTML with elements that also have an em declaration, their sizing multiplies.
rem is the rescue to em. rem is relative to the font size of HTML tag(root element). Therefore its not nested. It works the same way as em unit. But the problem with rem is that its not supported by some old browsers. So if you are using it then don’t forget to provide a backup or else use this polyfill for rem unit called as REM Unit.
<html>
<head>
<style>
@media screen and (min-width: 1200px)
{
html
{
font-size: 12px;
}
}
/* viewport-width >= 992px and viewport-width <= 1199px */
@media screen and (min-width: 992px) and (max-width: 1199px)
{
html
{
font-size: 10px;
}
}
/* viewport-width >= 768px and viewport-width <= 991px */
@media screen and (min-width: 768px) and (max-width: 991px)
{
html
{
font-size: 8px;
}
}
/* viewport-width <= 767 */
@media screen and (max-width: 767px)
{
html
{
font-size: 6px;
}
}
h1
{
/*relative to html tag*/
font-size: 2rem;
}
h2
{
font-size: 1.5rem;
}
h3
{
font-size: 1.3rem;
}
</style>
</head>
<body>
<h1>Hello</h1>
<h2>Hello</h2>
<h3>Hello</h3>
</body>
</html>