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:
- Relative Units
- 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>
Copy and Paste the following declaration in your CSS file:
div {
font-size: 3em;
}
Save both files.
I have made some assumptions in the explanation below. That:
- Your browser still has its default
font-size
set to16px
- 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:
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:
Your Developer Tools should now be docked to the right similar to the image below:
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
:
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;
}
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 afont-size
of3em
, which the browser computes to48px
- It's the same as 3 * (browser default
font-size
)
- It's the same as 3 * (browser default
-
We gave our paragraph a
font-size
of2em
, which means 2 multiplied by the parentfont-size
, in our case3em
- It's the same as 2 * 3em * (browser default
font-size
) or - 2 *
48px
- It's the same as 2 * 3em * (browser default
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%;
}
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.
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;
}
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 be50%
of the height which equals400px
-
50vmax
will be50%
of the width which equals720px
Let's take some examples. Update your CSS file to match the snippet below:
div {
border: 2px solid #1560bd;
width: 50vmax;
}
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.
Update the unit in the width
property and repeat the steps above.
div {
border: 2px solid #1560bd;
width: 50vmin; /* like this */
}
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;
}
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;
}
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
.
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;
}
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:
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.
If you remove Trebuchet MS
, save and reload the file. The computed font-size
will be different.
%(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>
.parent {
width: 70%;
margin: 0 auto;
padding: 0.7em;
border: 2px solid #1560bd;
}
.child {
width: 50%;
border: 2px solid #ea3c53;
padding: 0.7em;
}
Save you files and load (or refresh) in your browser, you should get an output similar to the image below:
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:
Next, CSS Specificity.