What is difference between CSS em and ch units?
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:
- All
h2
should be four times as big as the text:font-size: 4rem;
- All
p
should always have amargin
of a half line:margin-bottom: 0.5em;
- The
line-height
of elements should be 20% greater than thefont-size
:line-height: 1.2em;
- A
input
for the year, should always have thewidth
of four numbers:width: 4ch;
- The text width of a
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>