Spécifiez la largeur en * caractères *

108

Lorsque vous utilisez une police à largeur fixe , je voudrais spécifier la largeur d'un élément HTML en caractères .

L'unité "em" est censée être la largeur du caractère M, donc je devrais pouvoir l'utiliser pour spécifier une largeur. Ceci est un exemple:

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

Le résultat n'est pas ce que je voulais car la ligne du navigateur saute après la colonne 15, pas 10:

1 3 5 7 9 1 3 5
7 9 1

(Résultat dans Firefox et Chromium, tous deux dans Ubuntu.)

L'article de Wikipedia dit qu'un "em" n'a pas toujours la largeur d'un M, il semble donc que l'unité "em" ne puisse pas être fiable pour cela.

Martin Vilcans
la source
Je crois que "en" est aussi une largeur légale; c'est la largeur d'un chiffre en typographie. Cela pourrait mieux fonctionner pour vous.
Pete Wilson
6
La propriété 'em' utilise la taille de la police, ou la hauteur , de la police, et non la largeur des lettres. @Pete: Ce n'est pas le cas, voir Module Valeurs et Unités CSS Niveau 3 .
animuson
Sauf si vous utilisez une police à largeur fixe, différents caractères ont des largeurs différentes. Par conséquent, il est fonctionnellement impossible de définir une largeur en termes de nombre de caractères affichés.
Emily
"Cette question nécessite encore 4 vote (s) d'autres utilisateurs pour se fermer" - Hé, c'est ma question! Laissez-moi le fermer!
Martin Vilcans

Réponses:

23

1em est la hauteur d'un M, plutôt que la largeur. Il en va de même pour ex, qui est la hauteur d'un x. Plus généralement, ce sont les hauteurs des lettres majuscules et minuscules.

La largeur est une question totalement différente ...

Changez votre exemple ci-dessus en

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

et vous remarquerez que la largeur et la hauteur de la travée sont différentes. Pour une taille de police de 20 px sur Chrome, la portée est de 12 x 22 px, où 20 px est la hauteur de la police et 2 px pour la hauteur de ligne.

Maintenant que em et ex ne sont d'aucune utilité ici, une stratégie possible pour une solution uniquement CSS serait de

  1. Créez un élément contenant uniquement un & nbsp;
  2. Laissez-le se dimensionner automatiquement
  3. Placez votre div à l'intérieur et
  4. Faites-le 10 fois plus grand que l'élément environnant.

Je n'ai cependant pas réussi à coder cela. Je doute aussi que ce soit vraiment possible.

La même logique pourrait cependant être implémentée en Javascript. J'utilise jQuery omniprésent ici:

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

Le +1 in (w * 10 + 1) sert à gérer les problèmes d'arrondi.

Gerd Riesselmann
la source
1
J'espérais une solution CSS pure, ce qui n'est possible que si vous connaissez le rapport entre la hauteur et la largeur d'un caractère (voir stackoverflow.com/questions/1255281/… ). J'accepte cela comme la réponse car cela semble être une solution robuste.
Martin Vilcans
1em n'est pas la hauteur d'un M selon les réponses ici graphicdesign.stackexchange.com/questions/4035/… Le "|" le caractère doit être plus proche de 1em.
Sogartar
1
Sogartar, pour clarification: dans la typographie proprement dite, 1 em est en effet la largeur (ainsi que la hauteur em) d'un caractère de largeur fixe. Cependant, c'est la «typographie proprement dite» et nous avons de nombreuses personnes qui créent des fichiers de polices qui ne respectent pas les règles typographiques - particulièrement vrai dans le cas des polices Web. Le point de mon commentaire ici n'est pas (simplement) de façon effrontée. Mon point est: test, test, test. (Et puis testez-en plus.)
Parapluie
219

ch unité

L'unité que vous recherchez est ch. Selon la documentation MDN :

ch: Représente la largeur, ou plus précisément la mesure d'avance, du glyphe "0" (zéro, le caractère Unicode U + 0030) dans l'élément font.

Il est pris en charge dans les versions actuelles des principaux navigateurs ( caniuse ).

Exemple

pre {
    width: 80ch; /* classic terminal width for code sections */
}
transistor09
la source
3
Il y a aussi l' espace des figures , qui est précisément "égal à la largeur d'un chiffre" comme décrit dans l'article de Wikipedia sur l' espace (ponctuation) . Sa valeur Unicode est U + 2007 et elle peut être saisie en HTML en utilisant &#x2007;ou &#8199;. C'est fonctionnellement équivalent à l' chunité de CSS, mais bien que cela ne soit pas largement pris en charge, il peut être utilisé comme une solution de contournement en HTML (vilain hack, mais devrait fonctionner).
waldyrious
2
En fait, selon ce problème de chrome , Chrome le prend en charge depuis la v27, donc pour le moment, les dernières versions de tous les principaux navigateurs (IE, Chrome et Firefox) prennent en charge l'unité ch :)
waldyrious
2
Il faut noter que la taille des caractères est la taille du glyphe «0» dans la police de l'élément. Si vous attendez des caractères plus grands comme «m» ou «w», vous voudrez peut-être envisager de les agrandir en conséquence ou de les agrandir si nécessaire (par exemple, stackoverflow.com/questions/7168727/… )
user420667
1
Oui, aucun problème avec les polices à espacement fixe.
Willege
2
IE11 le prend mal. stackoverflow.com/questions/17825638/…
aleha