wandres.dev
DIMENSIONAR · Tamaños intrínsecos y extrínsecos

fit-content y stretch: los dos valores compuestos

fit-content como fórmula y como función, stretch frente a 100% cuando hay márgenes de por medio, y por qué estos dos valores cubren el 90% de los casos reales de dimensionado.

⏱ 17 min

min-content y max-content son medidas puras y por eso rara vez son la respuesta directa: una desborda y la otra estrangula. Los dos valores que usarás de verdad son compuestos. fit-content combina las dos medidas intrínsecas con el espacio disponible en una sola fórmula, y stretch resuelve el problema de rellenar el contenedor que 100% nunca resolvió del todo.

🎯 Al terminar esta lección sabrás
  • Expandir la definición de fit-content y predecir su resultado en tres escenarios.
  • Distinguir la palabra clave fit-content de la función fit-content() de grid.
  • Explicar por qué stretch no es lo mismo que inline-size: 100%.
  • Elegir entre los cinco valores de dimensionado según el problema.

fit-content es una fórmula, no una medida

fit-content no mide nada nuevo: combina lo que ya tienes. Su definición formal es exactamente esta:

fit-content = min( max-content, max( min-content, stretch ) )

Léelo de dentro afuera. max(min-content, stretch) significa “coge todo el espacio disponible, pero nunca bajes del mínimo del contenido”. El min(max-content, ...) de fuera significa “y nunca subas por encima de lo que el contenido necesita”. El resultado es la caja que se ajusta al contenido cuando cabe y se comporta como un bloque normal cuando no cabe.

Tres escenarios ilustran los tres tramos de la fórmula:

Si el contenido es corto y el contenedor ancho, gana max-content: la caja se encoge hasta el texto. Si el contenido es largo y el contenedor estrecho, gana stretch: la caja rellena el contenedor y el texto se parte. Si el contenedor es más estrecho que la palabra más larga, gana min-content: la caja desborda lo mínimo imprescindible en vez de partir la palabra.

/* Un aviso que ocupa lo que ocupa su texto, sin pasarse del contenedor */
.aviso {
  inline-size: fit-content;
  padding: 0.75rem 1rem;
  background: #f9e2af;
  color: #11111b;
}

Este es el valor que quieres casi siempre que pienses “que ocupe lo que necesite”. Es lo mismo que hacía el ajuste al contenido de los flotantes, pero sin flotar nada.

💡
fit-content también centra

Con inline-size: fit-content y margin-inline: auto tienes una caja ajustada al contenido y centrada, sin flex, sin grid y sin conocer el ancho. Los dos márgenes automáticos se reparten el espacio sobrante, que existe precisamente porque la caja no lo ocupó todo.

La función fit-content() es otra cosa

Hay una trampa de nomenclatura que cuesta tiempo. Además de la palabra clave, existe la función fit-content(longitud), que solo tiene sentido como tamaño de pista en grid. Su significado es distinto: pone un tope al crecimiento de la pista.

/* La pista crece con el contenido hasta un máximo de 30rem */
.tabla {
  display: grid;
  grid-template-columns: fit-content(30rem) 1fr;
}

Formalmente, fit-content(L) equivale a minmax(auto, max-content) recortado por L: la pista mide lo que el contenido pida, pero nunca más de L. La palabra clave sin argumento, en cambio, usa el espacio disponible como tope. Son parientes, no sinónimos, y usar una donde toca la otra da errores de sintaxis o resultados desconcertantes.

stretch frente al eterno 100%

inline-size: 100% tiene un problema conocido: el porcentaje se resuelve contra el ancho de contenido del bloque contenedor, y luego los márgenes del hijo se suman por fuera. Si el hijo tiene márgenes laterales, desborda.

/* Desborda su padre en 2rem */
.hijo { inline-size: 100%; margin-inline: 1rem; }

Durante años esto se parcheaba con box-sizing —que no ayuda, porque box-sizing afecta a bordes y rellenos, no a márgenes— o con calc(100% - 2rem), que obliga a repetir el margen en dos sitios y se desincroniza en la primera refactorización.

El valor stretch resuelve el caso correctamente: significa “ocupa todo el espacio disponible en el bloque contenedor después de restar tus propios márgenes”. Es el mismo tamaño que tendría la caja con inline-size: auto en flujo normal, pero disponible como valor explícito para usarlo donde auto significaría otra cosa.

/* Ocupa el ancho del padre menos sus propios márgenes. No desborda. */
.hijo { inline-size: stretch; margin-inline: 1rem; }

Este valor tuvo una historia larga bajo prefijos: -webkit-fill-available y -moz-available hacían aproximadamente lo mismo con diferencias sutiles. La versión estandarizada, stretch, llegó a los motores durante 2025 y 2026. Es el más reciente de los cinco valores de esta lección y el único para el que todavía tiene sentido escribir un respaldo:

.hijo {
  inline-size: -webkit-fill-available;  /* motores antiguos */
  inline-size: stretch;                 /* estándar, gana si se entiende */
  margin-inline: 1rem;
}

La cascada hace el trabajo: un motor que no reconoce stretch descarta la segunda declaración y se queda con la primera.

⚠️
Donde stretch importa de verdad es en el eje de bloque

En el eje en línea, auto ya hace lo que hace stretch para un bloque en flujo normal, así que la ganancia es pequeña. Donde stretch cambia las cosas es en block-size, porque ahí auto es intrínseco y 100% exige que el padre tenga altura definida. block-size: stretch te da la altura del contenedor sin cadenas de height: 100% desde html.

Los cinco valores, elegidos

Con esto tienes el catálogo completo del dimensionado intrínseco y extrínseco. La decisión se toma con una pregunta por valor.

min-content cuando quieres el ancho más estrecho posible: una columna de etiquetas, una barra de iconos, una celda que no debe crecer.

max-content cuando el contenido no debe partirse nunca: una pastilla, una fecha, un botón corto, un encabezado de tabla.

fit-content cuando quieres lo natural: que se ajuste al contenido si cabe y se comporte como un bloque si no cabe. Es el valor por defecto razonable para casi todo componente de tamaño variable.

stretch cuando quieres rellenar el contenedor y hay márgenes de por medio, o cuando estás en el eje de bloque.

Un número o un porcentaje cuando el tamaño es una decisión de diseño y no una consecuencia del contenido. Y ahí lo correcto casi siempre es combinarlos con topes intrínsecos:

/* Una columna de texto legible que nunca se estrangula */
.articulo {
  inline-size: min(65ch, 100%);
  margin-inline: auto;
}
Cada valor de sizing es una restricción, no una orden, y por eso se pueden componer

La razón de que min(), max() y clamp() encajen tan naturalmente con los tamaños intrínsecos es que ambos hablan el mismo idioma: el de las restricciones. fit-content no es un valor especial del motor, es literalmente una restricción compuesta que la especificación escribió por ti, min(max-content, max(min-content, stretch)), y que podrías haber escrito a mano. Esa es la revelación estructural del dimensionado en CSS: no estás asignando tamaños, estás declarando un sistema de desigualdades y dejando que el motor encuentre la solución. min-inline-size es una cota inferior, max-inline-size una cota superior, inline-size una preferencia, y el resultado final es el punto que satisface todas las restricciones simultáneamente. Cuando lo ves así, dejan de sorprenderte cosas que antes parecían arbitrarias: por qué max-inline-size gana siempre a inline-size, por qué min-inline-size gana a max-inline-size cuando entran en conflicto, por qué el orden de aplicación está definido en la especificación en lugar de depender del orden en que escribiste las declaraciones. Y sobre todo te da el hábito correcto: en vez de calcular un número, describe el rango aceptable. Un layout hecho de rangos aguanta contenidos que no habías previsto; uno hecho de números solo aguanta el contenido con el que lo probaste.

⚔️ Los cinco valores en la misma página
  1. Monta una caja con un texto corto y otra con un texto largo, y aplícales los cinco valores por turnos. Anota el resultado de cada combinación.
  2. Reproduce el desbordamiento de inline-size: 100% con margin-inline: 1rem y arréglalo con stretch.
  3. Construye un grid de dos columnas con fit-content(20rem) 1fr y comprueba qué pasa al meter contenido de más de 20rem.
  4. Escribe una caja centrada sin flex ni grid usando fit-content y margin-inline: auto.
  5. Explica por qué inline-size: min(65ch, 100%) es mejor que max-inline-size: 65ch cuando el padre es un elemento flex.