web-dev-qa-db-fra.com

CSS pur pour rendre la taille de police sensible à la quantité de caractères dynamique

Je sais que cela pourrait être résolu assez facilement avec Javascript, mais je ne m'intéresse qu'à une solution CSS pure.

Je veux un moyen de redimensionner dynamiquement le texte pour qu'il tienne toujours dans un div fixe. Voici l'exemple de balisage:

<div style="width: 200px; height: 1em; overflow: hidden;">
  <p>Some sample dynamic amount of text here</p>
</div>

Je pensais que cela pourrait peut-être être possible en spécifiant la largeur du conteneur dans ems et en faisant en sorte que la taille de la police de caractères hérite de cette valeur?

264
DMTintner

Je viens de découvrir que cela est possible en utilisant des unités VW. Ce sont les unités associées à la définition de la largeur de la fenêtre. Il existe certains inconvénients, tels que le manque de prise en charge des navigateurs existants, mais il s'agit certainement d'une chose à envisager sérieusement. De plus, vous pouvez toujours fournir des solutions de remplacement pour les navigateurs plus anciens, comme ceci:

p {
    font-size: 30px;
    font-size: 3.5vw;
}

http://css-tricks.com/viewport-sized-typography/ et https://medium.com/design-ux/66bddb327bb1

467
DMTintner

CSS3 supporte les nouvelles dimensions relatives au port de visualisation. Mais cela ne fonctionne pas dans Android <4.4

  1. 3.2vw = 3.2% de la largeur de la fenêtre
  2. 3.2vh = 3.2% de la hauteur de la fenêtre
  3. 3.2vmin = plus petit de 3.2vw ou 3.2vh
  4. 3.2vmax = Plus grand de 3.2vw ou 3.2vh

    body
    {
        font-size: 3.2vw;
    }
    

voir css-tricks.com/.... et aussi regarder caniuse.com/....

ou

Utilisez la requête multimédia . La manière la plus simple consiste à utiliser des dimensions dans% ou em. Il suffit de changer la taille de la police de base, tout va changer.

@media (max-width: @screen-xs) {
    body{font-size: 10px;}
}

@media (max-width: @screen-sm) {
    body{font-size: 14px;}
}


h5{
    font-size: 1.4em;
}

Utilisez les dimensions dans % ou em . Il suffit de changer la taille de la police de base, tout va changer. Dans la version précédente, vous pouviez simplement changer la police du corps et non pas h1 à chaque fois, ou laisser la taille de la police de base à la valeur par défaut du

voir kyleschaeffer.com/.... pour plus d'informations sur em, px et%

101
aWebDeveloper

Vous pourriez être intéressé par l'approche calc:

font-size: calc(4vw + 4vh + 2vmin);

terminé. Tweak valeurs jusqu'à correspond à votre goût.

Source: https://codepen.io/CrocoDillon/pen/fBJx

21
Rexford

Le seul moyen serait probablement de définir différentes largeurs pour différentes tailles d'écran, mais cette approche est assez floue et vous devez utiliser une solution js.

h1 {
    font-size: 20px;
}

@media all and (max-device-width: 720px){
    h1 {
        font-size: 18px;
    }
}

@media all and (max-device-width: 640px){
    h1 {
        font-size: 16px;
    }
}

@media all and (max-device-width: 320px){
    h1 {
        font-size: 12px;
    }
}
11
Sven Rojek

Je sais que je ressasse une question morte depuis longtemps, mais j'avais la même question et je voulais ajouter quelque chose. S'il vous plaît, ne m'interdit pas cela, je pensais que c'était assez important pour justifier cette réponse, je le supprimerai si nécessaire. @ Joseph Silber a tort, coder toutes les possibilités est en fait un moyen viable de le faire. La raison en est qu'il n'y a pas vraiment de possibilités infinies. Techniquement, il y en a une, mais 99% de vos visiteurs utiliseront une résolution standard. Cela est d'autant plus vrai pour les appareils mobiles (principale raison de la conception Web réactive), car la plupart des systèmes d'exploitation mobiles exécutent des applications en plein écran sans redimensionnement de la fenêtre.

En outre, la hauteur est sans importance en raison de la barre de défilement (à un certain point, je quitterais immédiatement une page Web de plus de 4 ou 5 pieds de long, mais cela est vrai dans la plupart des cas), vous n'avez donc qu'à vous soucier de la largeur. Et vraiment, les seules largeurs que vous devez coder sont les suivantes: 240, 320, 480 (pour les iThings plus anciennes), 640, 800, 1024, 1280, 1440, 1600, 1920, 2048, 2560. Ne vous souciez même pas de 4k, vos images seront trop lourdes et la taille 2560 étendue à 100% de la largeur sera parfaite sur un moniteur 4k (je l’ai déjà testé). Aussi, ne vous embêtez pas avec 720 (720x480) comme l'a suggéré l'affiche précédente. C'est une résolution utilisée presque exclusivement par les appareils photo numériques, et même alors, elle est très rare.

Si quelqu'un utilise une résolution exotique, presque tous les moteurs de rendu réalisés au cours des 15 dernières années seront arrondis au minimum. Par conséquent, si la largeur de l'écran est égale à, par exemple. 1100, ça va charger la règle 1024 CSS, votre site ne devrait pas casser. Cela rend inutile la comptabilisation de résolutions exotiques en essayant de créer une règle sensible, et l'idée qu'il soit nécessaire de coder pour chaque configuration possible pixel par pixel est ridicule, à moins que quelqu'un n'utilise un navigateur Web tellement obsolète que votre site ne se chargerait probablement pas à tout de même.

11
user281058

Pour référence, voici une solution JS qui redimensionne une police en fonction de la longueur du texte dans un conteneur.

Codepen avec du code légèrement modifié, mais même idée que ci-dessous:

function scaleFontSize(element) {
    var container = document.getElementById(element);

    // We only want to scale down long text, so first we reset
    // font-size to 100%, in case this function is called multiple times.
    container.style.fontSize = "100%";

    // Now actually check if the text is wider than
    // its container, if so then reduce font-size
    if (container.scrollWidth > container.clientWidth) {
        container.style.fontSize = "70%";
    }
}

Pour moi, j'appelle cette fonction lorsqu'un utilisateur effectue une sélection dans une liste déroulante, puis un div de mon menu est rempli (c'est ici que le texte dynamique apparaît).

    scaleFontSize("my_container_div");

En outre, j’utilise également des ellipses CSS ("...") pour tronquer un texte encore plus long , comme suit:

#my_container_div {
    width: 200px; /* width required for text-overflow to work */
    white-space: nowrap;
    overflow: hidden;
    text-overflow: Ellipsis;
}

Donc, finalement:

  • Texte court: p. Ex. "POMMES"

    Entièrement rendu, belles grandes lettres.

  • Texte long: p. Ex. "POMMES & ORANGES"

    Réduit de 70%, via la fonction de mise à l'échelle JS ci-dessus.

  • Texte très long: p. Ex. "POMMES & ORANGES & BANAN ..."

    Obtient une réduction de 70% ET est tronqué avec des ellipses "...", via la fonction de mise à l'échelle JS ci-dessus avec la règle CSS.

Vous pouvez également explorer la possibilité d'utiliser l'espacement des lettres CSS pour réduire le texte tout en conservant la même taille de police.

6
MarsAndBack

Comme beaucoup l'ont mentionné dans les commentaires au message de @ DMTinter, l'OP s'est interrogé sur le nombre ("montant") de caractères changés. Il posait également des questions sur les CSS, mais comme @Alexander l'a indiqué, "ce n'est pas possible uniquement avec CSS". Autant que je sache, cela semble être vrai à l'heure actuelle, alors il semble également logique que les gens veuillent connaître la prochaine meilleure chose.

Je ne suis pas particulièrement fier de cela, mais ça marche. Cela ressemble à une quantité excessive de code pour l'accomplir. C'est le noyau:

function fitText(el){
  var text = el.text();
  var fsize = parseInt(el.css('font-size'));
  var measured = measureText(text, fsize);

  if (measured.width > el.width()){
    console.log('reducing');
    while(true){
      fsize = parseInt(el.css('font-size'));
      var m = measureText(text, fsize );
      if(m.width > el.width()){
        el.css('font-size', --fsize + 'px');
      }
      else{
        break;
      }
    }
  }
  else if (measured.width < el.width()){
    console.log('increasing');
    while(true){
      fsize = parseInt(el.css('font-size'));
      var m = measureText(text, fsize);
      if(m.width < el.width()-4){ // not sure why -4 is needed (often)
        el.css('font-size', ++fsize + 'px');
      }
      else{
        break;
      }
    }
  }
}

Voici un JS Bin: http://jsbin.com/pidavon/edit?html,css,js,console,output
Veuillez suggérer d’éventuelles améliorations (je ne suis pas vraiment intéressé par l’utilisation de canvas pour mesurer le texte ... cela semble être une surcharge (?)).

Merci à @Pete pour la fonction measureText: https://stackoverflow.com/a/4032497/442665

2
jbobbins

Essayez RFS (pour la taille de police sensible) Bibliothèque de MartijnCuppens qui sera peut-être implémentée dans Bootstrap

2
Fred K

Cette solution pourrait également aider:

$(document).ready(function () {
    $(window).resize(function() {
        if ($(window).width() < 600) {
            $('body').css('font-size', '2.8vw' );
        } else if ($(window).width() >= 600 && $(window).width() < 750) {
            $('body').css('font-size', '2.4vw');
        } 
         // and so on... (according to our needs)
        } else if ($(window).width() >= 1200) {
            $('body').css('font-size', '1.2vw');
        }
    }); 
  });

Cela a bien fonctionné pour moi!

2
Gaurav Krishn
calc(42px + (60 - 42) * (100vw - 768px) / (1440 - 768));

utilisez cette équation.

Pour les valeurs supérieures ou inférieures à 1440 et 768, vous pouvez lui attribuer une valeur statique ou appliquer la même approche.

L'inconvénient de vw solution est que vous ne pouvez pas définir de rapport d'échelle, par exemple, une résolution de 5vw à la résolution d'écran 1440 peut être une taille de police de 60px, soit la taille de police de votre idée, mais lorsque vous réduisez la largeur de la fenêtre à 768, elle risque de finir. être 12px, pas le minimum que vous voulez. Avec cette approche, vous pouvez définir votre limite supérieure et inférieure, et la police sera redimensionnée elle-même entre les deux.

2
Shuwei