Especifique a largura em * caracteres *

108

Ao usar uma fonte de largura fixa , gostaria de especificar a largura de um elemento HTML em caracteres .

A unidade "em" deve ser a largura do caractere M, então devo ser capaz de usá-la para especificar uma largura. Isto é um exemplo:

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

O resultado não é o que eu queria, pois a linha do navegador quebra após a coluna 15, não 10:

1 3 5 7 9 1 3 5
7 9 1

(Resultado no Firefox e Chromium, ambos no Ubuntu.)

O artigo da Wikipedia diz que um "em" nem sempre tem a largura de um M, então definitivamente parece que a unidade "em" não é confiável para isso.

Martin Vilcans
fonte
Eu acredito que "en" também é uma largura legal; é a largura de um dígito na tipografia. Isso pode funcionar melhor para você.
Pete Wilson
6
A propriedade 'em' usa o tamanho da fonte, ou altura , da fonte, não a largura das letras. @Pete: Não é, consulte Módulo de Valores e Unidades CSS Nível 3 .
animuson
A menos que você esteja usando uma fonte de largura fixa, caracteres diferentes têm larguras diferentes. Portanto, é funcionalmente impossível definir uma largura em termos de número de caracteres mostrados.
Emily
"Esta questão ainda precisa de 4 voto (s) de outros usuários para ser fechada" - Ei, é a minha pergunta! Deixa eu fechar!
Martin Vilcans

Respostas:

23

1em é a altura de um M, em vez da largura. O mesmo vale para ex, que é a altura de um x. De modo mais geral, essas são as alturas das letras maiúsculas e minúsculas.

A largura é uma questão totalmente diferente ...

Mude seu exemplo acima para

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

e você notará que a largura e a altura do vão são diferentes. Para um tamanho de fonte de 20px no Chrome, a extensão é de 12x22 px, onde 20px é a altura da fonte e 2px é a altura da linha.

Agora, uma vez que em e ex não são úteis aqui, uma possível estratégia para uma solução somente CSS seria

  1. Crie um elemento contendo apenas um & nbsp;
  2. Deixe que ele se autosize
  3. Coloque seu div dentro e
  4. Torne-o 10 vezes maior que o elemento circundante.

No entanto, não consegui codificar isso. Também duvido que seja realmente possível.

A mesma lógica pode, entretanto, ser implementada em Javascript. Estou usando o jQuery onipresente aqui:

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

O +1 in (w * 10 + 1) é para lidar com problemas de arredondamento.

Gerd Riesselmann
fonte
1
Eu esperava uma solução CSS pura, que só é possível se você souber a proporção entre a altura e a largura de um caractere (consulte stackoverflow.com/questions/1255281/… ). Estou aceitando isso como a resposta, pois parece ser uma solução robusta.
Martin Vilcans
1em não é a altura de um M de acordo com as respostas aqui graphicdesign.stackexchange.com/questions/4035/… O "|" caractere deve estar mais próximo de 1em.
Sogartar
1
Sogartar, para esclarecimento: na tipografia, 1 em é de fato a largura (assim como a altura em) de um caractere de largura fixa. No entanto, isso é "tipografia adequada" e temos muitas pessoas agitadas por aí criando arquivos de fontes que não seguem as regras tipográficas - especialmente verdade no caso de fontes da web. O ponto do meu comentário aqui não é (meramente) arrogância mesquinha. Meu ponto é: teste, teste, teste. (E então teste um pouco mais.)
Parapluie
217

ch unidade

A unidade que você está procurando é ch. De acordo com os documentos MDN :

ch: Representa a largura, ou mais precisamente a medida de avanço, do glifo "0" (zero, o caractere Unicode U + 0030) no elemento font.

É compatível com as versões atuais dos principais navegadores ( caniuse ).

Exemplo

pre {
    width: 80ch; /* classic terminal width for code sections */
}
transistor09
fonte
3
Há também o espaço da figura , que é precisamente "igual à largura de um dígito", conforme descrito no artigo de espaço (pontuação) da Wikipedia . Seu valor Unicode é U + 2007 e pode ser inserido em HTML usando &#x2007;ou &#8199;. É funcionalmente equivalente à chunidade de CSS, mas embora não seja amplamente suportado, pode ser usado como uma solução alternativa em HTML (hack feio, mas deve funcionar).
waldyrious
2
Na verdade, de acordo com este problema do cromo , o Chrome o suporta desde a v27, então agora as últimas versões de todos os principais navegadores (IE, Chrome e Firefox) suportam a unidade ch :)
waldyrious
2
Deve-se notar que o tamanho do caractere é o tamanho do glifo '0' na fonte do elemento. Se você espera caracteres maiores como 'm' ou 'w', convém expandir de acordo ou expandi-lo conforme necessário (por exemplo, stackoverflow.com/questions/7168727/… )
user420667
1
Sim, sem problemas com fontes monoespaçadas.
Willege
2
O IE11 oferece suporte incorreto. stackoverflow.com/questions/17825638/…
aleha