Specify width in *characters*

CssFont Size

Css Problem Overview


When using a fixed width font, I'd like to specify the width of an HTML element in characters.

The "em" unit is supposed to be the width of the M character, so I should be able to use it to specify a width. This is an example:

<html>
  <head>
    <style>
      div {
        font-family: Courier;
        width: 10em;
      }
    </style>
  </head>
  <body>
    <div>
      1 3 5 7 9 1 3 5 7 9 1
    </div>
  </body>
</html>

The result is not what I wanted as the browser line breaks after column 15, not 10:

1 3 5 7 9 1 3 5
7 9 1

(Result in Firefox and Chromium, both in Ubuntu.)

Wikipedia's article says that an "em" is not always the width of an M, so it definitely looks like the "em" unit can't be trusted for this.

Css Solutions


Solution 1 - Css

ch unit

The unit you're looking for is ch. According to the MDN docs:

> 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.

It is supported in current versions of major browsers (caniuse).

Example

pre {
    width: 80ch; /* classic terminal width for code sections */
}

Solution 2 - Css

1em is the height of an M, rather than the width. Same holds for ex, which is the height of an x. More generally speaking, these are the heights of uppercase and lowercase letters.

Width is a totally different issue....

Change your example above to

<div>
    <span>1</span> 3 5 7 9 1 3 5 7 9 1
</div>

and you will notice width and height of the span are different. For a font-size of 20px on Chrome the span is 12x22 px, where 20px is the height of the font, and 2px are for line height.

Now since em and ex are of no use here, a possible strategy for a CSS-only solution would be to

  1. Create an element containing just a &nbsp;
  2. Let it autosize itself
  3. Place your div within and
  4. Make it 10 times as large as the surrounding element.

I however did not manage to code this up. I also doubt it really is possible.

The same logic could however be implemented in Javascript. I'm using ubiquitous jQuery here:

<html>
  <head>
    <style>
      body { font-size: 20px; font-family: Monospace; }
    </style>
    <script 
      type="text/javascript" 
      src ="https://ajax.googleapis.com/ajax/libs/jquery/1.7.0/jquery.min.js">
    </script>
  </head>
  <body>
    <div>1 3 5 7 9 1 3 5 7 9 1</div>
    <script>
      $('body').append('<div id="testwidth"><span>&nbsp;</span></div>');
      var w = $('#testwidth span').width();
      $('#testwidth').remove();
      $('div').css('width', (w * 10 + 1) + 'px');		
    </script>
  </body>
</html> 

The +1 in (w * 10 + 1) is to handle rounding problems.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionMartin VilcansView Question on Stackoverflow
Solution 1 - Csstransistor09View Answer on Stackoverflow
Solution 2 - CssGerd RiesselmannView Answer on Stackoverflow