Pregunta Escalado de fuente basado en el ancho del contenedor


Estoy teniendo dificultades para entender la escala de fuentes.

Actualmente tengo este sitio con un cuerpo font-size del 100%. 100% de lo que sin embargo? Esto parece calcular a 16px.

Tenía la impresión de que el 100% de alguna manera se referiría al tamaño de la ventana del navegador, pero aparentemente no porque siempre es de 16px si la ventana se redimensiona a un ancho móvil o a una pantalla panorámica completa.

¿Cómo puedo hacer que el texto en la escala de mi sitio esté relacionado con su contenedor? Intenté usar em pero esto tampoco escala.

Mi razonamiento es que cosas como mi menú se aplastan cuando cambias de tamaño, así que tengo que reducir el px font-size de .menuItem entre otros elementos en relación con el ancho del contenedor. (Por ejemplo, en el menú de un escritorio grande, 22px funciona perfectamente. Baje 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, así como tener puntos de corte adicionales, de lo contrario terminaré con cientos de puntos de corte por cada 100px de disminución de ancho para controlar el texto.


808
2018-04-17 09:37


origen


Respuestas:


EDITAR: si el contenedor no es el cuerpo CSS Tricks cubre todas tus opciones aquí: https://css-tricks.com/fitting-text-to-a-container/

Si el contenedor es el cuerpo, lo que estás buscando es Longitudes de porcentaje de la ventana gráfica:

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

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 más pequeño de vw o vh)
  • vmax (el más grande o vw o vh)

1 v * es igual al 1% del bloque que contiene inicial.

usarlo se ve así:

p {
    font-size: 4vw;
}

Como puede ver, cuando el ancho de la ventana gráfica aumenta, también lo hace el tamaño de fuente, sin la necesidad de utilizar consultas de medios.

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

El soporte del navegador es bastante bueno, pero es probable que necesite un respaldo, como por ejemplo:

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

Verifique 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: http://css-tricks.com/viewport-sized-typography/

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: http://madebymike.com.au/writing/precise-control-responsive-typography/

Y aquí hay un artículo sobre cómo configurar tu 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 "fundición líder" para ajustar también la altura de la línea. https://css-tricks.com/molten-leading-css/


1172
2017-11-06 14:40



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

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

Ese hecho no significa vw no se puede usar hasta cierto punto para el tamaño de ese contenedor. Ahora, para ver cualquier variación, uno debe estar asumiendo que el contenedor de alguna manera es flexible en tamaño. Ya sea a través de un porcentaje directo width o al ser 100% menos márgenes. El punto se convierte en "discutible" si el contenedor siempre está configurado para, digamos, 200px de ancho, luego simplemente configure un font-size eso funciona para ese ancho

Ejemplo 1

Sin embargo, con un contenedor de ancho flexible, se debe tener en cuenta que de alguna manera el contenedor es siendo dimensionado fuera de la ventana gráfica. Como tal, se trata de ajustar un vw configuración basada en la diferencia de porcentaje de tamaño en la ventana gráfica, lo que significa tener en cuenta el tamaño de los contenedores primarios. 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; 
}

Asumiendo aquí el div es un niño de la body, es 50% de eso 100% ancho, que es el tamaño de la vista en este caso básico. Básicamente, quieres establecer un vw eso te va a quedar bien. Como puede ver en mi comentario en el css anterior, puede "pensar" matemáticamente eso con respecto al tamaño completo de la ventana gráfica, pero no lo hace necesitar Para hacer eso. El texto se va a "flexionar" con el contenedor, porque el contenedor se está flexionando 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 en función de eso. Considera 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 200% 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 sigue basándose en la ventana gráfica, pero, en esencia, está configurado en función del tamaño del contenedor.

El tamaño del contenedor debería cambiar dinámicamente ...

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

Tome el ejemplo n. ° 1 arriba. Si el div fue cambiado a 25% ancho por cualquiera @media o javascript, entonces al mismo tiempo, el font-size tendría que ajustar en la consulta de medios o por javascript para el 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 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 de porcentaje.

Un reto

Con el CSS3 calc() función en uso, sería difícil ajustar dinámicamente, ya que esa función no funciona para font-sizepropósitos en este momento. Entonces, no puedes hacer un ajuste puro de CSS3 si tu ancho está cambiando calc(). Por supuesto, un ajuste menor de ancho para los márgenes puede no ser suficiente para garantizar cualquier cambio en font-size, entonces puede no importar


249
2017-11-06 16:56



Lo que hago en uno de mis proyectos es una "mezcla" entre vw y vh para ajustar el tamaño de letra a mis necesidades, por ej .:

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

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


21
2018-03-11 08:30



Hay una gran filosofía para este problema. Lo más fácil sería dar un cierto tamaño de fuente al cuerpo (recomiendo 10), y luego todo el otro elemento tendría su fuente en em o 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*10px = 20px */
.menu li{font-size:1.5em;} /* that means 1.5*20px = 30px */

Rem siempre es relativo al cuerpo

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 */

Y que podría crear una secuencia de comandos que modificaría el tamaño de la fuente en relación con el ancho de su contenedor. Pero esto no es lo que recomendaría. Porque en un contenedor de 900px de ancho, por ejemplo, tendrías p elemento con 12px de tamaño de letra, digamos. Y en su ideea eso se convertiría en un contenedor de 300 px de ancho en un tamaño de fuente de 4 px. Tiene que haber un límite inferior. Otra solución sería con consultas de medios, para que pueda establecer la fuente para diferentes anchos.

Pero las soluciones que recomendaría es usar una biblioteca de JavaScript que lo ayude con eso. Y fittext.js que encontré hasta ahora.


20
2017-11-11 10:01



Solución con 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/


19
2018-06-18 16:47



Actualizado porque obtuve un voto negativo.

Aquí está la función:

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

A continuación, convierta todos los tamaños de fuente de elementos secundarios de sus documentos a em o%.

A continuación, agregue algo como esto a su código para establecer el tamaño de la fuente base.

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

http://jsfiddle.net/0tpvccjt/


18
2018-01-07 09:43



Esto puede no ser muy práctico, pero si quiere que la fuente sea una función directa del padre, sin tener ningún JS que escuche / bucles (intervalo) para leer el tamaño de la página / div, 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 crear un iframe cuyo ancho sea el ancho máximo que desee que tenga su texto, y cuya altura sea igual a la altura máxima * de la relación de aspecto del texto en particular.

Dejando de lado la limitación de que las unidades de visualización también pueden aparecer en unidades secundarias laterales para texto (como si el% del tamaño se comportara como todos los demás), las unidades de vista proporcionan una herramienta muy poderosa: poder obtener la dimensión mínima / máxima . No puedes hacer eso en ningún otro lado, no puedes decir ... haz que la altura de este div sea el ancho del elemento * principal.

Una vez dicho esto, el truco es usar vmin y establecer el tamaño del iframe para que [fraction] * total height tenga un buen tamaño de fuente cuando la altura sea la dimensión límite, y [fraction] * width total cuando el ancho sea el limitando la dimensión Esta es la razón por la que la altura debe 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 tiene que establecer manualmente el CSS del iframe. Si adjuntas todo el archivo CSS, eso requeriría mucho ancho de banda para muchas áreas de texto. Entonces, lo que hago es adjuntar la regla que deseo 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 función pequeña 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 algunos ciclismo / escuchar JS. La verdadera solución sería que los navegadores proporcionaran una forma de escalar el texto como una función del contenedor principal AND para proporcionar también la misma funcionalidad de tipo vmin / vmax.

JS violín: https://jsfiddle.net/0jr7rrgm/3/ (haga clic una vez para bloquear el cuadrado rojo con el mouse, haga clic nuevamente para liberar)

La mayoría de las JS en el violín son solo mi función personalizada de hacer clic y arrastrar


12
2018-04-12 19:22



Solución Pure-CSS con calc(), Unidades de CSS y matemáticas

Esto no es precisamente lo que OP pide, pero puede hacer el día de alguien. Esta respuesta no es nada fácil y necesita algunas investigaciones al final del desarrollador.

Finalmente vine para obtener una solución de CSS puro para esto usando calc() con diferentes unidades. Necesitará una comprensión matemática básica de las fórmulas para calcular su expresión 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 por los tuyos.

Para las matemáticas

Necesitará:

  • muy bien ajustado ratio en alguna ventana gráfica, utilicé 320px, así obtuve 24px de alto y 224px de ancho por lo que la relación es 9.333 ... o 28/3
  • el ancho del contenedor, tuve padding: 3em y ancho completo, así que esto llegó a 100wv - 2 * 3em

X es el ancho del contenedor, entonces 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 el 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 alto en una ventana gráfica me dio una razón para jugar, y con la proporción sé cuál debería ser la altura en el ancho de otra ventana gráfica. Calcularlos con la mano tomaría mucho tiempo y al menos tomaría mucho ancho de banda, por lo que no es una buena respuesta.

Conclusión

Me pregunto por qué nadie ha descubierto esto y algunas personas incluso dicen que esto sería imposible de jugar con CSS. No me gusta usar Javascript para ajustar elementos, por lo que no acepto respuestas JS o incluso jQuery sin tener que profundizar más. En general, es bueno que esto se haya resuelto y este es un paso más 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 hablante nativo en inglés y también soy bastante nuevo para escribir respuestas de SO.

Editar: también se debe tener en cuenta que tenemos barras de desplazamiento malvadas en algunos navegadores. Por ejemplo, cuando uso Firefox noté que 100vw significa el ancho total 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 total debe marcarse cuidadosamente y preferiblemente probarse con muchos navegadores y dispositivos.


12
2017-09-01 10:27



Hay una manera de hacer esto SIN Javascript!

Puedes usar un svg en línea. Puedes usar css en un svg si está en línea. Debes recordar que usar este método significa que tu 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>

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;

}

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

¿Quieres algo más llamativo?

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

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


10
2018-03-13 15:48