web-dev-qa-db-fra.com

Comment changer automatiquement la taille du texte dans une div?

J'ai une image de fond avec un div. Je veux écrire du texte, mais ce texte doit modifier la taille de la police via la variable div.

20
useCase

Je comprends votre question de cette façon. Vous voudriez insérer du texte dans une div donnée avec une dimension fixe. Si la div est trop petite pour afficher tout le texte, la taille de la police doit être réduite jusqu'à ce que le texte s’intègre dans la div. Si tel est le cas, voici ma solution.

Voici un exemple avec une implémentation jQuery: http://jsfiddle.net/MYSVL/2/

Voici un div

<div id="fitin">
    <div>Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet.</div>
</div>

Avec une taille fixe

#fitin {
    width: 300px;
    height: 100px;
    border: 1px solid black;
    overflow: hidden;
    font-size: 1em;
}

Ce JavaScript fera le travail.

$(function() {
    while( $('#fitin div').height() > $('#fitin').height() ) {
        $('#fitin div').css('font-size', (parseInt($('#fitin div').css('font-size')) - 1) + "px" );
    }
});
52
DanielB

FlowType.js fera exactement cela: redimensionnez la police pour qu'elle corresponde à l'élément de délimitation, qu'il s'agisse d'un div ou d'un autre type d'élément.

Un exemple d'implémentation de FlowType:

  1. Configurez votre style

    body {
    font-size: 18px;
    line-height: 26px;
    }
    
  2. Téléchargez FlowType depuis GitHub et ajoutez-y une référence dans votre élément head

    flowtype.jQuery.js
    
  3. Call FlowType

    $('body').flowtype();
    
  4. (facultatif) Mise à jour des paramètres par défaut

    $('body').flowtype({
    minimum   : 500,
    maximum   : 1200,
    minFont   : 12,
    maxFont   : 40,
    fontRatio : 30,
    lineRatio : 1.45
    });
    

Découvrez leur page d'accueil pour une démo interactive

6
jdhurst

Je ne suis pas tout à fait sûr de comprendre votre question, mais je pense que ce que vous demandez, c'est comment insérer du texte dans un conteneur particulier de taille prédéfinie. Je vais essayer de répondre à cette question.

Côté client

Lorsque vous voulez faire cela à la demande du client, vous devrez utiliser Javascript. L'idée est de:

  1. générer une div invisible et définir son style sur:

    position: absolute;
    top: 0;
    left: 0;
    width: auto;
    height: auto;
    display: block;
    visibility: hidden;
    font-family: /* as per your original DIV */
    font-size: /* as per your original DIV */
    white-space: /* as per your original DIV */
    
  2. copiez votre texte 

  3. vérifiez si la largeur de DIV dépasse la taille de votre DIV d'origine.

  4. ajustez la valeur font-size non seulement en incrémentant/décrémentant, mais en calculant la différence de largeur entre votre DIV invisible et la DIV originale. Cela s’écartera pour corriger la taille beaucoup plus rapidement.

  5. allez à l'étape 3 .

Du côté serveur

Il n’existe aucun moyen fiable de définir la taille de la police sur le serveur afin qu’elle s'adapte à votre conteneur restitué par le client. Malheureusement, vous ne pouvez approximer les tailles que sur des données empiriques prétestées.

1
Robert Koritnik

La question a été répondue depuis longtemps, mais je voudrais ajouter quelques notes.

Depuis, un plugin jQuery supplémentaire a été ajouté à l'univers: FlowType.js

https://github.com/simplefocus/FlowType.JS

J'ai essayé mes solutions et plugins (y compris FlowType.JS), à la fin j'ai écrit le mien. J'aime juste l'inclure ici en tant qu '"inspiration". J'utilise une approche différente: je calcule le rapport entre la taille du texte et son parent. Je ne sais pas si cela a du sens, mais pour moi ça marche bien. 

    /* shrinkText jQuery Plugin  */

(function( $ ){

  $.fn.shrinkText = function() {

    var $_me = this;
    var $_parent = $_me.parent();

    var int_my_width = $_me.width();
    var int_parent_width = $_parent.width();

    if ( int_my_width > int_parent_width ){

      rl_ratio =   int_parent_width / int_my_width;

      var int_my_fontSize = $_me.css("font-size").replace(/[^-\d\.]/g, '');

      int_my_fontSize = Math.floor(int_my_fontSize * rl_ratio);

      $_me.css("font-size", int_my_fontSize + "px");

    }
  };

})( jQuery );

Il suppose un élément inline dans un élément de niveau bloc, il réduit l'élément inline en recalculant la taille de la police.

HTML:

<h1 style="white-space:nowrap;">
  <a href="#" >Macrobenthos of the North Sea - Miscellaneous worms</a>
</h1>

JavaScript:

if( jQuery().shrinkText ){
    $("#title a").shrinkText();
}
1
Ideogram

Vous devez précharger l'image pour obtenir la largeur et la hauteur de l'image.

Dès que vous avez les dimensions, vous pouvez "essayer" différentes tailles de police:

$("<img/>").appendTo(document.body).attr('src','myBackground.png').load(function(){
    var width = $(this).width(), height = $(this).height(),
        $div = $("#myDivId"),
        font = 30;

    do{
      font--;
      $div.css('font-size',font);
    }while($div.width()>width || $div.height()>height || font == 0);

    $div.width(width);
    $div.height(height);
});
0
jantimon

Découvrez cet exemple ici http://codepen.io/LukeXF/pen/yOQWNb , vous pouvez utiliser une fonction simple lors du chargement et du redimensionnement d'une page pour que la magie opère.

function resize() {  
    $('.resize').each(function(i, obj) {
        $(this).css('font-size', '8em');

        while ($(this).width() > $(this).parent().width()) {
            $(this).css('font-size', (parseInt($(this).css('font-size')) - 1) + "px");
        }
    });
}
0
LukeXF

J'ai fait une meilleure version du code @DanielB, peut-être que ça fait gagner du temps à quelqu'un :)

(Ajoutez simplement la classe RESIZABLE au div que vous voulez changer)

$(document).ready(function() {
    $(window).resize(function() {

        $('.RESIZABLE').each(function(i, obj) {
            $(this).css('font-size', '8em');

            while ($(this).width() > $(this).parent().width()) {
                $(this).css('font-size', (parseInt($(this).css('font-size')) - 1) + "px");
            }
        });






    });
});
0
Adacho

Voici une fonction globale avec des annotations JQuery et HTML5 Data permettant de définir la taille du bloc:

Ne me demandez pas pourquoi j'ai besoin de la table :-), la fonction width fonctionne mieux avec les tables ... sur Jquery 1.7 .. N'obtenir aucune largeur pour les Div

Utilisation:

<table>
 <tr>
    <td class="caa" data-text-max-width="500" data-text-max-height="80">
       The Text is Here
    </td>
 </tr>
</table>

Fonction à ajouter: 

$(function () {
    var textConsts = {
        MIN_SIZE_OF_A_TEXT: 9
    };

    $('*[data-text-max-width]').each(function () {

        var textMaxWidth = $(this).data("text-max-width");
        var textMaxHeight = $(this).data("text-max-height");
        var minSizeOfaText = $(this).data("text-min-size");

        $(this).css('font-size', '9em');

        if (minSizeOfaText == null || !($(this).hasData("text-min-size")))
            minSizeOfaText = textConsts.MIN_SIZE_OF_A_TEXT;

        if (textMaxWidth == null || !($(this).hasData("text-max-width")))
            textMaxWidth = $(this).parent().width();

        if (textMaxHeight == null || !($(this).hasData("text-max-height")))
            textMaxHeight = $(this).parent().height();

        var curentWidth = $(this).width();
        var curentFontSize = 0;
        var numberOfRounds = 0;
        var currentHeigth = $(this).height();
        curentFontSize = parseInt($(this).css('font-size'));
        var lineHeigth = parseInt($(this).css('line-height'));
        if (currentHeigth > (curentFontSize * lineHeigth)) {
            curentWidth += curentFontSize * lineHeigth;
        }

        while (curentWidth > textMaxWidth || currentHeigth > textMaxHeight) {

            curentFontSize = parseInt($(this).css('font-size'));
            curentFontSize -= 1;

            $(this).css('font-size', curentFontSize + "px");

            curentWidth = $(this).width();
            currentHeigth = $(this).height();

            if (currentHeigth > (curentFontSize * 1.5))
                curentWidth += curentFontSize * 1.5;

            numberOfRounds += 1;

            if (numberOfRounds > 1000)
                break;

            if (curentFontSize <= minSizeOfaText)
                break;
        }

        $(this).css('height', textMaxHeight + "px");
        $(this).css('width', textMaxWidth + "px");
    });

});
0
OBender

J'étends la solution DanielB dans le cas où vous avez un code HTML complexe dans la div et que vous souhaitez conserver le rapport entre différents éléments:

$(function() {
    $(window).on('resize', function() {
        $('#fitin').css('font-size', '1em');
        var count = 0;
        while( count< 30 && $('#fitin').height() > $('#fitin div').height() ) { 
            $('#fitin *').each(function( index ) {
                $(this).css('font-size',(parseInt($(this).css('font-size')) + 1) + "px");
            });
            count++;
        } 
        count = 0;
        while( count< 30 && $('#fitin div').height() > $('#fitin').height()-20 ) {
            $('#fitin *').each(function( index ) {
                $(this).css('font-size',(parseInt($(this).css('font-size')) - 1) + "px");
            })
            count++;
        }
    });
    $(window).trigger('resize');  
});
0
Renzo Ciot