Why is a monospace font set to 80em taking up less than 80 columns of text?

I'm trying to make some text on a webpage look like a page from Gopherspace. In other words, monospace font with a maximum of 80 columns. I figured that if the font is monospace and I set the width of the containing element to 80em, that would constrain it to a perfect 80 columns since every character should be the same width in a monospace font.

The colors I've added are just to make it easier to tell where line breaks occur.

In case this works on some browsers/computers and not others, here's what I see on my computer, which is running Firefox 65.0.1 on Mac OS 10.14.3.

longer than 80 columns

Why is this div almost twice the size of 80 columns of text and how can I fix it?

.plaintext {
  background-color: black;
  font-family: monospace;
  width: 80em;
  font-size: 10px;
  border: 2px solid red;
  overflow-wrap: break-word;
}

.r { color: red; }
.o { color: orange; }
.y { color: yellow; }
.g { color: green; }
.b { color: blue; }
.i { color: indigo; }
.v { color: violet; }
<div class="plaintext">
  <span class="r">0123456789</span><span class="o">0123456789</span><span class="y">0123456789</span><span class="g">0123456789</span><span class="b">0123456789</span><span class="i">0123456789</span><span class="v">0123456789</span><span class="r">0123456789</span>
</div>

1 answer

  • answered 2019-03-14 07:28 Mr Lister

    The font size of a element (measured in em) is the height of the font, not the width.
    (Originally, the word "em" refers to the width of the M, but not many fonts have an M exactly the width of 1em any more.)

    The solution is to use ch as a unit for the width. In monospace fonts, 1ch is the width of a character. In variable-width fonts, 1ch is the width of the 0 (zero) character.
    See the official definition at the W3C or the more readable MDN version.

    .plaintext {
      background-color: black;
      font-family: monospace;
      width: 80ch;      /* changed */
      font-size: 10px;
      border: 2px solid red;
      overflow-wrap: break-word;
    }
    
    .r { color: red; }
    .o { color: orange; }
    .y { color: yellow; }
    .g { color: green; }
    .b { color: blue; }
    .i { color: indigo; }
    .v { color: violet; }
    <div class="plaintext">
      <span class="r">0123456789</span><span class="o">0123456789</span><span class="y">0123456789</span><span class="g">0123456789</span><span class="b">0123456789</span><span class="i">0123456789</span><span class="v">0123456789</span><span class="r">0123456789</span>
    </div>