web-dev-qa-db-fra.com

Mise à l'échelle de la police en fonction de la largeur du conteneur

J'ai de la difficulté à comprendre comment redimensionner les polices.

J'ai actuellement ce site avec un corps font-size de 100%. 100% de quoi si? Cela semble calculer à 16px. 

J'avais l'impression que 100% se réfèreraient d'une manière ou d'une autre à la taille de la fenêtre du navigateur, mais apparemment pas, car la taille de la fenêtre est toujours de 16 pixels si la fenêtre est redimensionnée à la largeur d'un mobile ou à un bureau large.

Comment puis-je faire le texte sur la balance de mon site par rapport à son conteneur? J'ai essayé d'utiliser em mais cela ne s'adapte pas non plus.

Mon raisonnement est que des choses comme mon menu s’écrasent lorsque vous redimensionnez, je dois donc réduire le px font-size de .menuItem parmi d’autres éléments par rapport à la largeur du conteneur. (E.g dans le menu sur un grand bureau, 22px fonctionne parfaitement. Descendez à la largeur de la tablette et 16px est plus approprié.)

Je suis conscient que je peux ajouter des points d'arrêt, mais je souhaite vraiment que le texte s'adapte à des points d'arrêt supplémentaires, sinon je vais me retrouver avec des centaines de points d'arrêt pour chaque diminution de largeur de 100 pixels pour contrôler le texte.

917
Francesca

EDIT: Si le conteneur n'est pas le corps Les astuces CSS couvrent toutes vos options ici: https://css-tricks.com/fitting-text-to-a-container/

Si le conteneur est le corps, ce que vous recherchez est Viewport-length lengths :

Les longueurs viewport-pourcentage sont relatives à la taille du bloc contenant initial . Lorsque la hauteur ou la largeur du bloc contenant initial est modifiée, ils sont mis à l'échelle en conséquence. Cependant, lorsque la valeur de dépassement de capacité sur l'élément racine est auto, toutes les barres de défilement sont supposées n'exister pas. 

Les valeurs sont: 

  • vw (% de la largeur de la fenêtre)
  • vh (% de la hauteur de la fenêtre)
  • vi (1% de la taille de la fenêtre d'affichage dans la direction de l'axe en ligne de l'élément racine)
  • vb (1% de la taille de la fenêtre d'affichage dans la direction de l'axe de bloc de l'élément racine)
  • vmin (le plus petit de vw ou vh)
  • vmax (le plus grand ou vw ou vh)

1 v * est égal à 1% du bloc contenant initial.

l'utiliser ressemble à ceci:

p {
    font-size: 4vw;
}

Comme vous pouvez le constater, lorsque la largeur de la fenêtre d’affichage augmente, la taille de la police augmente également, sans que vous ayez à utiliser des requêtes multimédia.

Ces valeurs constituent une unité de dimensionnement, tout comme px ou em, de sorte qu'elles peuvent également être utilisées pour dimensionner d'autres éléments, tels que la largeur, la marge ou le remplissage.

La prise en charge du navigateur est très bonne, mais vous aurez probablement besoin d’une solution de secours, telle que:

p {
    font-size: 16px; 
    font-size: 4vw;
}

Consultez les statistiques de support: http://caniuse.com/#feat=viewport-units

Découvrez également CSS-Tricks pour une apparence plus large: http://css-tricks.com/viewport-sized-typography/

Voici un article de Nice sur la définition des tailles min/max et un peu plus de contrôle sur les tailles: http://madebymike.com.au/writing/precise-control-responsive-typography/

Et voici un article sur la définition de votre taille à l'aide de calc () afin que le texte remplisse la fenêtre d'affichage: http://codepen.io/CrocoDillon/pen/fBJxu

Consultez également cet article, qui utilise une technique appelée «fusion du fondant» pour ajuster également la hauteur de ligne. _ { https://css-tricks.com/molten-leading-css/

1278
jbenjohnson

Mais que se passe-t-il si le conteneur n'est pas la fenêtre (le corps)?

Alex pose cette question en commentaire sous la réponse acceptée. 

Ce fait ne signifie pas que vw ne peut pas être utilisé dans une certaine mesure pour dimensionner ce conteneur. Maintenant, pour voir toute variation, il faut supposer que le conteneur est en quelque sorte flexible en taille. Que ce soit par un pourcentage direct width ou par une marge de 100% moins. Le point devient "sans objet" si le conteneur est toujours défini sur, par exemple, 200px wide - définissez simplement un font-size qui fonctionne pour cette largeur.

Exemple 1

Cependant, avec un conteneur de largeur flexible, il faut bien se rendre compte que le conteneur est en quelque sorte toujours en dehors de la fenêtre d'affichage. En tant que tel, il suffit donc d'ajuster un paramètre vw basé sur cette différence de taille en pourcentage à la fenêtre d'affichage, ce qui implique de prendre en compte le dimensionnement des enveloppes parent. Prenons cet exemple :

div {
    width: 50%;
    border: 1px solid black;
    margin: 20px;
    font-size: 16px;
    /* 100 = viewport width, as 1vw = 1/100th of that
       So if the container is 50% of viewport (as here)
       then factor that into how you want it to size.
       Let's say you like 5vw if it were the whole width,
       then for this container, size it at 2.5vw (5 * .5 [i.e. 50%])
    */
    font-size: 2.5vw; 
}

En supposant qu'ici la div soit un enfant de la body, il s'agit de 50% de cette 100% largeur, qui correspond à la taille de la fenêtre d'affichage dans ce cas de base. En gros, vous voulez définir une vw qui vous ira bien. Comme vous pouvez le voir dans mon commentaire dans le fichier CSS ci-dessus, vous pouvez "réfléchir" mathématiquement à la taille de la fenêtre d'affichage, mais vous ne le faites pas {nécessité}. Le texte va "fléchir" avec le conteneur, car celui-ci fléchit avec le redimensionnement de la fenêtre. UPDATE: voici un exemple de deux conteneurs de tailles différentes .

Exemple 2

Vous pouvez contribuer au dimensionnement de la fenêtre en forçant le calcul à partir de cela. Considérez cet exemple :

html {width: 100%;} /* force html to be viewport width */
body {width: 150%; } /* overflow the body */

div {
    width: 50%;
    border: 1px solid black;
    margin: 20px;
    font-size: 16px;
    /* 100 = viewport width, as 1vw = 1/100th of that
       Here, the body is 150% of viewport, but the container is 50% 
       of viewport, so both parents factor  into how you want it to size.
       Let's say you like 5vw if it were the whole width,
       then for this container, size it at 3.75vw 
       (5 * 1.5 [i.e. 150%]) * .5 [i.e. 50%]
    */
    font-size: 3.75vw; 
}

Le dimensionnement est toujours basé hors de la fenêtre d'affichage, mais il est essentiellement configuré en fonction de la taille du conteneur lui-même.

Le dimensionnement du conteneur doit-il changer dynamiquement ...

Si le dimensionnement de l'élément conteneur finissait par modifier dynamiquement sa relation de pourcentage via les points de rupture @media ou via javascript, il serait alors nécessaire de recalculer la base "cible" pour maintenir la même "relation" pour la taille du texte.

Prenons l'exemple n ° 1 ci-dessus. Si la div était passée à 25% width par @media ou javascript, le font-size devrait en même temps s'ajuster dans la requête multimédia ou par javascript au nouveau calcul de 5vw * .25 = 1.25. Cela donnerait à la taille du texte la même taille que si la "largeur" ​​du conteneur 50% d'origine avait été réduite de moitié par rapport au dimensionnement de la fenêtre, mais elle a maintenant été réduite en raison d'une modification de son propre pourcentage de calcul. 

Un défi

Avec la fonction CSS3 calc() en cours d’utilisation, il deviendrait difficile d’ajuster de manière dynamique, car cette fonction ne fonctionne pas pour les besoins de font-size pour le moment. Vous ne pouvez donc pas effectuer d’ajustement CSS3 pur si votre largeur change sur calc(). Bien sûr, un ajustement mineur de la largeur des marges peut ne pas suffire à justifier un changement de font-size, de sorte que cela n’a peut-être pas d'importance.

277
ScottS

Ce que je fais dans l’un de mes projets est un "mélange" entre vw et vh pour adapter la taille de la police à mes besoins, par exemple:

font-size: calc(3vw + 3vh);

Je sais que cela ne répond pas à la question de l'op, mais peut-être que cela peut être une solution pour quelqu'un d'autre.

29
lsblsb

Solution avec SVG:

<div style="width: 60px;">  
  <svg width="100%" height="100%" viewBox="0 -200 1000 300"
     xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
    <text font-size="300" fill="black">Text</text>
  </svg>
</div>

https://jsfiddle.net/qc8ht5eb/

27
Danto

Il y a une grande philosophie pour cette question. La chose la plus facile à faire serait de donner une taille de police donnée à body (je recommande 10), puis tous les autres éléments auront leur police en em ou rem . pour comprendre ces unités . Em est toujours relatif à son parent

body{font-size:10px;}
.menu{font-size:2em;} /* that means 2*10px = 20px */
.menu li{font-size:1.5em;} /* that means 1.5*20px = 30px */

Rem est toujours relatif au corps

body{font-size:10px;}
.menu{font-size:2rem;} /* that means 2*10px = 20px */
.menu li{font-size:1.5rem;} /* that means 1.5*10px = 15px */

Et puis, vous pourriez créer un script qui modifierait la taille de la police par rapport à la largeur de votre conteneur . Mais ce n’est pas ce que je recommanderais. Parce que dans un conteneur d'une largeur de 900px, par exemple, vous auriez un élément p avec une taille de police de 12px, par exemple. Et sur votre idée, cela deviendrait un conteneur de 300 pixels de large avec une taille de police de 4 pixels. Il doit y avoir une limite inférieure . Une autre solution serait avec des requêtes de média, de sorte que vous pouvez définir la police pour différentes largeurs.

Mais la solution que je recommanderais consiste à utiliser une bibliothèque javascript qui vous aidera à cela. Et fittext.js que j'ai trouvé jusqu'ici.

21
Dan Ovidiu Boncut

Mis à jour parce que j'ai eu un vote négatif.

Voici la fonction:

document.body.setScaledFont = function(f) {
  var s = this.offsetWidth, fs = s * f;
  this.style.fontSize = fs + '%';
  return this
};

Convertissez ensuite toutes les tailles de police de vos éléments enfants en documents en em ou en%.

Ajoutez ensuite quelque chose comme ceci à votre code pour définir la taille de la police de base.

document.body.setScaledFont(0.35);
window.onresize = function() {
    document.body.setScaledFont(0.35);
}

http://jsfiddle.net/0tpvccjt/

20
tnt-rox

Solution Pure-CSS avec calc(), unités CSS et mathématiques

Ce n'est précisément pas ce que demande OP, mais peut faire de quelqu'un le jour. Cette réponse n’est pas facile à nourrir à la cuillère et nécessite quelques recherches de la part du développeur.

Je suis finalement arrivé à obtenir une solution purement CSS pour cela en utilisant calc() avec différentes unités. Vous aurez besoin d'une compréhension mathématique de base des formules pour élaborer votre expression pour calc().

Lorsque j'ai résolu le problème, je devais obtenir un en-tête réactif de largeur entière, avec quelques repères de remplissage dans le DOM. Je vais utiliser mes valeurs ici, les remplacer par les vôtres.

Aux mathématiques

Tu auras besoin de:

  • joliment ajusté dans certaines fenêtres, j’utilisais 320px, donc j’ai 24px de haut et 224px de large, donc le ratio est de 9,333 ... ou 28/3
  • la largeur du conteneur, j'avais padding: 3em et toute la largeur, donc c'est arrivé à 100wv - 2 * 3em

X étant la largeur du conteneur, remplacez-le par votre propre expression ou ajustez la valeur pour obtenir le texte de la page entière. R est le rapport que vous aurez. Vous pouvez l'obtenir en ajustant les valeurs dans une fenêtre, en inspectant la largeur et la hauteur des éléments et en les remplaçant par vos propres valeurs. En outre, il s'agit de width / heigth;) 

x = 100vw - 2 * 3em = 100vw - 6em
r = 224px/24px = 9.333... = 28 / 3

y = x / r
  = (100vw - 6em) / (28 / 3)
  = (100vw - 6em) * 3 / 28
  = (300vw - 18em) / 28
  = (75vw - 4.5rem) / 7

Et bang! Ça a marché! J'ai écrit 

font-size: calc((75vw - 4.5rem) / 7)

à mon en-tête et il s'est bien ajusté dans chaque fenêtre.

Mais comment ça marche?

Nous avons besoin de constantes ici. 100vw représente la largeur totale de la fenêtre de visualisation et mon objectif était d’établir un en-tête pleine largeur avec un remplissage.

Le rapport. Obtenir une largeur et une hauteur dans une fenêtre m'a donné un ratio avec lequel jouer, et avec un ratio, je sais ce que la hauteur devrait être dans la largeur d'une autre fenêtre. Les calculer à la main prendrait beaucoup de temps et prendrait au moins beaucoup de bandes passantes, alors ce n'est pas une bonne réponse.

Conclusion

Je me demande pourquoi personne n'a compris cela et certaines personnes disent même que ce serait impossible de bricoler avec CSS. Je n'aime pas utiliser Javascript dans les éléments de réglage, je n'accepte donc pas les réponses JS ou même jQuery sans chercher plus. Dans l’ensemble, c’est bien que cela ait été déterminé et qu’il s’agisse d’une étape vers l’implémentation de CSS pur dans la conception de sites Web. 

Je m'excuse de toute convention inhabituelle dans mon texte. Je ne suis pas un locuteur natif en anglais et je suis tout à fait nouveau en écrivant des réponses SO.

Edit : il convient également de noter que nous avons des barres de défilement maléfiques dans certains navigateurs. Par exemple, lors de l’utilisation de Firefox, j’ai remarqué que 100vw représente toute la largeur de la fenêtre, s’étendant sous la barre de défilement (où le contenu ne peut pas s’étendre!), De sorte que le texte en pleine largeur doit être soigneusement encadré et de préférence testé avec de nombreux navigateurs et périphériques.

18
hegez

Il existe un moyen de faire cela SANS javascript!

Vous pouvez utiliser un svg en ligne. Vous pouvez utiliser css sur un svg s'il est en ligne. N'oubliez pas que l'utilisation de cette méthode signifie que votre svg répondra à la taille de son conteneur.

Essayez d'utiliser la solution suivante ...

HTML

<div>
  <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 360.96 358.98" >
      <text>SAVE $500</text>

  </svg>

</div>

CSS

div {
  width: 50%; /* set your container width */
  height: 50%; /* Set your container height */

}

svg {
  width: 100%;
  height: auto;

}

text {
  transform: translate(40px, 202px);
  font-size: 62px;
  fill: #000;

}

exemple: https://jsfiddle.net/k8L4xLLa/32/

Tu veux quelque chose de plus flashy?

Les SVG vous permettent également de faire des choses sympas avec des formes et des ordures. Découvrez ce cas d'utilisation génial pour un texte évolutif ...

https://jsfiddle.net/k8L4xLLa/14/

14
Aaron Loften

Cela peut ne pas être très pratique, mais si vous voulez que la police soit une fonction directe du parent, sans aucun JS qui écoute/boucle (intervalle) pour lire la taille du div/page, il existe un moyen de le faire. Iframes. Tout ce qui se trouve dans l'iframe considérera la taille de l'iframe comme la taille de la fenêtre d'affichage. L'astuce consiste donc simplement à créer un iframe dont la largeur est la largeur maximale que vous souhaitez utiliser pour votre texte et dont la hauteur est égale à la hauteur maximale * du rapport de format du texte en question. 

Mettant de côté la limitation selon laquelle les unités de la fenêtre d'affichage ne peuvent pas non plus s'ajouter aux unités parent du texte (comme dans le fait que% size se comporte comme tout le monde), les unités de la fenêtre d'affichage fournissent un outil très puissant: pouvoir obtenir la dimension min/max. . Vous ne pouvez le faire nulle part ailleurs - vous ne pouvez pas dire… faites de la hauteur de cette div la largeur du parent * quelque chose. 

Cela dit, l’astuce consiste à utiliser vmin et à définir la taille de l’iframe de sorte que [fraction] * hauteur totale soit une bonne taille de police lorsque la hauteur correspond à la dimension limite et [fraction] * largeur totale lorsque la largeur correspond à la largeur. dimension limite. C'est pourquoi la hauteur doit être un produit de la largeur et du rapport de forme. 

pour mon exemple particulier, vous avez

.main iframe{
  position: absolute;
  top: 50%;
  left: 50%;
  width: 100%;
  height: calc(3.5 * 100%);
  background: rgba(0,0,0,0);
  border-style: none;
  transform: translate3d(-50%,-50%,0);
}

Le petit ennui avec cette méthode est que vous devez définir manuellement le CSS de l'iframe. Si vous attachez l'intégralité du fichier CSS, cela prendrait beaucoup de bande passante pour de nombreuses zones de texte. Donc, ce que je fais est d’attacher la règle que je veux directement à partir de mon CSS.

var rule = document.styleSheets[1].rules[4];
var iDoc = document.querySelector('iframe').contentDocument;
iDoc.styleSheets[0].insertRule(rule.cssText); 

Vous pouvez écrire une petite fonction qui obtient la règle CSS/toutes les règles CSS pouvant affecter la zone de texte.

Je ne peux pas penser à une autre façon de le faire sans avoir un peu de JS en écoute/écoute. La vraie solution serait que les navigateurs fournissent un moyen de redimensionner le texte en fonction du conteneur parent ET de fournir également la même fonctionnalité de type vmin/vmax.

JS fiddle: https://jsfiddle.net/0jr7rrgm/3/ (Cliquez une fois pour verrouiller le carré rouge sur la souris, cliquez à nouveau pour relâcher)

La plupart des JS dans le violon est juste ma fonction personnalisée cliquer-glisser

13
Roman Rekhler

Utiliser vw, em & co. ça marche à coup sûr, mais imo a toujours besoin d'un contact humain pour le peaufiner.

Voici un script que je viens d'écrire sur la base de @ tnt-rox ' answer qui tente d'automatiser le contact de cet humain:

$('#controller').click(function(){
	$('h2').each(function(){
    var
      $el = $(this),
      max = $el.get(0),
      el = null
    ;
    max =
      max
    ? max.offsetWidth
    : 320
    ;
    $el.css({
      'font-size': '1em',
      'display': 'inline',
    });
    el = $el.get(0);

    el.get_float = function(){
      var
        fs = 0
      ;
      if (this.style && this.style.fontSize) {
        fs = parseFloat(this.style.fontSize.replace( /([\d\.]+)em/g, '$1' ));
      }
      return fs;
    };

    el.bigger = function(){
      this.style.fontSize = (this.get_float() +0.1) +'em';
    };


    while ( el.offsetWidth < max ) {
      el.bigger();
    }
    // finishing touch.
    $el.css({
      'font-size': ((el.get_float() -0.1) +'em'),
      'line-height': 'normal',
      'display': '',
    });
	});  // end of ( each )
});	// end of ( font scaling test )
div {
  width: 50%;
  background-color: tomato;
  font-family: 'Arial';
}

h2 {
  white-space: nowrap;
}

h2:nth-child(2) {
  font-style: italic;  
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<input type="button" id="controller" value="Apply" />
<div>
  <h2>Lorem ipsum dolor</h2>
  <h2>Test String</h2>
  <h2>Sweet Concatenation</h2>
  <h2>Font Scaling</h2>
</div>

En gros, il réduit la taille de la police à 1em, puis commence à incrémenter de 0,1 jusqu'à atteindre la largeur maximale.

jsFiddle

7
WoodrowShigeru

cherchez-vous quelque chose comme ça? =>
http://jsfiddle.net/sijav/dGsC9/4/
http://fiddle.jshell.net/sijav/dGsC9/4/show/
J'ai utilisé flowtype et ça marche très bien (mais c'est du js et pas une solution css pure)

$('body').flowtype({
 minFont : 10,
 maxFont : 40,
 minimum : 500,
 maximum : 1200,
 fontRatio : 70
});
6
Sijav

Ce composant Web modifie la taille de la police afin que la largeur du texte interne corresponde à la largeur du conteneur. Vérifiez la démo .

Vous pouvez l'utiliser comme ceci: 

<full-width-text>Lorem Ipsum</full-width-text>
6
pomber

100% correspond à la taille de la police de base. Si vous ne l'avez pas définie, il s'agirait de la valeur par défaut de l'agent utilisateur du navigateur. 

Pour obtenir l’effet recherché, j’utiliserais un morceau de javascript pour ajuster la taille de la police de base par rapport aux dimensions de la fenêtre.

6
scoota269

Dans votre CSS, essayez d’ajouter ceci au bas de la page en modifiant la largeur de 320 pixels chaque fois que votre conception commence à casser:

    @media only screen and (max-width: 320px) {

       body { font-size: 1em; }

    }

Puis donnez la taille de la police dans "px" ou "em" comme vous le souhaitez.

6
Chunky

Avez-vous essayé http://simplefocus.com/flowtype/ ?

C'est ce que j'utilise pour mes sites et a parfaitement fonctionné. J'espère que ça aide.

6
Pixel Reaper

Ma propre solution, basée sur jQuery, fonctionne en augmentant progressivement la taille de la police jusqu'à ce que le conteneur obtienne une grande augmentation de hauteur (ce qui signifie qu'il a un saut de ligne) . Vous n'avez pas besoin de savoir quoi que ce soit sur la police utilisée, tout est pris en charge par le navigateur.

Vous pouvez jouer avec/ http://jsfiddle.net/tubededentifrice/u5y15d0L/2/

La magie se passe ici:

var setMaxTextSize=function(jElement) {
    //Get and set the font size into data for reuse upon resize
    var fontSize=parseInt(jElement.data(quickFitFontSizeData)) || parseInt(jElement.css("font-size"));
    jElement.data(quickFitFontSizeData,fontSize);

    //Gradually increase font size until the element gets a big increase in height (ie line break)
    var i=0;
    var previousHeight;
    do
    {
        previousHeight=jElement.height();
        jElement.css("font-size",""+(++fontSize)+"px");
    }
    while(i++<300 && jElement.height()-previousHeight<fontSize/2)

    //Finally, go back before the increase in height and set the element as resized by adding quickFitSetClass
    fontSize-=1;
    jElement.addClass(quickFitSetClass).css("font-size",""+fontSize+"px");

    return fontSize;
};
6
Vincent

J'ai préparé une fonction d'échelle simple en utilisant la transformation CSS au lieu de la taille de police. Vous pouvez l'utiliser à l'intérieur de n'importe quel conteneur, vous n'avez pas à définir de requêtes sur les médias, etc. :)

Article de blog: https://blog.polarbits.co/2017/03/07/full-width-css-js-scalable-header/

Le code:

function scaleHeader() {
  var scalable = document.querySelectorAll('.scale--js');
  var margin = 10;
  for (var i = 0; i < scalable.length; i++) {
    var scalableContainer = scalable[i].parentNode;
    scalable[i].style.transform = 'scale(1)';
    var scalableContainerWidth = scalableContainer.offsetWidth - margin;
    var scalableWidth = scalable[i].offsetWidth;
    scalable[i].style.transform = 'scale(' + scalableContainerWidth / scalableWidth + ')';
    scalableContainer.style.height = scalable[i].getBoundingClientRect().height + 'px';
  }
}

Démo de travail: https://codepen.io/maciejkorsan/pen/BWLryj

5
Maciej Korsan

Mon problème était similaire mais lié à la mise à l'échelle du texte dans un en-tête. J'ai essayé Fit Font mais je devais basculer le compresseur pour obtenir des résultats, car cela résolvait un problème légèrement différent, tout comme Text Flow. J'ai donc écrit mon propre petit plugin qui réduit la taille de la police pour l'adapter au conteneur, en supposant que vous ayez overflow: hidden et white-space: nowrap de sorte que même si réduire la police au minimum ne permet pas d'afficher l'intégralité du titre, il coupe simplement ce qu'il peut afficher. .

(function($) {

  // Reduces the size of text in the element to fit the parent.
  $.fn.reduceTextSize = function(options) {
    options = $.extend({
      minFontSize: 10
    }, options);

    function checkWidth(em) {
      var $em = $(em);
      var oldPosition = $em.css('position');
      $em.css('position', 'absolute');
      var width = $em.width();
      $em.css('position', oldPosition);
      return width;
    }

    return this.each(function(){
      var $this = $(this);
      var $parent = $this.parent();
      var prevFontSize;
      while (checkWidth($this) > $parent.width()) {
        var currentFontSize = parseInt($this.css('font-size').replace('px', ''));
        // Stop looping if min font size reached, or font size did not change last iteration.
        if (isNaN(currentFontSize) || currentFontSize <= options.minFontSize ||
            prevFontSize && prevFontSize == currentFontSize) {
          break;
        }
        prevFontSize = currentFontSize;
        $this.css('font-size', (currentFontSize - 1) + 'px');
      }
    });

  };

})(jQuery);
5
Aram Kocharyan

jetez un oeil à mon code, il fait le font size smaller à fit quoi qu'il en soit

mais je pense que cela ne conduit pas à une bonne expérience utilisateur

var containerWidth = $("#ui-id-2").width();
var items = $(".quickSearchAutocomplete .ui-menu-item");
var fontSize = 16;

items.each(function(){
    //display value depend sometimes on your case you may make it block or inline-table instead of inline-block or whatever value that make the div take overflow width
    $(this).css({"whiteSpace":"nowrap","display":"inline-block"});
    while ($(this).width() > containerWidth){
         console.log("$(this).width()"+ $(this).width() + "containerWidth" + containerWidth)
         $(this).css("font-size", fontSize -= 0.5);
    }
});

 result

espérons que cela vous aide

3
Basheer AL-MOMANI

Cela a fonctionné pour moi:

J'essaie d'approximativement la taille de la police en fonction de la largeur/hauteur obtenue en paramétrant la taille de la police: 10px. En gros, l’idée est "si j’ai une largeur de 20 pixels et une hauteur de 11 pixels avec une taille de police: 10 pixels, quelle serait donc la taille de police maximale pour un conteneur de 50 pixels de large et 30 pixels de hauteur?"

La réponse est un système à double proportion:

{20: 10 = 50: X, 11: 10 = 30: Y} = {X = (10 * 50)/20, Y = (10 * 30)/11}

Maintenant, X est une taille de police qui correspond à la largeur, Y est une taille de police qui correspond à la hauteur; prendre la plus petite valeur

function getMaxFontSizeApprox(el){
    var fontSize = 10;
    var p = el.parentNode;

    var parent_h = p.offsetHeight ? p.offsetHeight : p.style.pixelHeight;
    if(!parent_h)parent_h = 0;

    var parent_w = p.offsetHeight ? p.offsetWidth : p.style.pixelWidth;
    if(!parent_w)parent_w = 0;

    el.style.fontSize = fontSize + "px";

    var el_h = el.offsetHeight ? el.offsetHeight : el.style.pixelHeight;
    if(!el_h)el_h = 0;

    var el_w = el.offsetHeight ? el.offsetWidth : el.style.pixelWidth;
    if(!el_w)el_w = 0;

    //0.5 is the error on the measure that js does
    //if real measure had been 12.49 px => js would have said 12px
    //so we think about the worst case when could have, we add 0.5 to 
    //compensate the round error
    var fs1 = (fontSize*(parent_w + 0.5))/(el_w + 0.5);
    var fs2 = (fontSize*(parent_h) + 0.5)/(el_h + 0.5);

    fontSize = Math.floor(Math.min(fs1,fs2));
    el.style.fontSize = fontSize + "px";
    return fontSize;
}

NB: l'argument de la fonction doit être un élément span ou un élément plus petit que son parent, sinon, si les enfants et le parent ont la même largeur/hauteur, la fonction échouera.

2
Maurizio Ricci

En tant que solution de secours JavaScript (ou votre seule solution), vous pouvez utiliser mon plugin jQuery Scalem , qui vous permet de redimensionner par rapport à l'élément parent (conteneur) en passant l'option reference.

2
thdoan

Pour les textes dynamiques, ce plugin est très utile http://freqdec.github.io/slabText/ . Ajoutez simplement css

.slabtexted .slabtext
    {
    display: -moz-inline-box;
    display: inline-block;
    white-space: nowrap;
    }
.slabtextinactive .slabtext
    {
    display: inline;
    white-space: normal;
    font-size: 1em !important;
    letter-spacing: inherit !important;
    Word-spacing: inherit !important;
    *letter-spacing: normal !important;
    *Word-spacing: normal !important;
    }
.slabtextdone .slabtext
    {
    display: block;
    }

et script

$('#mydiv').slabText();
2
pajouk

Essayez d’utiliser fitText plugin, car la taille du Viewport n’est pas la solution à ce problème . Il suffit d’ajouter une bibliothèque.

<script src="http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"></script> <script src="jquery.fittext.js"></script>

et changez la taille de la police pour corriger en paramétrant le coefficient de texte:

$("#text_div").fitText(0.8);

vous pouvez définir les valeurs max et min du texte:

$("#text_div").fitText(0.8, { minFontSize: '12px', maxFontSize: '36px' });
2
dsb

Toujours avoir votre élément avec cet attribut:

Javascript: element.style.fontSize = "100%";

ou

CSS: style = "font-size: 100%;"

Lorsque vous passez en mode plein écran, vous devriez déjà avoir une variable scale calculée (scale> 1 ou scale = 1). Ensuite, en plein écran:

document.body.style.fontSize = (scale * 100) + "%";

Cela fonctionne bien avec peu de code.

2
marirena

Utiliser les variables CSS

Personne n'a encore mentionné les variables CSS, et cette approche a fonctionné mieux pour moi, alors:

Supposons que votre page contienne une colonne qui correspond à 100% de la largeur de l'écran d'un utilisateur de mobile, mais dont le max-width est 800px. Il y a donc de l'espace sur le bureau de chaque côté de la colonne. Mettez ceci en haut de votre page:

<script> document.documentElement.style.setProperty('--column-width', Math.min(window.innerWidth, 800)+'px'); </script>

Et maintenant, vous pouvez utiliser cette variable (au lieu de l'unité vw intégrée) pour définir la taille de votre police. Par exemple.

p {
  font-size: calc( var(--column-width) / 100 );
}

Ce n'est pas une approche pure CSS, mais c'est assez proche.

1
user993683

Pour adapter la taille de la police de caractères à son conteneur, consultez plutôt la fonction resizeFont() que j'ai partagée dans cette question (une combinaison d'autres réponses, dont la plupart sont déjà liées ici). Il est déclenché à l'aide de window.addEventListener('resize', resizeFont);.

Vanilla JS: Redimensionner la taille de la police pour s'adapter au conteneur

JS:

function resizeFont() {
  var elements  = document.getElementsByClassName('resize');
  console.log(elements);
  if (elements.length < 0) {
    return;
  }
  _len = elements.length;
  for (_i = 0; _i < _len; _i++) {
    var el = elements[_i];
    el.style.fontSize = "100%";
    for (var size = 100; el.scrollHeight > el.clientHeight; size -= 10) {
      el.style.fontSize = size + '%';
    }
  }
}

Vous pouvez peut-être utiliser vw/vh en tant que solution de secours. Vous pouvez ainsi affecter dynamiquement des unités em ou rem à l'aide de javascript, en vous assurant que les polices sont redimensionnées vers la fenêtre si javascript est désactivé.

Appliquez la classe .resize à tous les éléments contenant le texte que vous souhaitez mettre à l'échelle.

Déclenchez la fonction avant d'ajouter l'écouteur d'événement de redimensionnement de la fenêtre. Ensuite, tout texte ne correspondant pas à son conteneur sera réduit lors du chargement de la page, ainsi que lors de son redimensionnement.

REMARQUE: le font-size par défaut doit être défini sur em, rem ou % pour obtenir des résultats corrects.

1
Joshua Flood

Je ne vois aucune réponse concernant la propriété CSS flex, mais elle peut aussi être très utile.

1
Smart Coder

html

<div style="height:100px; width:200px;">
  <div id='qwe'>
    test
  </div>
</div>

js pour maximiser la taille de police

 el = document.getElementById('qwe');        
 maxFontPixels = 50;
    maxHeight = el.parentElement.offsetHeight;
    fontSize = Number(maxFontPixels || maxHeight);
    el.style.width = '100%';
    el.style.overflowWrap = 'break-Word';
    var minFS = 3, maxFS = fontSize;
    while (fontSize != minFS) {
      el.style.fontSize = `${fontSize}px`;
      if (el.offsetHeight < maxHeight) {
        minFS = fontSize;
      } else{
        maxFS = fontSize;
      }
      fontSize = Math.floor((minFS + maxFS)/2);
    }
    el.style.fontSize = `${minFS}px`;
0
Ramil Gilfanov

Les requêtes de média directes semblent être une solution beaucoup plus simple et plus compréhensible pour redimensionner une police en fonction de la taille des conteneurs qui peuvent être dynamiques.

La section ci-dessous redimensionne la police à la taille du conteneur, que celui-ci soit redimensionné à la taille de la fenêtre d'affichage ou qu'il atteigne sa valeur maximale. Si vous avez des conteneurs d'une largeur différente de 100%, vous pouvez ajuster la vw en conséquence.

.container {
    width: 100%;
    max-width: 600px;
}
.headline {
    font-size: 20vw;
}
.subhead {
    font-size: 5vw;
}
@media (min-width:600px) {
    .headline {
        font-size: 120px;
    }
    .subhead {
        font-size: 32px;
    }
}
0
Justin Krause

Mais que se passe-t-il si le conteneur n'est pas la fenêtre (le corps)?

La vraie réponse est que la propriété transform vous permet de manipuler visuellement un élément en inclinant, en faisant pivoter, en traduisant ou en redimensionnant:

https://css-tricks.com/almanac/properties/t/transform/

0
Crystal