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 a margin of a half line: margin-bottom: 0.5em;
  • The line-height of elements should be 20% greater than the font-size: line-height: 1.2em;
  • A input for the year, should always have the width 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's font.

em - Represents the calculated font-size of the element. If used on the font-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>

Tags:

Css