CSS Units

Habdul Hazeez - Oct 29 '19 - - Dev Community

Almost everything you can think of has a unit of measurement e.g 2Mbs, 2 Pounds of flour e.t.c. You should not be surprised when I tell you that there are some mathematical units of measurement that are found in CSS and if you have a thing for math you will find these units comforting and if otherwise, am sorry, you kind of have to know them, but that does not mean you will use them all the time. Lucky you!.

When you read the term "mathematical units of measurement" in the last paragraph, you might be thinking: "Don't tell me I'll have to do math in CSS", hmmmmm, Yes! Of course, but not the likes of Quadratic Equation or Polynomials. The math you will be doing is mostly to ensure:

  • Page elements fit in the position you want them
  • Page layout is consistent
  • The text on your web page is readable in varying devices e.t.c

There are varying units in CSS, they have their ups and downs and they all have specific cases when you can use them in your web page. Some units are best used with font sizes, some are best suited to borders and some are good candidates in media queries.

In CSS, units are categorized into two types:

  1. Relative Units
  2. Absolute Units

RELATIVE UNITS

Relative length units specify a length relative to another length property. Examples are:

  • em
  • rem
  • vmin
  • vmax
  • vw
  • vh
  • ch
  • ex
  • %(percentage)
  • lh

ABSOLUTE UNITS

Absolute length units are fixed in relation to each other. Examples include:

  • in
  • cm
  • mm
  • pt
  • pc
  • px

Now, we'll briefly explain some of these units and give recommendations on where and when they are best used in a web document.

To follow along with the code snippets in this post, create a new Skeleton file with a div and a paragraph, save it with any name you like, preferably css_units.html, create a new CSS file and save it as css_units.css and make sure it's linked with the html file as depicted in the code snippet below. The rest of this post will assume you already created this skeleton html and css file (unless otherwise stated).

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <title>CSS Units</title>
  <link rel="stylesheet" href="css_units.css">
</head>
<body>
  <div>
    <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed
do eiusmod tempor incididunt ut labore et dolore magna aliqua.</p>
  </div>
</body>
</html>
Enter fullscreen mode Exit fullscreen mode

Copy and Paste the following declaration in your CSS file:

div {
  font-size: 3em;
}
Enter fullscreen mode Exit fullscreen mode

Save both files.


I have made some assumptions in the explanation below. That:

  • Your browser still has its default font-size set to 16px
  • You update your CSS or HTML skeleton files to match the code snippet under each explanation
  • You are using the latest version of Firefox or Chrome as of October 2019

All screenshots in this post are from Firefox 70, if you are using Chrome your output will be slightly different but you can still follow along.


em

The Specification states:

The 'em' unit is equal to the computed value of the 'font-size' property of the element on which it is used. The exception is when 'em' occurs in the value of the font-size' property itself, in which case it refers to the font size of the parent element.

This translates to: When the em is used as a unit for an element, the value you specify is the same as the value the browser will calculate for the element's font-size in px. But there is a catch in what the specification states, which is the second part of the statement:

... The exception is when 'em' occurs in the value of the 'font-size' property itself, in which case it refers to the font size of the parent element.

What this means is that: if you specify the font-size of an element in em, the em will be calculated by the browser with respect to the parent's font-size. Say What? Let's explain with some code and images.

Load your skeleton file in your browser. Right-click on the paragraph text and click on "Inspect Element" from the context menu:

Inspect Element in Firefox

By default the browser Developer Tools is docked to the bottom of the page in Firefox, mine is docked to the right. If you will like this, click on the 3 dotted symbol " ... " towards the top-right corner of the Developer Tools and click on "Dock to Right". The image below sums this up nicely:

Devtools in Firefox Docked to the Right

Your Developer Tools should now be docked to the right similar to the image below:

DevTools in Firefox

You will notice in the Rules tab that the paragraph has no font-size of its own but it's using the font-size of its parent which is 3em and the browser says it's "inherited from div" ( inheritance will be discussed in a future lesson). If you switch over to the Computed tab, you'll notice that the browser calculated a font-size of 48px:

Computed Font Size in Firefox DevTools

Now, the question is: How did the browser arrive at 48px? Let's do some math!

Most browser have default values for most HTML Elements, for most browser, the default value for the font-size is 16px. And in CSS 1em is equal to 16px. So we have:

  • 1em = 16px
  • 3em = 3 * 16px = 48px (the computed value by the browser)

Now let's demonstrate the "exception" the specification mentioned.

Add the following declaration to your CSS file:

p {
  font-size: 2em;
}
Enter fullscreen mode Exit fullscreen mode

Save your file, and refresh your browser. The font-size of the paragraph will be enormous, and if you use "Inspect Element" on it, you will notice that the browser is now using the font-size you specified i.e 2em and it ruled out the font-size of the parent element, the div.

But that does not mean the browser is not using the ruled out value. Switch over to the Computed tab you'll see the browser calculated a computed value of 96px for the paragraph. What? Why? How? Let's do some math.

Remember that by default:

  • 1em = 16px

Which means our parent element font-size in 'em' will be multiples of 16px, so we have:

  • 2em = 32px, which is 2 * 16
  • 3em = 48px, which is 3 * 16.

Now if you recall, we gave our div element a value of 3em. And the spec says:

... The exception is when 'em' occurs in the value of the 'font-size' property itself, in which case it refers to the font size of the parent element.

This is exactly what we did, we gave our paragraph a font-size specified in 'em' and the browser will now calculate its font-size relative to the font-size of the parent element, in this case, the div.

So here is the thing:

  • We gave our div element a font-size of 3em, which the browser computes to 48px
    • It's the same as 3 * (browser default font-size)
  • We gave our paragraph a font-size of 2em, which means 2 multiplied by the parent font-size, in our case 3em

    • It's the same as 2 * 3em * (browser default font-size) or
    • 2 * 48px
  • 2 * 3 * 16 will equal 96

  • 2 * 48 will equal 96

That's how the browser computed the 96px when we specified the font-size as 2em. Now you might be thinking, if we can increase the font size can we decrease it? Of course!, make sure the value you specify as your 'em' value is less than one (1) when you do this the browser will do some division along with the routine multiplication.

So, if you change the font-size of the paragraph to 0.65em, in math 0.65 can be written as 65/100 so the browser will calculate the font-size as:

  • 65/100* (browser default) * (parent font-size)
  • 65/100 * 16 * 3 => (65 * 16 * 3)/100 => 3120/100 => 31.2

Go ahead, give it a try.

rem

The rem unit was introduced in CSS3 and it stands for "root em". The em unit is relative to the font-size of the parent, which causes the compounding issue. The rem unit is relative to the root element.

The root element in HTML is the html element itself, which means we can define a single font size on the html element and define all rem units to be a percentage of that.

Given the CSS code snippet below, we defined the html font-size as 65.2%. Now, you might ask 65.2% of what exactly?. The browser default font-size of 16px. Update your CSS file to match the snippet below:

html {
  font-size: 62.5%;
}
Enter fullscreen mode Exit fullscreen mode

Save your CSS file and load it in your browser. The font-size of the paragraph will be small. Using "Inspect Element", you will realize the browser computed a font-size of 10px. How? Let's find out.

Computed Font Size in Chrome

In Mathematics 65.2% is the same as 65.2/100 which can be written as 0.652. And when you hear a phrase like "2% of 100" it's the same as saying "2% multiplied by 100". Why multiplication? When the word "of" appears in the context of numbers in math its means multiplication, so when I mentioned earlier that "65.2% of the browser default font-size" its the same as "65% multiplied by the browser default font-size". Which is:

  • 65.2% * 16 or
  • 0.652 * 16

The calculation above equals 10, which is the same value computed by the browser. This value is now the root em.

If we apply the following declaration to our paragraph, the browser will compute a value of 14px.

p {
  font-size: 1.4rem;
}
Enter fullscreen mode Exit fullscreen mode

In the code snippet above:

  • 1.4rem means "1.4 of the root em"
  • This can be written as "1.4 * 10".
  • Which equals 14.

vmin and vmax

These units work with the width and height of the viewport which is actually the available browser window. The difference between these units are:

  • vmin selects the minimum value between the height and width
  • vmax selects the maximum value between the height and width

For example if the viewport has a width of 1440px and height of 800px:

  • 50vmin will be 50% of the height which equals 400px
  • 50vmax will be 50% of the width which equals 720px

Let's take some examples. Update your CSS file to match the snippet below:

div {
  border: 2px solid #1560bd;
  width: 50vmax;
}
Enter fullscreen mode Exit fullscreen mode

Given the code snippet above, the width of the div element will change depending on the viewport height and width. To see this in action:

  • Use the browser "Inspect Element" on the div element, this will open the Developer Tools
  • Switch to the Computed tab and take note of the computed width
  • Resize the Developer Tools window or browser Window.

You will observe the width will change if you get to a certain window size or height.

CSS vmin and vmax demonstrated in Firefox By resizing the Browser window

Update the unit in the width property and repeat the steps above.

div {
 border: 2px solid #1560bd;
 width: 50vmin; /* like this */
}
Enter fullscreen mode Exit fullscreen mode

vh and vw

vh and vw stands for:

  • viewport height
  • viewport width

These units are similar to vmin and vmax and they are equivalent to 1% of the viewport's height and width.

Update your CSS file to match the snippet below:

div {
  border: 2px solid #1560bd;
  width: 50vh;
}
Enter fullscreen mode Exit fullscreen mode

Repeat the experiment under the vmin and vmax by resizing your browser window and observe the computed width in the Browser Developer Tools.

ch

From the Mozilla Developer Network:

Represents the width, or more precisely the advance measure, of the glyph "0" (zero, the Unicode character U+0030) in the element's font. Update your CSS file to match the code snippet below:

Update your CSS file to match the snippet below:

div {
  font-size: 1ch;
  border: 1px solid black;
}
Enter fullscreen mode Exit fullscreen mode

Save the code, and load the file in your browser, Use "Inspect Element" on the paragraph. In Firefox and Chrome the computed font-size is 8px and If you use Internet Explorer the computed font-size is 16px.

The ch unit demonstrated in Firefox

ex

The 'ex' unit is similar in behavior to the 'em' unit, but the 'ex' unit has to do with an element's height.

The specification states:

The 'ex' unit is defined by the element's first available font. The exception is when 'ex' occurs in the value of the 'font-size' property, in which case it refers to the 'ex' of the parent element.

This translates to: If the 'ex' unit is used on an element, the height computed by the browser will depend on the available font. And if used directly as the font-size unit of an element it will be calculated relative to the parent's height.

So, by default:

  • 1ex = 7.15px

Which means our parent element font-size specified in 'ex' will be multiples of 7.15px:

  • 2ex = 14.3px which is 2 * 7.15
  • 3ex = 21.45px which is 3 * 7.15

Now, when we give our paragraph a font-size in 'ex', the browser will calculate the font-size relative to the parent's height. And this value will vary depending on the first available font. First available font? Let's explain that with code and some images.

We will be using our previous code samples with a slight modification. Update your CSS to match the code snippet below:

div {
  font-family: "Times New Roman","Trebuchet Ms", Helvetica, Verdana;
  font-size: 3ex;
}

p {
  font-size: 1ex;
}
Enter fullscreen mode Exit fullscreen mode

Save and load the file in your browser. The font-size will be very small, this is because the font-size is calculated based on the height of the first available font in our case its Times New Roman. Use "Inspect Element" on the paragraph, navigate to the Computed tab, and check out the font-size, it should be similar to the image below:

CSS ex unit in Firefox DevTools

Now, update the font-family property by removing the first font "Times New Roman", which will leave you with Trebuchet Ms, Helvetica, and Verdana, Save the file and reload it in your browser. Check out the Computed tab, the font-size will be different.

CSS ex unit in Firefox Devtools

If you remove Trebuchet MS, save and reload the file. The computed font-size will be different.

CSS ex unit in Firefox DevTools

%(percentage)

Understanding the percentage unit is quite straightforward, it measures relative to the parent length. So, when the parent width is 900px then 50% would become 450px.

Update you skeleton html and CSS files to match the snippet below:

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <title>CSS Units</title>
  <link rel="stylesheet" href="css_units.css">
</head>
<body>
  <div class="parent">
    <div class="child">
      <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod
tempor incididunt ut labore et dolore magna aliqua.</p>
    </div>
  </div>
</body>
</html>
Enter fullscreen mode Exit fullscreen mode
.parent {
  width: 70%;
  margin: 0 auto;
  padding: 0.7em;
  border: 2px solid #1560bd;
}

.child {
  width: 50%;
  border: 2px solid #ea3c53;
  padding: 0.7em;
}
Enter fullscreen mode Exit fullscreen mode

Save you files and load (or refresh) in your browser, you should get an output similar to the image below:

Alt Text

The .child class will always be 50% of .parent irrespective of the viewport. Try resizing your browser window.

The remaining units are absolute length units and are generally considered to always be the same size.

  • in: inches — 1in is equal to 2.54cm.
  • cm: centimeters
  • mm: millimeters
  • pt: points — the points used by CSS are equal to 1/72nd of 1in.
  • pc: picas — 1pc is equal to 12pt.
  • px: pixel units — 1px is equal to 0.75pt.

We did not discuss the lh unit because it's experimental as of October 2019 and not widely supported as depicted in the caniuse image below:

Alt Text

Next, CSS Specificity.

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .