Cambie dinámicamente el tamaño de la fuente en función de la longitud del texto

7 minutos de lectura

avatar de usuario de user2613399
usuario2613399

Necesito mostrar el texto ingresado por el usuario en un div de tamaño fijo. Lo que quiero es que el tamaño de la fuente se ajuste automáticamente para que el texto llene el cuadro tanto como sea posible.

Probablemente me gustaría comenzar con un tamaño de fuente máximo y, aunque el texto es demasiado grande para caber en el contenedor, reducir el tamaño de fuente hasta que quepa y la fuente debe mostrarse como una sola línea.

  • No, no es posible hacerlo solo con CSS.

    – roberto

    14 de agosto de 2013 a las 10:28

  • alguien me puede dar una solución usando js

    – usuario2613399

    14 de agosto de 2013 a las 11:18

avatar de usuario de putvande
putvande

Di que tienes esto:

<div id="outer" style="width:200px; height:20px; border:1px solid red;">
    <div>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer mollis dui felis, vel vehicula tortor cursus nec</div>
</div>

Entonces puedes hacer algo como:

$(document).ready(function () {
    resize_to_fit();
});

function resize_to_fit(){
    var fontsize = $('div#outer div').css('font-size');
    $('div#outer div').css('fontSize', parseFloat(fontsize) - 1);

    if($('div#outer div').height() >= $('div#outer').height()){
        resize_to_fit();
    }
}

Muestra de trabajo

$(document).ready(function() {
  resize_to_fit();
});

function resize_to_fit() {
  var fontsize = $('div#outer div').css('font-size');
  $('div#outer div').css('fontSize', parseFloat(fontsize) - 1);

  if ($('div#outer div').height() >= $('div#outer').height()) {
    resize_to_fit();
  }
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="outer" style="width:200px; height:20px; border:1px solid red;">
  <div>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer mollis dui felis, vel vehicula tortor cursus nec</div>
</div>

  • Esto requiere jquery para ejecutarse, la operación nunca indica jquery.

    – sin sal

    5 jun 2019 a las 19:50

Basado en la lógica de la respuesta principal aquí, creé un versión sin jQuery,

const input = document.querySelector('input');
const output = document.querySelector('.output');
const outputContainer = document.querySelector('.container');

function resize_to_fit() {
  let fontSize = window.getComputedStyle(output).fontSize;
  output.style.fontSize = (parseFloat(fontSize) - 1) + 'px';
  
  if(output.clientHeight >= outputContainer.clientHeight){
    resize_to_fit();
  }
}

function processInput() { 
  output.innerHTML =this.value;
  output.style.fontSize="100px"; // Default font size
  resize_to_fit();
}

input.addEventListener('input', processInput);
<input type="text" placeholder="Add text input here" style="margin: 10px; width:50%;">

<div id="outer" class="container" 
style="width:80%; height:100px; border:2px solid red; font-size:20px;">
  
<div class="output" style="word-break: break-all; word-wrap: break-word;">
</div>

</div>

avatar de usuario de cfs
CFS

Obtener el tamaño en píxeles de una cadena de texto es algo difícil de hacer y depende mucho del navegador y la configuración del usuario, por lo que probablemente será difícil encontrar una solución que funcione en todos los casos.

Por “mostrar texto ingresado por el usuario”, ¿quiere decir que el usuario está escribiendo en un cuadro de texto? Si es así, puede adjuntar un oyente de pulsación de tecla que comprueba la longitud del valor del texto, luego ajusta el font-size respectivamente. Aquí hay un ejemplo, aunque probablemente necesitará cambiar las longitudes y los tamaños de fuente para satisfacer sus necesidades:

Demostración de trabajo

$('#text').on('keypress', function(e) {
    var that = $(this),
        textLength = that.val().length
    ;

    if(textLength > 30) {
        that.css('font-size', '5px');
    } else if(textLength > 20) {
        that.css('font-size', '10px');
    } else if(textLength > 10) {
        that.css('font-size', '15px');
    }
});

  • ¿Qué sucede si el texto se obtiene de una fuente externa (el usuario no escribirá en el cuadro) y ese texto debe mostrarse en un div? ¿Cómo sabremos el tamaño del texto?

    – usuario2613399

    14 de agosto de 2013 a las 17:11

  • Vea la respuesta de @ putvande, creo que eso podría ser lo que más se acerca a lo que está buscando

    – CFS

    14/08/2013 a las 17:17

Avatar de usuario de Akin Hwan
Akin Hwan

Si por longitud de texto se refiere al número de caracteres, hay este artículo que apunta a un fragmento de jquery corto. Cambiar el tamaño de fuente dinámicamente en función del número de caracteres.

http://jsfiddle.net/jfbrLjt2/

 $('.text').each(function(){
 var el= $(this);
   var textLength = el.html().length;
    if (textLength > 20) {
        el.css('font-size', '0.8em');
    }
});

<!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
    <style>
        #div1{
            width: 200px;
            height: 200px;
            font-size: 32px;
            line-height: 1.2em;
        }
    </style>
    <script type="text/javascript" src="https://stackoverflow.com/questions/18229230/js/jquery-1.9.1.min.js"></script>
    <script>
        $(function(){
            n = 1;
            while(n==1){
                n = 0
                if ($('#div1 .holder').outerHeight()>$('#div1').outerHeight()){
                    var fz = parseInt($('#div1').css('font-size'));
                    $('#div1').css({'font-size' : fz-1});
                    n = 1
                } else {n = 0}
            }
        });
    </script>
</head>
<body>
    <div id="div1">
        <div class="holder">I need to display user entered text into a fixed size div. What i want is for the font size to be automatically adjusted so that the text fills the box as much as possible.
I'd probably want to start with a maximum font size and while the text is too big to fit the container, shrink the font size until it fits and the font must be displayed as a single line. Is it possible to do this using only css and html.</div>
    </div>
</body>
</html>

  • ¿Por qué no usar un valor booleano en lugar de n=1?

    – CFS

    14 de agosto de 2013 a las 12:57

  • ¿Cual es la diferencia? Es solo una bandera. Escribí lo primero que se te vino a la mente

    – Anónimo

    14 de agosto de 2013 a las 13:05

  • Por lo general, los indicadores son booleanos; de lo contrario, puede resultar confuso para alguien que lea su código, ya que un número entero puede indicar que hay más de dos estados.

    – CFS

    14 de agosto de 2013 a las 13:49

  • o hacer while(true) y break

    – reformado

    8 de agosto de 2019 a las 17:06

Avatar de usuario de Joe
José

Gracias putvande por dejarme saber el método general. Aquí hay una versión mejorada.

  1. Deshazte del infierno de devolución de llamada.
  2. Se corrigieron algunos errores que pueden causar que la página se cuelgue.

Mismo HTML:

<div id="outer" style="width:200px; height:20px; border:1px solid red;">
    <div>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer mollis dui felis, vel vehicula tortor cursus nec</div>
</div>

Aquí está la función:

resize_to_fit($('#outer'), $('#outer div'));

function resize_to_fit(outer, inner) {
    while(inner.height() > outer.height()) {
        var fontsize = parseInt(inner.css('font-size')) - 1;
        inner.css('font-size', fontsize);
        // some browsers(chrome) the min font return value is 12px
        if(fontsize <= 1 || parseInt(inner.css('font-size')) >= fontsize+1)
            break;
    }
}

  • ¿Por qué no usar un valor booleano en lugar de n=1?

    – CFS

    14 de agosto de 2013 a las 12:57

  • ¿Cual es la diferencia? Es solo una bandera. Escribí lo primero que se te vino a la mente

    – Anónimo

    14 de agosto de 2013 a las 13:05

  • Por lo general, los indicadores son booleanos; de lo contrario, puede resultar confuso para alguien que lea su código, ya que un número entero puede indicar que hay más de dos estados.

    – CFS

    14 de agosto de 2013 a las 13:49

  • o hacer while(true) y break

    – reformado

    8 de agosto de 2019 a las 17:06

avatar de usuario de ecairol
ecairol

Usando muy poco Javascript, puede asignar una clase CSS con la longitud de la cadena, por ejemplo: text-length-5 o text-length-20

Luego use exclusivamente CSS para apuntar a diferentes font-size de acuerdo con esos nombres de clase.

Probablemente no funcione para todos los casos, pero funcionó muy bien para el mío, donde la longitud máxima era de unos 10-12 caracteres.

Si tiene más de 100 o más de 1000 caracteres, también puede crear una función que reciba la longitud y devuelva una clase CSS, luego estilice la base en esos rangos.


HTML:

<div class="box">ABC</div>
<div class="box">ABCDE</div>

Javascript (jQuery, pero la misma idea se puede aplicar a React o Vanilla JS)

$(".box").each((i, el)=> {
  const length = $(el).text().length;
  $(el).addClass("text-length-"+length);
})

CSS:

.box {
  font-size: 16px;
}
.box.text-length-4,
.box.text-length-5,
.box.text-length-6 {
  font-size: 12px;
}

¿Ha sido útil esta solución?