web-dev-qa-db-fra.com

Ajustez le texte parfaitement à l'intérieur d'un div (hauteur et largeur) sans affecter la taille du div

Je m'excuse par avance, car je sais que cette question a déjà été posée à plusieurs reprises, mais je n'arrive pas à trouver la bonne solution (et croyez-moi, j'en ai essayé quelques-unes!)

Fondamentalement, c'est l'ancien " Ajuster le texte parfaitement à l'intérieur d'un div sans affecter la taille du div ". Et à moins que je ne sois complètement numéroté, je pense que CSS n’a aucun moyen de le faire. Donc, ce que je veux dire fondamentalement, c'est plutôt que de faire quelque chose comme:

#someDiv {
font-size: 12px;
}

ou...

#someDiv {
font-size: 1em;
}

... Je veux pouvoir faire quelque chose comme ça:

#someDiv {
font-size: fluid;
}

... signifiant que quel que soit le texte contenu dans cette div, adaptez-le parfaitement de gauche à droite et de haut en bas, sans débordement ni espace.

Après avoir parcouru d'innombrables sites Web à la recherche de cette solution CSS, j'ai maintenant accepté le fait que CSS n'en est pas capable ... alors, entrez jQuery.

J'ai trouvé plusieurs solutions jQuery en ligne, mais elles ne font que redimensionner le texte pour l'adapter à la largeur, mais je souhaite également l'adapter à la hauteur. Donc, effectivement, je veux dire à jQuery:

"jQuery, trouvez $ (this) div et le texte qu’il contient, je veux que vous l’échelonniez de manière à ce qu’il remplisse le plus possible la hauteur et la largeur de la div".

Au cas où je ne m'expliquerais pas très bien, j'ai joint un graphique expliquant le problème auquel je suis confronté et la solution que je recherche.

Toute aide serait très appréciée. Je vous remercie.

enter image description here

22
Ben Clarke

Voici la même réponse, mais en Javascript

var autoSizeText;

autoSizeText = function() {
  var el, elements, _i, _len, _results;
  elements = $('.resize');
  console.log(elements);
  if (elements.length < 0) {
    return;
  }
  _results = [];
  for (_i = 0, _len = elements.length; _i < _len; _i++) {
    el = elements[_i];
    _results.Push((function(el) {
      var resizeText, _results1;
      resizeText = function() {
        var elNewFontSize;
        elNewFontSize = (parseInt($(el).css('font-size').slice(0, -2)) - 1) + 'px';
        return $(el).css('font-size', elNewFontSize);
      };
      _results1 = [];
      while (el.scrollHeight > el.offsetHeight) {
        _results1.Push(resizeText());
      }
       return _results1;
    })(el));
  }
  return _results;
};

$(document).ready(function() {
  return autoSizeText();
});

À propos ... si vous avez besoin de convertir coffeescript en javascript, rendez-vous sur js2coffee.org

15
joshboley

Je voulais quelque chose de similaire moi-même récemment:

<div class='container'>
    <div class='no-resize'>This text won't be resized and will go out of the div.</div>
    <div class='resize'>This text will be resized and wont go out of the div.</div>
</div>

Et

.no-resize, .resize {
    width: 100px;
    height: 50px;
    border: 1px solid #000;
    color: #000;
    float: left;
    margin-left: 10px;
    font-size: 15px
}

Fiddler à jsfiddle.net/mn4rr/1/ .

10
Thomas McNaught

Je n'ai pas assez de réputation pour commenter la réponse acceptée alors j'ai fait une réponse. Si height a une transition css3 dessus, les réponses autoSizeText() et $.resizeText ci-dessus ont des problèmes. J'ai fait un plugin jquery court pour résoudre ce problème. 

$.fn.resizeText = function (options) {

    var settings = $.extend({ maxfont: 40, minfont: 4 }, options);

    var style = $('<style>').html('.nodelays ' +
    '{ ' +
        '-moz-transition: none !important; ' +
        '-webkit-transition: none !important;' +
        '-o-transition: none !important; ' +
        'transition: none !important;' +
    '}');

    function shrink(el, fontsize, minfontsize)
    {
        if (fontsize < minfontsize) return;

        el.style.fontSize = fontsize + 'px';

        if (el.scrollHeight > el.offsetHeight) shrink(el, fontsize - 1, minfontsize);
    }

    $('head').append(style);

    $(this).each(function(index, el)
    {
        var element = $(el);

        element.addClass('nodelays');

        shrink(el, settings.maxfont, settings.minfont);

        element.removeClass('nodelays');
    });

    style.remove();
}

Pour utiliser ce plugin, il vous suffit d'appeler

 $(selector).resizeText();

J'espère que cela économisera du temps à quelqu'un d'autre. J'ai perdu 20 bonnes minutes à me demander pourquoi le code ci-dessus provoquait une boucle infinie sur ma page.

8
Kelt

J'ai résolu ceci en faisant un plugin jQuery, c'est ici: http://jsfiddle.net/c9YNz/2/ (Mise à jour pour gérer le redimensionnement des fenêtres)

Le code pour le plugin réduit simplement le texte à une taille de 0.01em et le redimensionne ensuite, voici le code du plugin:

$.fn.resizeText = function () {
    var width = $(this).innerWidth();
    var height = $(this).innerHeight();
    var html =  $(this).html();
    var newElem = $("<div>", {
        html: html,
        style: "display: inline-block;overflow:hidden;font-size:0.1em;padding:0;margin:0;border:0;outline:0"
    });

    $(this).html(newElem);
    $.resizeText.increaseSize(10, 0.1, newElem, width, height);

    $(window).resize(function () {
        if ($.resizeText.interval)
            clearTimeout($.resizeText.interval)

        $.resizeText.interval = setTimeout(function () {
            elem.html(elem.find("div.createdResizeObject").first().html());
            elem.resizeText();
        }, 300);
    });
}

$.resizeText = {
    increaseSize: function (increment, start, newElem, width, height) {
        var fontSize = start;

        while (newElem.outerWidth() <= width && newElem.outerHeight() <= height) {
            fontSize += increment;
            newElem.css("font-size", fontSize + "em");
        }

        if (newElem.outerWidth() > width || newElem.outerHeight() > height) {
            fontSize -= increment;
            newElem.css("font-size", fontSize + "em");
            if (increment > 0.1) {
                $.resizeText.increaseSize(increment / 10, fontSize, newElem, width, height);
            }
        }
    }
};

Alors si vous avez ce code HTML:

<div class="resizeText" style="width:1200px;height:400px;">
Insert text from slipsum here.
</div>

Vous l'appelez juste comme ça:

$(document).ready(function () {
    $(".resizeText").resizeText();
});

Ce n’est pas la meilleure façon de le faire, mais c’est suffisant pour vous, je l’imagine (en plus, cela fonctionne).

4
Maverick

Voici une version légèrement modifiée des réponses données.

Exigences

  1. La classe contenant du texte a la classe "redimensionner".
  2. il contient la hauteur et la largeur (%, px, peu importe ...)

Quels changements dans cette version?  

  1. J'ai ajouté le redimensionnement (en liant l'événement resize à la fonction) autoSizeText. C'est loin d'être idéal, mais si nous ne redimensionnons pas beaucoup, ça devrait aller.
  2. Dans les versions précédentes, le texte ne faisait que diminuer. Maintenant, il essaie de trouver la plus grande police sans sortir de la div.

Remarque: 

Je ne prétends pas que le code est prêt pour la production. Mais si vous trouvez quelque chose que vous pouvez améliorer, veuillez le partager avec la communauté.

var autoSizeText = function () {
    var el, elements, _i, _len;
    elements = $('.resize');
    if (elements.length < 0) {
        return;
    }
    for (_i = 0, _len = elements.length; _i < _len; _i++) {
        el = elements[_i];
        dichoFit = function (el) {

            diminishText = function () {
                var elNewFontSize;
                elNewFontSize = (parseInt($(el).css('font-size').slice(0, -2)) - 1) + 'px';

                return $(el).css('font-size', elNewFontSize);
            };
            augmentText = function () {
                var elNewFontSize;
                elNewFontSize = (parseInt($(el).css('font-size').slice(0, -2)) + 1) + 'px';

                return $(el).css('font-size', elNewFontSize);
            };


            diminishText();
            while (el.scrollHeight < el.offsetHeight) {
                augmentText();
            }
            augmentText();
            while (el.scrollHeight > el.offsetHeight) {
                diminishText();
            }

        }
        dichoFit(el);
    }
};

$(document).ready(function () {
    autoSizeText();
    $(window).resize(function resizeText(){
        autoSizeText()
    })
});
.sizable{
 width: 50vw;
 height: 50vh;
 border: 2px solid darkred;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

  <div class='sizable resize'>
  I am a sizable div and I have explicit width and height.
</div>

2
madjaoue

Désolé, la réponse tardive mais peut gagner du temps de beaucoup, J'écris ce code qui fonctionne parfaitement pendant le redimensionnement de la fenêtre.

function fitTextInDiv(){
    if($this.find('.text-wrapper').height() > $this.find('.aligned-text').height() ){
        while( $this.find('.text-wrapper').height() > $this.find('.aligned-text').height() ) {
             $this.find('.aligned-text').css('font-size', (parseFloat($this.find('.aligned-text').css('font-size')) + 0.1) + "px" );
        }
    }
    else if($this.find('.text-wrapper').height() < $this.find('.aligned-text').height() ){
        while( $this.find('.text-wrapper').height() < $this.find('.aligned-text').height() ) {
            $this.find('.aligned-text').css('font-size', (parseFloat($this.find('.aligned-text').css('font-size')) - 0.1) + "px" );
        }

     }
}

Où text-wrapper est le parent et où litered-text est l'enfant div. Vous devez spécifier la hauteur et la largeur de l'élément parent. Dans le redimensionnement, vous pouvez définir la hauteur et la largeur de l'élément parent à l'aide de jquery, puis appeler cette fonction.

J'écris ce code parce que j'ai essayé mes nombreux plugins mais ils ne supportent pas le redimensionnement de la fenêtre.

0
Danesh

J'ai le même problème et la solution consiste essentiellement à utiliser du javascript pour contrôler la taille de la police. Consultez cet exemple sur codepen: 

https://codepen.io/ThePostModernPlatonic/pen/BZKzVR

essayez de le redimensionner 

<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>Documento sem título</title>
<style>
</style>
</head>
<body>
<div style="height:100vh;background-color: tomato;" id="wrap">        
  <h1 class="quote" id="quotee" style="padding-top: 56px">Because too much "light" doesn't <em>illuminate</em> our paths and warm us, it only blinds and burns us.</h1>
</div>
</body>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"></script>
<script>
  var multiplexador = 3;
  initial_div_height = document.getElementById ("wrap").scrollHeight;
  setInterval(function(){ 
    var div = document.getElementById ("wrap");
    var frase = document.getElementById ("quotee");
    var message = "WIDTH div " + div.scrollWidth + "px. "+ frase.scrollWidth+"px. frase \n";
    message += "HEIGHT div " + initial_div_height + "px. "+ frase.scrollHeight+"px. frase \n";           
    if (frase.scrollHeight < initial_div_height - 30){
      multiplexador += 1;
      $("#quotee").css("font-size", multiplexador); 
    }
    console.log(message);          
  }, 10);
</script>
</html>
0
Heitor Giacomini

Voici ma version. Ceci est construit avec ES6 sur un projet React.

export function autoSizeText(container, attempts=30) {
  let setChildrenToInheritFontSize = ( el ) => {
    el.style.fontSize = 'inherit';
    _.each( el.children, (child) => {
      setChildrenToInheritFontSize( child );
    });
  };


  let resizeText = (el) => {
    attempts--;
    let elNewFontSize;
    if( el.style.fontSize === "" ||  el.style.fontSize === "inherit" ||  el.style.fontSize === "NaN" ){
      elNewFontSize = '32px'; // largest font to start with
    } else {
      elNewFontSize = (parseInt(el.style.fontSize.slice(0, -2)) - 1) + 'px';
    }
    el.style.fontSize = elNewFontSize;

    // this function can crash the app, so we need to limit it
    if( attempts <= 0 ) {
      return;
    }

    if ( (el.scrollWidth > el.offsetWidth) || (el.scrollHeight > el.offsetHeight)) {
      resizeText(el);
    }
  };
  setChildrenToInheritFontSize( container );
  resizeText(container);
}
0
Steven Stark

J'ai récemment eu une div de largeur maximale qui recevait du texte d'un champ de saisie de texte et je devais adapter le texte à cette div. Voici comment je l'ai résolu (simple JS, sans plugin):

function addName(){
    let maxWidth = 550;
    let defaultFontSize = 50;
    let entry = document.getElementById('nameInput').value;
    let nameDiv = document.getElementById('name');
    let fontSize = nameDiv.style["font-size"];
    fontSize = fontSize.replace('px','');
    fontSize = parseInt(fontSize);
    nameDiv.innerText = entry;
    if (nameDiv.clientWidth > maxWidth) {
        fontSize = fontSize - 2.5;
        nameDiv.style["font-size"] = `${fontSize}px`;
    } else if (nameDiv.clientWidth < maxWidth && fontSize < defaultFontSize ) {
        fontSize = fontSize + 2.5;
        nameDiv.style["font-size"] = `${fontSize}px`;
    }
}
#name {
    height: 70px;
    line-height: 70px;
    text-align: center;
    overflow: hidden;
    width: auto;
    display: table; /*THAT DOES THE MAGIC*/
    margin: auto;
    border: 1px solid black
/* THE BORDER IS FOR TEST PURPOSES TO SEE WHAT'S HAPPENING WITH THE DIV*/
}
<input type="text" id="nameInput" oninput="addName()">
<div id="name" style="font-size: 50px;"></div>

0
iMac Ange