Escalado de fuente basado en el ancho del contenedor

Me está costando entender el escalado de fuentes.

Actualmente tengo un sitio web con un cuerpo font-size del 100%. ¿100% de qué? Esto parece computar a 16 píxeles.

Tenía la impresión de que 100% se referiría de alguna manera al tamaño de la ventana del navegador, pero aparentemente no porque siempre son 16 píxeles, ya sea que la ventana se redimensione a un ancho móvil o un escritorio de pantalla ancha en toda regla.

¿Cómo puedo hacer que el texto de mi sitio se escale en relación con su contenedor? Traté de usar em, pero esto tampoco escala.

Mi razonamiento es que cosas como mi menú se aplastan cuando cambia el tamaño, por lo que necesito reducir el px font-size of .menuItem entre otros elementos en relación al ancho del contenedor. (Por ejemplo, en el menú de un escritorio grande, 22px funciona perfectamente. Mover hacia abajo al ancho de la tableta y 16px es más apropiado.)

Soy consciente de que puedo agregar puntos de interrupción, pero realmente quiero que el texto se escale como bien como tener puntos de interrupción adicionales, de lo contrario, terminaré con cientos de puntos de interrupción por cada 100 píxeles de disminución en el ancho para controlar el texto.

preguntado el 17 de abril de 13 a las 10:04

font-size: 100%; significa el 100% del tamaño que habría tenido el texto (es decir, el que hereda de su padre). Por defecto es 16px. Entonces, si usara el 50%, sería tamaño de fuente: 8px -

Lo que está buscando se llama tipografía receptiva o del tamaño de una ventana gráfica. css-tricks.com/viewport-sized-typography -

Donar FitText una mirada. -

@Andy: En realidad, "de forma predeterminada" es el tamaño de texto del navegador que los usuarios tienen configurado, que no necesariamente se resuelve en 16 px. -

@PatsyIssa ¡Ahora, si solo hubiera algo así que no requiriera jQuery! -

30 Respuestas

Si el contenedor no es el cuerpo, CSS Tricks cubre todas sus opciones en Ajuste de texto a un contenedor.

Si el contenedor es el cuerpo, lo que buscas es Longitudes de porcentaje de ventana gráfica:

EL longitudes de porcentaje de ventana gráfica son relativas al tamaño de la bloque contenedor inicial. Cuando se cambia la altura o el ancho del bloque contenedor inicial, se escalan en consecuencia. Sin embargo, cuando el valor de desbordamiento en el elemento raíz es automático, se supone que no existen barras de desplazamiento.

Los valores son:

  • vw (% del ancho de la ventana gráfica)
  • vh (% de la altura de la ventana gráfica)
  • vi (1% del tamaño de la ventana gráfica en la dirección del eje en línea del elemento raíz)
  • vb (1% del tamaño de la ventana gráfica en la dirección del eje del bloque del elemento raíz)
  • vmin (el menor de vw or vh)
  • vmax (cuanto más grande o vw or vh)

1 v* es igual al 1% del bloque contenedor inicial.

Usarlo se ve así:

p {
    font-size: 4vw;
}

Como puede ver, cuando aumenta el ancho de la ventana gráfica, también lo hace el font-size, sin necesidad de utilizar consultas de medios.

Estos valores son una unidad de tamaño, al igual que px or em, por lo que también se pueden usar para cambiar el tamaño de otros elementos, como el ancho, el margen o el relleno.

La compatibilidad con el navegador es bastante buena, pero es probable que necesite una alternativa, como:

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

Consulte las estadísticas de soporte: http://caniuse.com/#feat=viewport-units.

Además, echa un vistazo a CSS-Tricks para una mirada más amplia: Tipografía de tamaño de ventana gráfica

Aquí hay un buen artículo sobre cómo establecer tamaños mínimos/máximos y ejercer un poco más de control sobre los tamaños: Control preciso sobre la tipografía receptiva

Y aquí hay un artículo sobre cómo configurar su tamaño usando calc() para que el texto llene la ventana gráfica: http://codepen.io/CrocoDillon/pen/fBJxu

Además, consulte este artículo, que utiliza una técnica denominada "dirección fundida" para ajustar también la altura de la línea. Líder fundido en CSS

contestado el 27 de mayo de 22 a las 22:05

Pero, ¿y si el contenedor no es la ventana gráfica (cuerpo)? - Alex

+1 para la solución SVG vinculada. Este es el único (cuando el contenedor no es el cuerpo) que funcionó para mí. ¿Hay alguna desventaja? - jugando

Pero, ¿y si el contenedor no es la ventana gráfica (cuerpo)?

Esta pregunta se hace en un comentario de Alex bajo la respuesta aceptada.

Ese hecho no significa vw no se puede utilizar hasta cierto punto al tamaño de ese contenedor. Ahora, para ver cualquier variación, uno tiene que asumir que el contenedor es de alguna manera flexible en tamaño. Ya sea a través de un porcentaje directo width o por ser 100% menos márgenes. El punto se vuelve "discutible" si el contenedor siempre se establece en, digamos, 200px ancho--entonces simplemente establezca un font-size que sirve para ese ancho.

ejemplo 1

Sin embargo, con un contenedor de ancho flexible, debe tenerse en cuenta que de alguna manera el contenedor es todavía está siendo dimensionado fuera de la ventana gráfica. Como tal, se trata de ajustar un vw configuración basada en esa diferencia de tamaño porcentual con respecto a la ventana gráfica, lo que significa tener en cuenta el tamaño de los contenedores principales. Toma este ejemplo:

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;
}

Suponiendo aquí la div es un hijo del body, es el 50% de eso 100% ancho, que es el tamaño de la ventana gráfica en este caso básico. Básicamente, desea establecer un vw eso te va a quedar bien. Como puede ver en mi comentario en el contenido de CSS anterior, puede "pensar" matemáticamente con respecto al tamaño completo de la ventana gráfica, pero no necesita Para hacer eso. El texto se va a "flexionar" con el contenedor porque el contenedor se flexiona con el cambio de tamaño de la ventana gráfica. ACTUALIZAR: aquí hay un ejemplo de dos contenedores de diferentes tamaños.

ejemplo 2

Puede ayudar a garantizar el tamaño de la ventana gráfica forzando el cálculo basado en eso. Considere este ejemplo:

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;
}

El tamaño todavía se basa en la ventana gráfica, pero en esencia se configura en función del tamaño del contenedor en sí.

Si el tamaño del contenedor cambia dinámicamente...

Si el tamaño del elemento contenedor terminó cambiando dinámicamente su relación porcentual ya sea a través de @media puntos de interrupción o a través de JavaScript, cualquiera que sea el "objetivo" base necesitará un nuevo cálculo para mantener la misma "relación" para el tamaño del texto.

Tome el ejemplo #1 arriba. Si el div fue cambiado a 25% ancho por cualquiera @media o JavaScript, entonces al mismo tiempo, el font-size necesitaría ajustarse en la consulta de medios o por JavaScript al nuevo cálculo de 5vw * .25 = 1.25. Esto pondría el tamaño del texto en el mismo tamaño que habría tenido si tuviera el "ancho" del original 50% El contenedor se ha reducido a la mitad del tamaño de la ventana gráfica, pero ahora se ha reducido debido a un cambio en su propio cálculo porcentual.

Un desafío

Con el CSS3 calc() función en uso, sería difícil de ajustar dinámicamente, ya que esa función no funciona para font-size propósitos en este momento. Por lo tanto, no podría hacer un ajuste CSS 3 puro si su ancho está cambiando calc(). Por supuesto, un pequeño ajuste de ancho para los márgenes puede no ser suficiente para justificar cualquier cambio en font-size, así que puede que no importe.

Respondido el 20 de junio de 20 a las 10:06

Gran respuesta, sin embargo, no funcionará si el elemento contenedor tiene un ancho máximo. - Himmators

Solución con SVG:

.resizeme {
  resize: both;
  margin: 0;
  padding: 0;
  height: 75px;
  width: 500px;
  background-color: lightblue;
  overflow: hidden;
}
<div class="resizeme">
  <svg
    width="100%"
    height="100%"
    viewBox="0 0 500 75"
    preserveAspectRatio="xMinYMid meet"
    style="background-color:green"
    xmlns="http://www.w3.org/2000/svg"
    xmlns:xlink="http://www.w3.org/1999/xlink"
  >
        <text
          x="0"
          y="75"
          font-size="75"
          fill="black"
        >█Resize This█</text>
      </svg>
</div>

Solución con SVG y text-wrapping usando foreignObject:

.resizeme {
  resize: both;
  margin: 0;
  padding: 0;
  height: 200px;
  width: 500px;
  background-color: lightblue;
  overflow: hidden;
}
<div class="resizeme">
  <svg
    width="100%"
    height="100%"
    viewBox="0 0 500 200"
    preserveAspectRatio="xMinYMin meet"
  >
      <foreignObject width="100%" height="100%" xmlns="http://www.w3.org/1999/xhtml">
        <div xmlns="http://www.w3.org/1999/xhtml" style="background-color:lightgreen;">
          <h1>heading</h1>
          <p>Resize the blue box.</p>
        </div>
      </foreignObject>
    </svg>
</div>

Respondido el 13 de junio de 20 a las 12:06

salvavidas!!!! - Ismael Sherif

No estoy seguro de por qué, pero esto simplemente no funciona. El fragmento aquí funciona, pero al transferir este otro uso, el texto simplemente desborda el contenedor SVG sin cambiar el tamaño. - douglas gaskell

esto es as, el foreignObject la configuración es perfecta para cambiar el tamaño de algunos textos (e íconos, etc.) según el ancho del contenedor. tenga en cuenta que tuve un problema extraño en iOS donde al aplicar opacity eso no fue 1 (100%) estaba rompiendo el cambio de tamaño por completo, parece opacity debe colocar el estilo en su propia capa de procesamiento, lo que hace que se rompa el cambio de tamaño. la eliminación de la opacity y poner eso en el padre o usar diferentes estilos (color cambiar en su lugar) solucionó este problema. - Fredrivett

Salvavidas para mí también - H294

En uno de mis proyectos utilizo una "mezcla" entre vw y vh para ajustar el tamaño de fuente a mis necesidades, por ejemplo:

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

Sé que esto no responde a la pregunta del OP, pero tal vez pueda ser una solución para cualquier otra persona.

Respondido 31 ago 19, 00:08

¡Esto es lo que yo llamo una solución elegante! - GRGodoi

Solución de CSS puro con calc(), unidades CSS y matemáticas

Esto no es precisamente lo que pide OP, pero puede alegrarle el día a alguien. Esta respuesta no es fácil de alimentar con cuchara y necesita algo de investigación por parte del desarrollador.

Finalmente llegué a obtener una solución de CSS puro para esto usando calc() con diferentes unidades. Necesitará algunos conocimientos matemáticos básicos de fórmulas para calcular su expresión para calc().

Cuando resolví esto, tuve que obtener un encabezado receptivo de ancho de página completo con algunos padres de relleno en DOM. Usaré mis valores aquí, reemplázalos con los tuyos.

a las matemáticas

Necesitarás:

  • Proporción muy bien ajustada en alguna ventana gráfica. Usé 320 píxeles, por lo que obtuve 24 píxeles de alto y 224 píxeles de ancho, por lo que la relación es 9.333... o 28/3
  • El ancho del contenedor, lo tenía padding: 3em y ancho completo, así que esto llegó a 100wv - 2 * 3em

X es el ancho del contenedor, así que reemplácelo con su propia expresión o ajuste el valor para obtener texto de página completa. R es la proporción que tendrá. Puede obtenerlo ajustando los valores en alguna ventana gráfica, inspeccionando el ancho y alto del elemento y reemplazándolos con sus propios valores. Además, es 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

Y ¡bang! ¡Funcionó! escribí

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

a mi encabezado y se ajustó muy bien en cada ventana gráfica.

pero como funciona?

Necesitamos algunas constantes aquí. 100vw significa el ancho completo de la ventana gráfica, y mi objetivo era establecer un encabezado de ancho completo con algo de relleno.

El radio. Obtener un ancho y una altura en una ventana gráfica me dio una proporción con la que jugar, y con la proporción sé cuál debería ser la altura en el ancho de otra ventana gráfica. Calcularlos a mano llevaría mucho tiempo y al menos mucho ancho de banda, por lo que no es una buena respuesta.

Conclusión

Me pregunto por qué nadie se ha dado cuenta de esto y algunas personas incluso dicen que sería imposible jugar con CSS. No me gusta usar JavaScript para ajustar elementos, por lo que no acepto respuestas de JavaScript (y me olvido de jQuery) sin profundizar más. En general, es bueno que esto se haya resuelto y este es un paso hacia las implementaciones de CSS puro en el diseño de sitios web.

Me disculpo por cualquier convención inusual en mi texto, no soy un hablante nativo de inglés y también soy bastante nuevo en escribir respuestas de desbordamiento de pila.

También se debe tener en cuenta que tenemos barras de desplazamiento malvadas en algunos navegadores. Por ejemplo, al usar Firefox noté que 100vw significa el ancho completo de la ventana gráfica, que se extiende debajo de la barra de desplazamiento (¡donde el contenido no se puede expandir!), por lo que el texto de ancho completo debe estar cuidadosamente marginado y, preferiblemente, probarse con muchos navegadores y dispositivos.

Respondido el 15 de Septiembre de 19 a las 09:09

Esta solución funciona solo SI (1) conoce la fuente, (2) la fuente está disponible en el dispositivo de un usuario y (3) el texto es siempre el mismo. Esto lo convierte en un caso de uso muy limitado. - Andrei Volgin

Las barras de desplazamiento no son malas. Personalmente, desprecio los nuevos diseños simplistas de ocultar la barra de desplazamiento hasta que pasa el cursor sobre donde solía estar. Accesibilidad y todo. - bobort

Hay una gran filosofía para este tema.

Lo más fácil sería darle un cierto tamaño de fuente al cuerpo (recomiendo 10), y luego todos los demás elementos tendrían su fuente en em or rem. Te daré un ejemplo para entender esas unidades. Em siempre es relativo a su padre:

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

Rem siempre es relativa al cuerpo:

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

Y luego podría crear una secuencia de comandos que modificaría el tamaño de fuente en relación con el ancho de su contenedor. Pero esto no es lo que recomendaría. Porque en un contenedor de 900 píxeles de ancho, por ejemplo, tendría un p elemento con un tamaño de fuente de 12 píxeles, digamos. Y según su idea, se convertiría en un contenedor de 300 píxeles de ancho con un tamaño de fuente de 4 píxeles. Tiene que haber un límite inferior.

Otras soluciones serían con consultas de medios, de modo que pueda configurar la fuente para diferentes anchos.

Pero la solución que recomendaría es usar una biblioteca de JavaScript que te ayude con eso. Y fittext.js que encontré hasta ahora.

Respondido 31 ago 19, 00:08

Aquí está la función:

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

Luego, convierta todos los tamaños de fuente de los elementos secundarios de sus documentos a em's o %.

Luego agregue algo como esto a su código para establecer el tamaño de fuente base.

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

http://jsfiddle.net/0tpvccjt/

Respondido 31 ago 19, 00:08

Hay una forma de hacer esto sin ¡JavaScript!

Puede usar una imagen SVG en línea. Puede usar CSS en un SVG si está en línea. Debe recordar que el uso de este método significa que su imagen SVG responderá al tamaño de su contenedor.

Intenta usar la siguiente solución...

HTML

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

CO

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;
}

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

¿Quieres algo más llamativo?

Las imágenes SVG también te permiten hacer cosas geniales con formas y basura. Echa un vistazo a este gran caso de uso de texto escalable...

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

Respondido 31 ago 19, 01:08

Esta es la mejor solución para mí porque maneja la relación de tamaño entre el tamaño de fuente y el SVG real. - Elron

Esto puede no ser muy práctico, pero si desea que una fuente sea una función directa del padre, sin tener ningún JavaScript que escuche/repita (intervalo) para leer el tamaño del div/página, hay una manera de hacerlo. . Iframes.

Cualquier cosa dentro del iframe considerará el tamaño del iframe como el tamaño de la ventana gráfica. Entonces, el truco es simplemente hacer un iframe cuyo ancho sea el ancho máximo que desea que tenga su texto, y cuya altura sea igual a la altura máxima * la relación de aspecto del texto en particular.

Dejando a un lado la limitación de que las unidades de ventana gráfica no pueden venir junto con las unidades principales laterales para el texto (como en el caso de que el % del tamaño se comporte como todos los demás), las unidades de ventana gráfica proporcionan una herramienta muy poderosa: poder obtener la dimensión mínima/máxima . No puede hacer eso en ningún otro lugar, no puede decir ... hacer que la altura de este div sea el ancho del padre * algo.

Dicho esto, el truco consiste en usar vmin y establecer el tamaño del iframe de modo que [fracción] * altura total sea un buen tamaño de fuente cuando la altura es la dimensión límite, y [fracción] * ancho total cuando el ancho es el dimensión limitante. Es por eso que la altura tiene que ser un producto del ancho y la relación de aspecto.

Para mi ejemplo particular, tienes

.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);
}

La pequeña molestia con este método es que debe configurar manualmente el CSS del iframe. Si adjunta todo el archivo CSS, ocuparía mucho ancho de banda para muchas áreas de texto. Entonces, lo que hago es adjuntar la regla que quiero directamente desde mi CSS.

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

Puede escribir una pequeña función que obtenga la regla CSS/todas las reglas CSS que afectarían el área de texto.

No puedo pensar en otra forma de hacerlo sin tener algo de JavaScript de ciclismo/escucha. La solución real sería que los navegadores proporcionaran una forma de escalar el texto como una función del contenedor principal. y para proporcionar también la misma funcionalidad de tipo vmin/vmax.

JSFiddle: https://jsfiddle.net/0jr7rrgm/3/ (haga clic una vez para bloquear el cuadrado rojo en el mouse y haga clic nuevamente para liberarlo)

La mayor parte del JavaScript en el violín es solo mi función personalizada de hacer clic y arrastrar.

Respondido 31 ago 19, 00:08

Usar vw, em y compañía funciona con seguridad, pero en mi opinión, siempre necesita un toque humano para el ajuste fino.

Aquí hay un guión que acabo de escribir basado en @tnt-rox' https://www.youtube.com/watch?v=xB-eutXNUMXJtA&feature=youtu.be que trata de automatizar el toque de ese humano:

$('#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>

Básicamente reduce el tamaño de fuente a 1em y luego comienza a incrementarse en 0.1 hasta que alcanza el ancho máximo.

JSFiddle

Respondido 31 ago 19, 01:08

Artísticamente, si necesita colocar dos o más líneas de texto dentro del mismo ancho, independientemente de la cantidad de caracteres, entonces tiene buenas opciones.

Es mejor encontrar una solución dinámica para que cualquier texto que se ingrese termine con una buena visualización.

Veamos cómo podemos acercarnos.

var els     = document.querySelectorAll(".divtext"),
refWidth    = els[0].clientWidth,
refFontSize = parseFloat(window.getComputedStyle(els[0],null)
                               .getPropertyValue("font-size"));

els.forEach((el,i) => el.style.fontSize = refFontSize * refWidth / els[i].clientWidth + "px")
#container {
  display: inline-block;
  background-color: black;
  padding: 0.6vw 1.2vw;
}
.divtext {
  display: table;
  color: white;
  font-family: impact;
  font-size: 4.5vw;
}
<div id="container">
  <div class="divtext">THIS IS JUST AN</div>
  <div class="divtext">EXAMPLE</div>
  <div class="divtext">TO SHOW YOU WHAT</div>
  <div class="divtext">YOU WANT</div>
</div>

Todo lo que hacemos es obtener el ancho (els[0].clientWidth) y el tamaño de fuente (parseFloat(window.getComputedStyle(els[0],null).getPropertyValue("font-size"))) de la primera línea como referencia y luego simplemente calcule el tamaño de fuente de las líneas subsiguientes en consecuencia.

Respondido 10 Feb 20, 19:02

Usar variables CSS

Nadie ha mencionado las variables CSS todavía, y este enfoque funcionó mejor para mí, así que:

Supongamos que tiene una columna en su página que tiene el 100% del ancho de la pantalla de un usuario móvil, pero tiene un max-width de 800 px, por lo que en el escritorio hay algo de espacio a ambos lados de la columna. Pon esto en la parte superior de tu página:

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

Y ahora puede usar esa variable (en lugar de la incorporada vw unidad) para establecer el tamaño de la fuente. P.ej

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

No es un puro Enfoque CSS, pero está bastante cerca.

Respondido 09 Oct 18, 11:10

Esta es realmente una gran solución si necesita manipularla desde js, ¡gracias! - Mladen Mihajlovic

Es bastante bueno, pero no creo que funcione de manera receptiva, setProperty solo se ejecutará una vez, ¿verdad? - bjornw

@BjornW Simplemente podría ponerlo en un oyente. Por ejemplo, un oyente cuando la página cambia de tamaño. - Luke Skywalker

El 100 % es relativo al tamaño de fuente base que, si no lo ha configurado, sería el valor predeterminado del agente de usuario del navegador.

Para obtener el efecto que busca, usaría un código JavaScript para ajustar el tamaño de fuente base en relación con las dimensiones de la ventana.

Respondido 31 ago 19, 00:08

Preparé una función de escala simple usando la transformación CSS en lugar del tamaño de fuente. Puede usarlo dentro de cualquier contenedor, no tiene que configurar consultas de medios, etc. :)

Entrada en el blog: Encabezado escalable CSS y JS de ancho completo

El código:

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';
  }
}

Demostración de trabajo: https://codepen.io/maciejkorsan/pen/BWLryj

Respondido 31 ago 19, 00:08

Creo que OP está buscando una solución CSS. - m02ph3u5

Este componente web cambia el tamaño de fuente para que el ancho del texto interno coincida con el ancho del contenedor. Comprobar el manifestación.

Puedes usarlo así:

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

Respondido 30 Oct 16, 14:10

Intente http://simplefocus.com/flowtype/. Esto es lo que uso para mis sitios, y ha funcionado perfectamente.

Respondido 31 ago 19, 00:08

Puede que estés buscando algo como esto:

http://jsfiddle.net/sijav/dGsC9/4/
http://fiddle.jshell.net/sijav/dGsC9/4/show/

He utilizado tipo de flujo, y funciona muy bien (sin embargo, es JavaScript y no una solución CSS pura):

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

Respondido 31 ago 19, 00:08

Mi propia solución, basada en jQuery, funciona aumentando gradualmente el tamaño de la fuente hasta que el contenedor aumenta mucho de altura (lo que significa que tiene un salto de línea).

Es bastante simple, pero funciona bastante bien y es muy fácil de usar. no tienes que saber cualquier cosa sobre la fuente que se utiliza, el navegador se encarga de todo.

Puedes jugar con eso http://jsfiddle.net/tubededentifrice/u5y15d0L/2/

La magia sucede aquí:

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 (i.e. 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;
};

Respondido 31 ago 19, 00:08

Estaba muy frustrado al tratar de lograr un ajuste de texto ajustado, así que terminé usando un método basado en lienzo al que llegué al intentar sin éxito otros métodos. Lo que buscaba se parece al adjunto, que resulta ser sorprendentemente difícil (para mí). Con suerte, algún día tendremos una forma simple de hacer esto solo con CSS. Las desventajas de este enfoque son que el texto se trata más como una imagen, pero para algunos casos de uso está bien.

https://codesandbox.io/s/create-a-canvas-tightly-holding-a-word-st2h1?file=/index.html

Esta imagen es una captura de pantalla de un diseño de cuadrícula CSS de cuatro lienzos de sangrado completo.

enter image description here

Respondido 04 ago 20, 16:08

No es realmente una respuesta, sino un sentimiento que comparto. - Yuri

A veces, el texto solo necesita ajustarse al espacio dado. Como en el mundo real, el nombre de la tienda debe colocarse lo más grande posible en la tienda. No nombrar la tienda de acuerdo con las fuentes/tamaños de fuente disponibles y el ancho de la tienda. - Yuri

Solo quiero comentar que aprecio tu sentido de la dirección de arte. Colores, opciones tipográficas, yuxtaposición... fantástico. - wle8300

Dentro de su CSS, intente agregar esto en la parte inferior cambiando el ancho de 320 píxeles para donde su diseño comience a romperse:

@media only screen and (max-width: 320px) {
  body { font-size: 1em; }
}

Luego proporcione el tamaño de fuente en "px" o "em" como desee.

Respondido 20 ago 21, 11:08

Mi problema era similar, pero relacionado con la escala de texto dentro de un encabezado. Probé Fit Font, pero necesitaba cambiar el compresor para obtener resultados, ya que estaba resolviendo un problema ligeramente diferente, al igual que Text Flow.

Así que escribí mi propio pequeño complemento que redujo el tamaño de la fuente para que se ajuste al contenedor, suponiendo que tenga overflow: hidden y white-space: nowrap de modo que aunque reducir la fuente al mínimo no permite mostrar el encabezado completo, solo corta lo que puede mostrar.

(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);

Respondido 31 ago 19, 00:08

Intenta usar el ajusteTexto complemento, porque los tamaños de Viewport no son la solución de este problema.

Simplemente agregue la biblioteca:

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

Y cambie el tamaño de fuente para corregirlo configurando el coeficiente de texto:

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

Puede establecer valores máximos y mínimos de texto:

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

Respondido 31 ago 19, 01:08

Siempre ten tu elementos con este atributo:

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

or

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

Cuando vaya a pantalla completa, ya debería tener un escala variable calculada (escala > 1 o escala = 1). Luego, en pantalla completa:

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

Funciona muy bien con poco código.

Respondido 31 ago 19, 00:08

Echa un vistazo a mi código. hace que el font size smaller a fit lo que sea allí.

Pero creo que esto no conduce a una buena experiencia de usuario.

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

items.each(function(){
    // Displaying a value depends 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);
    }
});

Resultado

Respondido 31 ago 19, 00:08

Para texto dinámico, este complemento es bastante útil:

http://freqdec.github.io/slabText/

Simplemente agregue 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;
}

Y el guión:

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

Respondido 31 ago 19, 01:08

Esto funcionó para mí:

Trato de aproximar el tamaño de la fuente en función del ancho/alto obtenido al configurar `font-size: 10px`. Básicamente, la idea es "si tengo 20 píxeles de ancho y 11 píxeles de alto con `font-size: 10px`, ¿cuál sería el tamaño de fuente máximo para calcular un contenedor de 50 píxeles de ancho y 30 píxeles de alto?"

La respuesta es un sistema de doble proporción:

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

Ahora X es un tamaño de fuente que coincidirá con el ancho, e Y es un tamaño de fuente que coincidirá con la altura; tomar el valor más pequeño

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 JavaScript does
    // if the real measure had been 12.49 px => JavaScript 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: el argumento de la función debe ser un elemento de intervalo o un elemento que sea más pequeño que su padre; de ​​lo contrario, si los hijos y el padre tienen el mismo ancho/alto, la función fallará.

Respondido 31 ago 19, 01:08

HTML

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

Código JavaScript para maximizar el tamaño de fuente:

var fontSize, maxHeight, maxWidth, textElement, parentElement;
textElement = document.getElementById('qwe');
parentElement = textElement.parentElement;    
maxHeight = parentElement.clientHeight;
maxWidth = parentElement.clientWidth;
fontSize = maxHeight;
var minFS = 3, maxFS = fontSize;
while (fontSize != minFS) {
  textElement.style.fontSize = `${fontSize}px`;
  if (textElement.offsetHeight < maxHeight && textElement.offsetWidth <= maxWidth) {
    minFS = fontSize;
  } else{
    maxFS = fontSize;
  }
  fontSize = Math.floor((minFS + maxFS)/2);
}
textElement.style.fontSize = `${minFS}px`;

Respondido el 20 de junio de 20 a las 10:06

Como respaldo de JavaScript (o su única solución), puede usar mi Complemento jQuery Scalem, que le permite escalar en relación con el elemento principal (contenedor) pasando el reference .

Respondido el 05 de enero de 17 a las 07:01

En caso de que sea útil para alguien, la mayoría de las soluciones en este hilo estaban envolviendo el texto en varias líneas, forma e.

Pero luego encontré esto, y funcionó:

https://github.com/chunksnbits/jquery-quickfit

Ejemplo de uso:

$('.someText').quickfit({max:50,tolerance:.4})

Respondido el 14 de junio de 17 a las 07:06

Para hacer que el tamaño de la fuente se ajuste a su contenedor, en lugar de a la ventana, consulte la resizeFont() función que he compartido en esta pregunta (una combinación de otras respuestas, la mayoría de las cuales ya están vinculadas aquí). Se activa utilizando window.addEventListener('resize', resizeFont);.

Vanilla JavaScript: cambia el tamaño de la fuente: increíble para que se ajuste al contenedor

JavaScript:

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 + '%';
    }
  }
}

Tal vez podría usar vw/vh como respaldo, por lo que asigna dinámicamente em or rem unidades usando JavaScript, asegurando que las fuentes se escalan a la ventana si JavaScript está deshabilitado.

Aplique la .resize class a todos los elementos que contienen texto que desea escalar.

Active la función antes de agregar el detector de eventos de cambio de tamaño de ventana. Luego, cualquier texto que no se ajuste a su contenedor se reducirá cuando se cargue la página, así como cuando se cambie el tamaño.

NOTA: El valor predeterminado font-size debe establecerse en cualquiera em,rem or % para lograr resultados adecuados.

Respondido 31 ago 19, 01:08

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.