Líneas de texto de igual ancho

Los bloques de texto tipo póster, en los que cada línea se escala para abarcar todo el ancho del contenedor, pueden crear encabezados visualmente llamativos. Con text-fit, el navegador escala cada línea durante el diseño, por lo que se mantiene correcta cuando se cambia el tamaño, se modifica el texto y se carga la fuente.

Para una sola línea que llena su contenedor (p. ej., un encabezado o una cita destacada), aplica text-fit directamente a ese elemento. Esta guía abarca los bloques de varias líneas.

Implementación básica

Para las líneas forzadas:

  • Une cada línea en un <span> con display: block.
  • Aplica white-space: nowrap a cada línea forzada <span>.

Lineamientos de implementación:

  • Usa text-fit: grow per-line-all <percentage> en el encabezado.
  • Usa per-line-all, no per-line. per-line omite la última línea y cualquier línea que termine en un salto forzado, por lo que, con un bloque por línea, no escala nada.
  • grow no se puede combinar con shrink. Establece el font-size base en un máximo o un mínimo según lo que sea un mejor resguardo o más fácil de calcular, y establece text-fit en shrink o grow según corresponda. Si no tienes un motivo para usar shrink, prefiere grow y establece font-size en un valor mínimo, ya que es más seguro en la mayoría de los casos.
  • Siempre limita el crecimiento o la reducción con el porcentaje (p.ej., 300%) como un parámetro de seguridad.
  • El contenedor necesita un tamaño intercalado definido. text-fit nunca cambia el tamaño intrínseco, por lo que no hace nada en los anchos fit-content/max-content ni en los elementos de flexbox o cuadrícula con tamaño de contenido.
  • Recorta el interlineado por encima de la primera línea y por debajo de la última (consulta Alineación precisa del texto).
  • Mantén line-height pequeño, 1 o menos; de lo contrario, los espacios entre las líneas de diferentes tamaños de fuente se vuelven difíciles de manejar.
  • IMPORTANTE: Ten en cuenta que el font-size calculado no cambia, por lo que el espaciado de em no se escala.
  • Para evitar que se enfaticen demasiado las líneas huérfanas por accidente, aplica text-wrap: balance o text-wrap: pretty si hay líneas libres.

Espaciado

Si se fuerza el ajuste de todas las líneas, se produce un mayor control sobre el espaciado:

  • Aplica text-box: trim-both cap alphabetic a cada bloque de línea para que su cuadro se ajuste a sus propios glifos. Recorta con las métricas ajustadas. Consulta Alineación precisa del texto para obtener más detalles.
  • Separa las líneas con Flexbox o Grid + gap en el encabezado, no con line-height. De esta manera, los espacios son uniformes en lugar de aumentar con el tamaño de la fuente de cada línea.

Si algunas líneas están libres, no uses text-box: solo recorta la primera y la última línea, por lo que las líneas exteriores se ajustarán a los glifos, mientras que los espacios interiores mantendrán su interlineado. Permite que line-height controle todo el espaciado.

Diseño visual

  • Los bloques se ven mejor cuando hay una variación significativa en los tamaños de fuente entre las líneas. Evita crear composiciones a partir de texto con líneas mayormente uniformes, ya que esto dará como resultado tamaños de fuente que no son iguales ni lo suficientemente diferentes, lo que infringe el principio de diseño de contraste. Para garantizar esto, fuerza líneas cortas: ajusta las palabras que quieras enfatizar en un bloque y deja que el resto se ajuste, es decir, un diseño mixto. Esto es especialmente importante cuando se combina con text-wrap: balance.
  • Se recomienda combinar esto con text-transform: uppercase cuando se usa con alfabetos occidentales, ya que las astas ascendentes y descendentes tienden a crear espacios atrapados o superponer líneas adyacentes, lo que genera un resultado menos agradable desde el punto de vista estético.
  • Cuando fuerces líneas cortas, elige palabras que mejoren el mensaje si se enfatizan.
  • Limitación: El texto que crece también aumentará de peso visual y sus trazos se percibirán como más fuertes. Actualmente, no hay forma de contrarrestar esto, p.ej., reduciendo el font-weight para el texto más grande, ya que no hay una unidad para usar en un cálculo, ya que el escalamiento no afecta a las unidades relativas a la fuente, como em.

Estrategias de resguardo

Para text-box

text-box no necesita un resguardo independiente: mantén el line-height pequeño también en los diseños fijos. Es una operación no-op en text-box y mantiene los espacios reducidos donde no se admite, a costa de los espacios que se escalan con el tamaño de fuente de cada línea.

Para text-wrap: balance

Para text-fit

Las líneas forzadas tienen un resguardo breve y fiel: mide cada línea en su tamaño base y escálala según la proporción con el contenedor, con el mismo límite.

@supports not (text-fit: grow) {
  .lockup > span {
    /* Shrink-wrap each line so its width is the text width */
    width: fit-content;
    /* --text-fit-scale is measured by the script; the cap mirrors the text-fit percentage */
    font-size: min(var(--text-fit-scale, 1) * 1em, 300%);
  }
}
if (!CSS.supports('text-fit', 'grow per-line-all')) {
  const fit = lockup => {
    const lines = [...lockup.querySelectorAll(':scope > span')];
    // Unscale first: on a refit, offsetWidth would otherwise include the previous scale
    for (const line of lines) line.style.removeProperty('--text-fit-scale');
    // MANDATORY: all reads, then all writes. Interleaving them (e.g. reading
    // lockup.clientWidth inside the write loop) forces one reflow per line.
    const scales = lines.map(line => lockup.clientWidth / line.offsetWidth);
    lines.forEach((line, i) => line.style.setProperty('--text-fit-scale', scales[i]));
  };
  // Refit on resize and font load
  for (const lockup of document.querySelectorAll('.lockup')) {
    new ResizeObserver(() => fit(lockup)).observe(lockup);
  }
}

Las líneas libres no tienen un resguardo fiel (los saltos de línea se desconocen hasta el diseño): mejora progresiva a un encabezado equilibrado con un tamaño de base fluido, como clamp(2rem, 1rem + 5cqi, 5rem). En un diseño mixto, la secuencia de comandos anterior aún se ajusta a las líneas forzadas; un bloque de ajuste mide tanto como el contenedor, por lo que mantiene la escala 1 y solo obtiene el tamaño de base fluido.

Si el ajuste de texto es fundamental, considera usar una biblioteca de JS (p.ej., fitty), que se cargue de forma condicional solo si no se admite text-fit.