Specify width in *characters*

90,323

Solution 1

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.

Solution 2

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 */
}
Share:
90,323
Martin Vilcans
Author by

Martin Vilcans

Programmer with background in games, mobile, and web. Favorite languages: Rust and Python. Occational blog: http://www.librador.com Twitter: https://twitter.com/vilcans

Updated on May 31, 2020

Comments

  • Martin Vilcans
    Martin Vilcans about 4 years

    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.

  • Martin Vilcans
    Martin Vilcans over 12 years
    I was hoping for a pure CSS solution, which only is possible if you happen to know the ratio between the height and the width of a character (see stackoverflow.com/questions/1255281/…). I'm accepting this as the answer as it seems to be a robust solution.
  • waldyrious
    waldyrious about 10 years
    There's also the figure space, which is precisely "equal to the width of one digit" as described in Wikipedia's space (punctuation) article. It's Unicode value is U+2007 and it can be entered in HTML using &#x2007; or &#8199;. It's functionally equivalent to the ch unit of CSS, but while that isn't widely supported, it can be used as a workaround in HTML (ugly hack, but should work).
  • waldyrious
    waldyrious about 10 years
    Actually, according to this chromium issue, Chrome supports it since v27, so right now the latest versions of all the major browsers (IE, Chrome and Firefox) support the ch unit :)
  • user420667
    user420667 over 8 years
    One should note the character size is the size of the glyph '0' in the element's font. If you expect larger characters like 'm' or 'w' you might want to consider expanding accordingly or having it expand as needed (e.g. stackoverflow.com/questions/7168727/…)
  • Louis
    Louis about 8 years
    very useful. I added a sample.
  • Willege
    Willege about 8 years
    The ch unit considers the width of the '0' - it doesn't really assure, for example with max-width: 90ch; that the lines of text will actually all be less than or equal to 90 characters.
  • transistor09
    transistor09 about 8 years
    @Willege yes, it would be irresponsible to rely solely on this to make, say, a terminal emulator but, if the font is truly monospaced (at least for the characters in use) and there are no rounding bugs, lines should be as long as specified.
  • Willege
    Willege about 8 years
    Yep, no problems with monospaced fonts.
  • Sogartar
    Sogartar over 7 years
    1em is not the height of an M according to the answers here graphicdesign.stackexchange.com/questions/4035/… The "|" character should be closer to 1em.
  • Parapluie
    Parapluie over 7 years
    Sogartar, for clarification: in typography proper 1 em is indeed the width (as well as the em height) of a fixed-width character. However, that is "typography proper" and we have many fly-by-night folks out there creating font files which do not adhere to typographic rules — especially true in the case of web fonts. The point of my comment here is not (merely) curmudgeonly grandstanding. My point is: test, test, test. (And then test some more.)
  • aleha
    aleha over 6 years
  • Mikel
    Mikel over 5 years
    if you want to use ch along with letter-spacing a trick is to set width to the amount of characters in ch + (letter-spacing * (amount characters - 1)). e.g 5 characters with 1px letter spacing: letter-spacing: 1px; width: calc(5ch + 4px).
  • jcubic
    jcubic almost 4 years
    This is one issue to consider, if you need to support IE11 there is bug in ch unit, where it's smaller then actual character (because it don't count surrounded spaces), the issue is present since IE9, check CSS3 ch unit inconsistent between IE9+ and other browsers. This can be fixed by using width in JavaScript, If IE is something you support.
  • chetbox
    chetbox about 3 years
    Please use the 'ch' unit. This answer describes it well: stackoverflow.com/a/16586438/244640
  • Aaron Hudon
    Aaron Hudon over 2 years
    Looks at %, em, vw. @transistor90 : "These aren't the units you're looking for" ;)