Converting CSS Pixels to Rems
Cory Rylan
- 3 minutes
CSS has many different measurement value types. While px or pixels are the most common, there are some advantages of the other available types. One of these value types is the rem. This post will see how rem works and how you can create "relative pixels" to make your Web pages more accessible and scalable.
Rem is a relative value based on the base font size of the web page. This means if your base font size changes on the page, anything using rem will scale relative to that font size.
html {
font-size: 16px;
}
h1 {
font-size: 1.5rem; /* 24px */
}
p {
font-size: 1rem; /* 16px */
}
By default, the base font size on the Web is 16px. So if we use 1rem
, we get a font size of about 16px
. If we use a rem value of 1.5rem
, then we get around 24px
. So let's change the base font size to say 20px
.
html {
font-size: 20px;
}
h1 {
font-size: 1.5rem; /* 30px */
}
p {
font-size: 1rem; /* 20px */
}
By increasing the base font size, we also increase the scale of anything on the page using rem. This is helpful for responsive typography but also accessibility. Using rem, we can allow the user to scale the browser default font size, and our UI remains functional and scalable.
Accessibility
If we use px, the user cannot adjust the font size, which can be a serious issue with any vision impairments. I am not talking about browser zoom, which scales the page; I am referring to font size settings within Chrome. Go ahead and try it yourself and see how it can work great with rem but break with px.
Now thinking in rem is not always easy. For example, we could use a CSS Processing language like Sass or a tool like Post CSS to convert our px to rem. However, there is a way to accomplish this natively using CSS Custom Properties (CSS Variables).
Relative Pixels
Using CSS Custom Properties and CSS Calc, we can create dynamic rem values but express them as px variables.
html {
font-size: calc((var(--base) / 16) * 100%);
--r32: calc((32 / var(--base) * 1rem));
--r24: calc((24 / var(--base) * 1rem));
--r16: calc((16 / var(--base) * 1rem));
--base: 16;
}
h1, h2, h3, p {
font-weight: normal;
margin: 0 0 var(--r24) 0;
}
p {
font-size:16px;
}
h1 {
font-size: var(--r32);
}
h2 {
font-size: var(--r24);
}
We are creating a --base
variable that can be used to adjust the base value calculated to create our rem value. For example, using a px value divided by the base, we can have a px percentage converted to rem by multiplying to 1rem.
So in the case of --r24
, it stores the value of 24
divided by --base (16)
, then we convert to rem * 1rem
. Now we can refer to --r24
as a "relative" pixel representing 24px in Rem.
<h1>Relative 32px / 2rem</h1>
<h2>Relative 24px / 1.5rem</h2>
<h3>Relative 16px / 1rem</h3>
<p>Fixed 16px</p>
In this screenshot, you can see the regular px and rem are the same for size 16.
However, if we increase our browser font size, we can see px
value fails to scale in the browser properly.
By using rem, we allow our UI to scale appropriately and improve the accessibility of our sites. This trick of using CSS Custom Properties is handy for Web Components. Using Web Components and Rem works like regular HTML and CSS; however, if your component ships with a different base font than the consuming application, your rem values could be off. But by storing our --base
variable, we can easily adjust the base value for our Web Components by sharing the same --base
variable.
Check out the full working demo below!