Escala de fuente según el tamaño del contenedor

Resuelto Francesca asked hace 11 años • 40 respuestas

Me está costando entender la escala de fuente.

Actualmente tengo un sitio web con un cuerpo font-sizedel 100%. ¿100% de qué? Esto parece calcularse en 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 a un escritorio de pantalla ancha en toda regla.

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

Mi razonamiento es que cosas como mi menú se reducen cuando cambias el tamaño, por lo que necesito reducir, px font-sizeentre .menuItemotros elementos, en relación con el ancho del contenedor. (Por ejemplo, en el menú de un escritorio grande, 22pxfunciona perfectamente. Bajar al ancho de una tableta y 16pxes más apropiado).

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

Francesca avatar Apr 17 '13 16:04 Francesca
Aceptado

Las consultas de contenedores son ahora probablemente la mejor opción, según su caso de uso, y son compatibles con los principales navegadores. Vea el nivel de soporte aquí: https://caniuse.com/mdn-css_properties_container

Ahora es muy fácil de controlar:

.module h2 {
  font-size: 1em;
  container-name: sidebar
}

@container sidebar (min-width: 700px) {
  .module h2 {
    font-size: 2em;
  }
}
Expandir fragmento

Consulte el artículo de MDN sobre consultas de contenedores para obtener más detalles: https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Container_Queries

Más ejemplos de lo que puede lograr: https://css-tricks.com/a-few-times-container-size-queries-would-have-helped-me-out/


Antigua respuesta

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

Si el contenedor es el cuerpo, lo que busca es longitudes de porcentaje de ventana gráfica :

Las longitudes porcentuales de la ventana gráfica son relativas al tamaño del 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 auto, se supone que no existe ninguna barra 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 vwo vh)
  • vmax(el más grande o vwo vh)

1 v* es igual al 1% del bloque contenedor 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 font-size, sin necesidad de utilizar consultas de medios.

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

La compatibilidad con el navegador es bastante buena, pero probablemente necesitarás un respaldo, como por ejemplo:

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

Consulte las estadísticas de soporte: https://caniuse.com/viewport-units .

Además, consulte Trucos de CSS para obtener una visión más amplia: Tipografía del tamaño de una ventana gráfica.

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

Y aquí hay un ejemplo de cómo configurar su tamaño calc()para que el texto llene la ventana gráfica: https://codepen.io/CrocoDillon/pen/wvdrBY

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

2507rkt3 avatar Nov 06 '2013 14:11 2507rkt3

Pero ¿qué pasa si el contenedor no es la ventana gráfica (cuerpo)?

Alex hace esta pregunta en un comentario en la respuesta de 2507rkt3 .

Ese hecho no significa que vwno se pueda utilizar hasta cierto punto el tamaño de ese contenedor. Ahora bien, para ver alguna variación hay que asumir que el contenedor de alguna manera es de tamaño flexible. Ya sea mediante un porcentaje directo widtho mediante un 100% menos márgenes. El punto se vuelve "discutible" si el contenedor siempre está configurado, digamos, 200pxen ancho; luego simplemente configure un font-sizeque funcione para ese ancho.

Ejemplo 1

Sin embargo, con un contenedor de ancho flexible, se debe tener en cuenta que de alguna manera el tamaño del contenedor todavía se está reduciendo fuera de la ventana gráfica . Como tal, se trata de ajustar una vwconfiguración en función de esa diferencia de tamaño porcentual en la ventana gráfica, lo que significa tener en cuenta el tamaño de los contenedores principales. Tome 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í que dives hijo de body, tiene 50%ese 100%ancho, que es el tamaño de la ventana gráfica en este caso básico. Básicamente, desea configurar un diseño vwque le parezca bien. Como puede ver en mi comentario en el contenido CSS anterior, puede "pensar" matemáticamente con respecto al tamaño completo de la ventana gráfica, pero no es necesario que lo haga. El texto se "flexionará" con el contenedor porque el contenedor se flexionará con el cambio de tamaño de la ventana gráfica. A continuación se muestra 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.

¿Debería el tamaño del contenedor cambiar dinámicamente...?

Si el tamaño del elemento contenedor terminó cambiando dinámicamente su relación porcentual, ya sea a través @mediade puntos de interrupción o mediante JavaScript, entonces, cualquiera que fuera el "objetivo" base, sería necesario volver a calcularlo para mantener la misma "relación" para el tamaño del texto.

Tome el ejemplo n.° 1 anterior. Si se divcambió al 25%ancho mediante @mediaJavaScript, al mismo tiempo, font-sizesería necesario ajustarlo en la consulta de medios o mediante JavaScript al nuevo cálculo de 5vw * .25 = 1.25. Esto colocaría el tamaño del texto en el mismo tamaño que habría tenido si el "ancho" del 50%contenedor original se hubiera 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 reto

Con la función CSScalc() en uso, sería difícil realizar ajustes dinámicos, ya que esa función no funciona para font-sizesus propósitos en este momento. Por lo tanto, no podrá realizar un ajuste de CSS puro si su ancho cambia calc(). Por supuesto, un ajuste menor del ancho de los márgenes puede no ser suficiente para justificar ningún cambio en font-size, por lo que puede que no importe.

ScottS avatar Nov 06 '2013 16:11 ScottS

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>
Expandir fragmento

Solución con SVG y ajuste de texto 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>
Expandir fragmento

Dantio avatar Jun 18 '2015 16:06 Dantio