#15DaysOfCSS Day 6: Units

PX and REM and % oh my

Units of measure in CSS are a source of constant confusion for many developers, beginner and experienced. Let's take a quick peek at these, including what's "legal" and what we recommend you use in your work.

Absolute units

An absolute unit is one that is inflexible and unchanging, regardless of context. One cm here is one cm over there. It is what it is.

In general, even though CSS supports absolute units, with the exception of px, they are rarely used in web work. They are more frequently used in printing. (Remember that you may make styles exclusive to printing!)

Units include:

  • Centimeters (cm), millimeters (mm), inches (in)

  • Picas (pc), points (pt)

  • Pixels (px)

One pixel is 1/96th of an inch. This is the only absolute unit regularly used in stylesheets for screens.

Relative units

These are the units that are more difficult to understand but are much more useful in your daily CSS work. A few of the ones we use most frequently include:

  • rem (root-relative em) and em

  • percents

  • vw (1% of the viewport's width), vh (1% of the viewport's height)

em vs rem

Jen shared this video with you last week, but it's worth sharing here again. We've also got a CodePen comparison for you.

Viewport units

There are 100 viewport units available in width and height, regardless of the size of the screen. One vw is 1% of the screen's width. One vh is 1% of the screen's height.

If this is true, why not just say width: 1% instead of width: 1vw ? Because percentages don't always refer to the viewport - they refer to their containing element.

Percentages

See today's CodePen example

Whenever you work with percentages, you should always ask, "what is this a percentage of?"

For example, let's say we have this HTML:

<div class="content">
  <h1>This h1 is 100% wide.</h1>
</div>

And this CSS:

.content {
  border: 2px solid red;
  width: 100%;
}
.content h1 {
  width: 100%;
  border: 2px solid blue;
}

Unsurprisingly, this content stretches completely across the page.

But if we change the HTML to this:

<div class="wrapper">
  <div class="content">
    <h1>This h1 is 100% wide.</h1>
  </div>
</div>

And add one CSS declaration block:

.wrapper {
  width: 50%;
  border: 5px dotted black;
}

How wide are .content and .content h1 now?

They are still 100% wide, even though it looks like this example stretches only halfway across the page.

When width: 100% is set, it is 100% of the width of the containing element. The H1 fills 100% of its containing element, .content. And .content fills 100% of its containing element, .wrapper. However, .wrapper is set to occupy 50% of its containing element, body.

✅ Final pro tip: Think about a row of elements using the border box model. The width of the row is 100%, as the row is the containing element. If you work with percentages for the CSS width of each element inside of the row, plus percentages for margins, it's easy to add everything to 100%.

👉🏿 TL:DR -- anytime you see a percentage for a size, think "x% of what?"

Why are relative units so much more popular than absolute units?

We have not yet discussed responsive design and navbars (next week!). However, as many of you know, responsive design is the process of changing the look of the layout based on viewport dimensions, controlled by media queries.

Relative units may scale and flex with changing designs. Absolute units do not.

There is a time and place for both of these types of units, of course. We’ll explain more as we head into responsive design.

Flexbox is different

When working with Flexbox, there is no width. Instead, there is flex-basis. This property is assigned to the child (or flex-item) and is expressed in one of two formats:

.child-item {
   flex-basis: 25%
   flex: 0 0 25%;
}

The flex declaration is shorthand. The three numbers represent flex-grow, flex-shrink, and flex-basis. (Refer to CSS-Tricks "A Complete Guide To Flexbox" for all the details.)

What's the difference between width and flex-basis?

flex-basis is the "flex" in Flexbox!

If I declare width: 25%, then the width will be 25%. It will not be 24.9%, or 25.1%. It's always 25% (but 25% of what! 😁).

However, flex-basis: 25% says "get me as close to 25% as you can." It may indeed be 24.9%, or 25.1%, or even 15% in some circumstances.

✅ If you're not using flex-basis, then your flexible boxes aren't that flexible.

Grid has its own special unit

When working with Flexbox, we worry about math in our layouts to keep things lined up.

We don't have to do math with Grid if you use the fr or fraction unit. fr is unique to Grid and may not be used elsewhere in CSS.

We won't go into further details (otherwise this email gets REALLY long). Jen has a Flexbox and Grid course available at Frontend Masters that was just updated in August. She explains everything in detail there. Alternatively, CSS-Tricks Complete Guide to Grid is a useful reference.

If you're a qualifying student or teacher, you may get a free 6-month subscription to Frontend Masters with the Github Student Developer Pack.

Let's also talk about height

By default, how tall is an element on a web page? It's as tall as its content, plus any margin, padding, and border involved. That's it. (Remember that two intersecting vertical margins collapse! We discussed this back on Day 2.)

If you set height="100%", the height is set to the height of the content, not the height of the page, or the containing element, as you might expect.

So how do you get the height to stretch to the height of the page?

There have been different solutions to this problem through the years, like faux columns (ah, the good old days) or 15,437 paragraph returns to make the page longer.

Today, the best way to assign height is to use vh units.

⛔️ However, ideally, you never assign height to anything with text inside of it. Some site visitors may wish to enlarge the text on the page using browser controls. The height may or may not scale appropriately. What happens when the text grows outside of your carefully constructed box? Sometimes it's cut off, sometimes scrollbars appear. Either way, it’s not good user experience.

✅ In general, if there's text involved, leave height alone. It is what it is.

Small caveat

Sometimes you'll assign height to a shape without text inside of it. For example, maybe you have a SVG shape, or you're doing something with a <div></div> box like making a colored square or other shape, or you’re displaying a background image. In these cases, height is necessary and should be assigned. You may have trouble if you don't assign height!

Jen's favorite units

Jen teaches students these units in beginning CSS, because all designs are responsive eventually.

  • rem for font sizing, padding, margin (not in layouts)

  • % for margin (in layouts), width, flex-basis

  • px for border widths, media query values

  • fr for CSS grid layouts.

Erika's preference for beginning students

These are the units Erika teaches before her students start responsive design.

  • px for font size, border widths, media query values

  • em for padding, margin because it's then relative to the font sizes

  • % for width

  • we go into rem and managing units as a system a little later in the semester when we pick up flexbox and RWD

🎉📚Get the #15DaysOfCSS e-book📚🎉

These #15DaysOfCSS posts will be compiled into an e-book — pre-order now!

Email is great, and blogs are awesome, but it can be challenging to use them as a reference in the future. We'll be assembling this month's work into an e-book.

Pre-order the book

🖥 Today’s CodePen examples

Today’s CodePen examples map out the code described in this email.

Check out today's examples

👩🏽‍💻 Challenge: Practicing units with boa constrictors 🐍

👩🏽‍💻 Today, we are being swallowed by a boa constrictor, and we must figure out our units of measure before we are digested.

Take the CodePen Challenge

📚 More information and examples

📚 MDN: CSS values and units

📚 CodePen: em vs rem

📚 CSS Tricks: A complete guide to Flexbox

📽 LinkedIn Learning: CSS Print Stylesheets (subscription required)

📽 Flexbox and Grid version 2 at Frontend Masters (subscription required)