With every complex feature in CSS, you’ll always have that turning point when you see how truly powerful the feature is. And, believe it or not, my personal turning point with ems came long after I wrote a pun-filled introduction to the subject.
Although I understood ems fairly well by that point, I really started to see how powerful they are when I read Simurai’s post on Medium called Sizing (Web) components.
So I’m going ride his coattails in this post. Here you’ll find a quick introduction to em units, followed by a live demonstration of the technique he describes.
What are ems?
In CSS, an em unit is equal to the computed
font-size for the element to which the em is applied. When em units are declared on child elements that don’t have a
font-size defined, they will inherit their
font-size from their parent, or from another ancestor element, possibly going all the way back to the root element on the document.
Look at the following CSS:
In this case, 1em on this element, or on its child elements (assuming no other
font-size definitions), would be equal to 20px. So if we added a line:
border-radius value of
.5em computes to 10px (i.e. 20*.5). Similarly:
The padding value of
2em is equal to 40px (20*2). As mentioned, this type of calculation would apply to any child elements as well — unless any of those child elements had an explicitly defined
font-size value, in which case the em value would be calculated based on that. If no font size is defined anywhere in the CSS, the em unit will be equal to the browser’s default font size for the document, which is usually 16px.
I think that should make it clear how ems work. Now let’s look at how this technique can be used to make easily resizable web components, as discussed by Simurai in the original Medium article. I’ll take his idea a step further by providing a demo to see this in action.
The concept of “components” is pretty popular right now. It works well with modular CSS techniques as well as with the idea of encapsulated sections of code in general. And I’m guessing the following technique will be even more interesting when the Web Components spec becomes widely supported.
The technique basically works like this: The
font-size property is used, as Simurai refers to it, as a “trojan horse”, creating the base unit for the various elements inside our component, or module. Since em units, as described above, are calculated based on the root-defined
font-size on the parent element, this makes the entire component easily resizable by simply changing the
font-size on the parent element.
Let’s look at this in action in a CodePen demo:
See the Pen Using ems for resizable components by SitePoint (@SitePoint) on CodePen.
This silly little module has four basic elements in it. Nothing fancy, just an example to illustrate this technique. Move the range slider at the top of the demo page to change the size of the module. You can also test it at full screen. The range slider is hooked onto a single value on the root element for the component: The
It should be noted here that the purpose of making the component resizable using this single CSS property is not necessarily so that the user can do this. It’s mainly so that the developer maintaining the module can make adjustments quickly, without fiddling with the different values in all parts of the component.
As described in the previous section, as the font size changes, this trickles down to all the em values that are set on that parent element as well as to all of its child elements, making all parts of the component proportionally flexible.
If you examine the CSS, you’ll notice the following:
- Everything inside the component is sized with ems, except the outside border (which we want to remain at 2px at all times), and the image, which I could resize if we wanted it to, but I’m happy with its size being static for this case.
- The teardrop-like thing in the top right corner is a pseudo-element, which likewise benefits from the base
font-size on the parent.
- The CSS also includes two media queries that adjust the
font-size on the parent. Again, this shows the usefulness of this technique because you don’t have to change all the various sizes in the media queries, but only the
Some Notes, Flaws, etc.
As you can see from using the range slider in the demo, this type of flexible resizing isn’t always something you’ll want to use. It can be somewhat restricting.
You may have to tweak some of the em values to get them how you like, and, as in the case of the parent border in the demo, you may not want the resize-ability to apply to all elements. You can overcome this easily by simply avoiding ems on the elements you want to leave out.
As described in the discussion on Simurai’s original article, you don’t have to use px units to set the root
font-size. You can use ems for that too, but just remember that this will be inherited in the same way from its parent, possibly coming from the document’s default value for
What About rems and Sass?
The rem unit in CSS always inherits its value from the base font size setting on the root element of the document, irrespective of the computed font size. In HTML, the root element is always the
html element. So you could use rems, but this would mean you’ll have to control all components on the page using the font size on that element. It could work on certain projects, but I think this technique works best when focusing the resizability on an isolated component, rather than the whole document.
As for using a preprocessor like Sass, I think that’s a side point. Ultimately, your compiled stylesheet will use whatever units you’re using in your Sass code, and the inheritance will work the same way.
As already mentioned, Simurai deserves the credit for making this technique more widely known. Of course, as he mentions, this is nothing new and the basic concept has been used by many experienced developers for years — but maybe not so much in the context of web components, or modules.
As Simurai says, I think this is a nice method to use when building a CSS framework or library of components, and, if nothing else, I think the technique really drives home the point about how powerful em units are.
If you have any feedback or experience with a similar technique, or have any ideas for how this concept can be improved, I’d be glad to hear your comments.