What is difference between CSS em and ch units?
I have been using ch in my stylesheet, but em seems more common. What is the difference between them?
I understand that 20ch would give enough space for 20 zeroes. I don’t understand what em is. Does it give enough space for 20 M's or is it 20 x fontsize, i.e. size 16 font would give 320, but 320 of what unit? I don't get if they are almost the same or completely different.
The CSS ch unit is defined as the width of the character 0 (zero, or U+0030) of the font. While the ch unit works as an exact measurement for monospaced / fixed width fonts like Courier, it can be unpredictable with proportional fonts like Arial.
EM is relative to the parent element's font size, so if you wish to scale the element's size based on its parent's size, use EM. REM is relative to the root (HTML) font size, so if you wish to scale the element's size based on the root size, no matter what the parent size is, use REM.
Pixels are the most commonly used and accepted unit. And it's considered the base of measurement for many other units. It provides the most consistent result among various devices. The box element in the following example has a height of 150px and width of 150px, and it will remain the same on all screen sizes.
There are two types of length units: absolute and relative.
I've looked at all the answers and also your comments on them and I got the feeling that you want using em
and ch
units mainly for width
or height
properties.
[...] they are not good for setting a field width then?
And from my perspective, I would not recommend that.
CH-Units
First of all, I've never worked with ch
before and honestly I do not see any real use for it - maybe an input
for the year, so that there is always the width for four numbers, but not more - because it never tells you exactly how wide an element will end up.
I changed my mind and now I see a good real use for ch
. :)
The example of an input
for the year, so that there is always the width for four numbers, will persist. But ch
is also very useful for correctly defining the text width of a paragraph.
With pixel, relative or percentage values it is very difficult - especially for a responsive design - to set the perfect text width per line including spacing for a paragraph. However, this can be a liability for the user experience on the website. An abstract by Atlassian Design is a perfect match:
Set the reading environment to suit the reader. Wide lines of text are difficult to read and make it harder for people to focus. While there is no right way to measure the perfect width for text, a good goal is to aim for between 60 and 100 characters per line including spacing. Setting an optimal line length breaks up content into easily digestible blocks.
Source: Atlassian Design
This is where ch
can be used perfectly as a unit. For a better view, you can look at the examples at the end.
But now finally to the definition of ch
;)
As often been said, ch
refers to the width of the 0
character to its font size.
As example: The body has a font-size: 16px
and the 0
character has a width of 10px
from the selected font-family, then 1ch
equals 10px
. And even that is still inaccurate, because e.g. italic
or bold
can change the width of the character.
EM- & REM-Units
As also often said, em
- and to bring one more player in - also rem
are relative to the font-size
.
Where rem
is always relative to the root element font-size
, em
is relative to the font-size
of the own element or the last parent element (can be also the root element) with a font-size
.
As em
example: Only the body
has a font-size: 16px;
and the element got no font-size
himself, then 1em
equals 16px
. If a parent of the element or the element himself got a font-size: 20px;
, then 1em
equals 20px
. em
units can also multiply upon themselves.
As rem
example: The body
has a font-size: 16px;
, then 1rem
equals 16px
. Even if the element himself or a parent element got a font-size: 20px;
, 1rem
still equals to the body
settings of 16px
.
[...] if ch is size of '0' in font, why is not em the size of 'M' in font [...]
em
was originally based on the typographic measurement of the current font M
character but that is already outdated. As you can see now, it always references to a "fixed start-value" and not the width of a character.
Recommended usage
As I said, from my perspective I would not recommend to use ch
, em
or rem
for width
or height
properties. These units are more useful for "textual" properties.
Some examples:
h2
should be four times as big as the text: font-size: 4rem;
p
should always have a margin
of a half line: margin-bottom: 0.5em;
line-height
of elements should be 20% greater than the font-size
: line-height: 1.2em;
input
for the year, should always have the width
of four numbers: width: 4ch;
p
should always have a width of 80 characters per line including spacing: width: 80ch;
but pixels are not flexible when dealing with different devices
For this, as a conclusion, I would advise you to simply work with percentages width: 80%;
or the viewport width and viewport height height: 100vh; width: 100vw;
. Or at least always with a maximum value: width: 1000px; max-width: 100%;
.
Here are a few snippets - just for the examples with width
properties - for a better understanding:
em
- Relative to the font size of the own element or the last parent element with a font size
body {
font-size: 16px;
}
p {
font-weight: bold;
}
div {
width: 1em;
height: 50px;
background: lightgray;
}
.em-0-5 {
width: 0.5em;
}
.em-10 {
width: 10em;
}
.fs-10 {
font-size: 10px;
}
.parent {
font-size: 0.5em;
}
.parent div {
width: 10em;
}
<p>1em (body font-size * 1 = 16px)</p>
<div></div>
<p>0.5em (body font-size * 0.5 = 8px)</p>
<div class="em-0-5"></div>
<p>10em (body font-size * 10 = 160px)</p>
<div class="em-10"></div>
<p>10em from 10px own element font-size (element font-size * 10 = 100px)</p>
<div class="em-10 fs-10"></div>
<p>10em from 0.5em parent font-size (body font-size * parent font-size * 10 = 80px)</p>
<span class="parent">
<div></div>
</span>
rem
- Relative to font-size of the root element
body {
font-size: 16px;
}
p {
font-weight: bold;
}
div {
width: 10rem;
height: 50px;
background: lightgray;
}
.parent {
font-size: 20px;
}
.parent div {
width: 5rem;
}
<p>10rem (body font-size * 10 = 160px)</p>
<div></div>
<p>5rem in a parent element with font-size 20px (body font-size * 5 = 80px)</p>
<span class="parent">
<div></div>
</span>
ch
- Relative to width of the "0" (zero)
body {
font-size: 16px;
}
p {
font-weight: bold;
}
input {
width: 4ch;
}
div {
width: 20ch;
background: lightgray;
word-wrap: break-word;
}
.ch-1 {
width: 1ch;
}
.ch-5 {
width: 5ch;
font-size: 32px;
}
<p>4ch (space of 4x zero character)</p>
<input type="text" value="2018" />
<p>20ch (space of 20x zero characters)</p>
<div>0000000000000000000000000</div>
<p>Also 20ch (space of 20x zero characters)</p>
<div>Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. Aenean massa. Cum sociis natoque penatibus et </div>
<p>1ch (space of 1x zero character)</p>
<div class="ch-1">00000</div>
<p>5ch from font-size 32px (space for 5x zero characters with a font-size of 32px)</p>
<div class="ch-5">0000000000000000000000000</div>
I usually use em
& rem
. It's an easier way of make things responsive and depends of the font-family you choose and not on a specific character.
From MDN <length>
documentation:
ch
- Represents the width, or more precisely the advance measure, of the glyph "0" (zero, the Unicode character U+0030) in the element'sfont
.
em
- Represents the calculatedfont-size
of the element. If used on thefont-size
property itself, it represents the inherited font-size of the element.
<h1>How em works</h1>
<h2>Default values</h2>
<p style="font-size: 1em">I am 1 em on a default browser (10px)</p>
<p style="font-size: 2em">I am 2 em on a default browser (20px)</p>
<hr>
<h2>Inherit values</h2>
<div style="font-size: 18px">
<p style="font-size: 1em">I am 1 em depending on my parent element font-size (18px)</p>
<p style="font-size: 2em">I am 2 em depending on my parent element font-size (36px)</p>
</div>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With