Building Resizeable Components with Relative CSS Units

Share this:

The following is a guest post by Ahmad Shadeed. Ahmad has put together a ton of examples to show off how using relative units can benefit us. I think a lot of us think of units like em as being for font-size, which it is, but can also be for lots of other things, tying together typographic sizing and other visual elements.

We are living in a dynamic world, everything we do could be changed at anytime. We, as Front-End Developers should build our layouts in a dynamic approach.

In this article, we will explore a concept that lets us resize our components by using CSS relative units (%, em, or rem). Not just the type size, but all the UI in that component. We'll look at practical examples, pros and cons of the approach, and even a complete web page built out in this manner.

The only way to resize the entire component proportionally, then, is to adjust the font-size of each element manually to match each other at a new size. Perhaps your client tells you they'd like to see that area 1.5× bigger, you'd have to adjust those sizes to 21px and 54px respectively.

To make things a bit easier to adjust, we could use percentage font sizing.

.post-category {
font-size: 85%;
}
.post-title {
font-size: 135%;
}

This is saying: the font-size should be 85% of its closest parent element with a defined font-size.

When we use em for values other than font-size, the computed pixel value it represents is still based on font-size. This is unlike, say, percentages, where a percentage width is based on the width of the parent, not the font-size!

For instance, if we set:

.post {
font-size: 24px;
border-left: 0.25em solid #4a90e2;
}

The border-left-width will compute to 6px.

In the following interactive demo, the slider changes the font-size on both components. The first everything set in pixels: font-size, border, margin, and padding. The second sets all those things in ems:

Proportional Buttons

Sometimes we need variations of a button. Perhaps a bigger version to emphasize a more important call to action. We can benefit from em units by using it for the padding, that way we can easily increase the size of the button through both font-size and padding.

We'll set everything with relative units like we've touched on already. The decorative icon we will place with an SVG image applied via a pseudo element. We'll position that pseudo element absolutely, again with relative positioning and sizing, leaving enough space for it (with relative padding) on the parent element.

All the classics are set in relative units here: padding, border, border-radius... but we've also used relative units for both the background-position and the background-size. Now it all scales up nicely!

Limiting Line Length, Only When You Need To

Take a block of content like this:

We have quite a bit of horizontal space there. Without limiting anything, the line length of that paragraph would have been a bit too long to be comfortable. Setting max-width is a great way to limit line-length. We probably wouldn't set it in pixels (for all the same reasons we've been covering all along: it doesn't scale) and we probably wouldn't use percentages either, as at narrower widths, 100% is likely fine. Relative units it is!

<div class="hero">
<h2>This is title for this hero section</h2>
<p>And this paragraph is a sub title, as you know I'm writing an article about using em units to build dynamic components.</p>
<a href="#">Read about hero</a>
</div>

SVG Icons in Buttons

One of the reasons people cite liking working with icon fonts is that the font is automatically sized along with the text. But that can also work with <img> (as we've seen), and can work with inline <svg> icons as well!

We'll use em values to set the width and height, and then the icons will scale proportionally as the font scales.

Image Sprites

Some things have fixed sizes that are a lot easier to think about in pixels, like raster images. But that doesn't mean we still can't work with them in relative units. If we combine background-position and background-size in ems, we can use CSS sprites that can scale in size.

Combining em and rem

We've mainly used the em unit throughout this article. We established that the em unit is based on font-size and cascades. But em has a cousin unit: rem. The rem unit is still relative, but relative only to the root (e.g. html {} or :root {}). So it doesn't really cascade like em does, but if you change the root font-size, it will change accordingly.

By combining em and rem, we can keep some sizes fixed and keep the other dynamic. For example, say you wanted the text in these components to be only relative to the root, but have other elements be relative to the more immediate font size. Like the image, for example:

It just can be weird to see two different em values in the same element evaluating to the same end value.

This is in addition to the fact that the cascading effect of ems is sometimes challenging in itself. If you size things inside components in ems and those components can be nested, that can cause cascading of sizes that may be undesirable.

Closing up

Sizing in pixels is harder to maintain. They aren't relative to anything else. You need to manually adjust all of them to change a proportion. Difficult, time consuming, error prone.

Settings values in ems makes things proportional to the font-size, so changing the font-size scales all the values on that element (and cascades to the children).

Setting font sizes in pixels may prevent the user from changing their default font size via their browser settings, which is no good for accessibility.

Further reading

Share this:

Comments

“Quite often using ems for any of that kind of layout stuff is actually preferable to using pixels because an em is related to your type so that there’s an inherent relationship between the layout and the typeface that you’re using.”

Compare CSS-Tricks.com and americanpressinstitute.org at different font sizes set by your browser and you’ll see a stark difference.

In Chrome, go to Settings and search for Font Size ( or put this in the URL bar chrome://settings/search#font).

In Firefox, go to Preferences, Content, and increase the font size.

Set the font size to very large and compare the two sites. CSS-Tricks is laid out in pixels and this looks nearly the same. The American Press Institute site is laid out using ems so it scales relative to the font size set by the browser.

Why is this important in terms of accessibility? Those with low-vision need larger font sizes to read. They could go to every site and hit Control or Command + a couple of times to scale the website up. Or they could change the default font size setting of the browser and be done for all sites they visit. A well designed site with this use case in mind should adjust to the readers preference for a larger font size.

Wait, you’re already doing this in your example pens. Why are the written examples in the article showing with ems? You should just show your em() helper right from the start, it solves a lot of the challenges at the end of the article.

Thanks so much for your suggestion. You’re right, We are using a Sass function to help in calculating the em value. The code snippets use em units just to make it simple for people who are not aware of CSS Pre-Processors. I think that it’s important to explain things in CSS (behind the scenes) instead of just showing a specific Sass function.

I will find a way to add a section on using the Sass function so more people can learn about that.

Nice article. I have been using px for very long time and i am planning to move to relative units. I have a questions. If we specify parent font size in px, child elements with em will use that. But if we don’t specify font size to parent, what font size it take?
Thank you

Nice round-up! The demos illustrate perfectly how powerful ems are and I hope to see many more folks adopting this method globally in their designs.

I’ve made a few sites using only ems and it makes life so much easier when incrementally upscaling for oversized “desktop” displays; just increase the root font-size in a media query and BAM! Everything proportionally bigger with only one little edit :)

One thing I’ve tried is using em for sizing throughout with a root font-size set with vw. This makes the site scales proportionately as the browser is resized. I set some media query breakpoints that raise/lower the root vw, and adjust design as needed.

Very nice article.
Disagree with the comments on font-size and accessibility. Yes most browsers can scale even fixed fonts these days, but not always, and it is tested for so why not mention it as a plus since it’ll fill in the small gaps?

Would be nice if your svg examples used aria or similar so you show everything with the most accessibility possible (without over doing it), to go with all the other meticulously done things shown.

Could someone please explain me why we want the scaling in the first place?

When ever I encounter an article that touts the wonders of em or rem scaling I never see a good explanation for scaling like this. Everyone just seems to jump to the nitty gritty of the tech instead of talking about why.

As a sidenote ie9 started supporting font scaling even with px values and even before that many browser vendors started supporting zooming. You can actually zoom the website with code simply by setting html{zoom:150%;}

If you’re talking about scaling based on browser width, what are the optimal values to scale, how did you come up with them and why?

Very helpful article. I was looking forward using proportional units for long but didn’t really find an article explaining it with this amount of examples showing every side of it. I am having a new project coming up soon and I am planning to start using the proportional units. With this article as reference, I wouldn’t fear getting lost in the woods :D

This comment thread is closed. If you have important information to share, please contact us.

Related

How do you stay up to date in this fast⁠-⁠moving industry?

A good start is to sign up for our weekly hand-written newsletter. We bring you the best articles and ideas from around the web, and what we think about them.

👋

CSS-Tricks* is created, written by, and maintained by Chris Coyier and a team of swell people. It is built on WordPress and powered up by Jetpack. It is made possible through sponsorships from products and services we like.