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

Tamaño intrínseco frente a extrínseco

La distinción que estructura todo el dimensionado en CSS: si el tamaño de una caja viene de lo que contiene o de lo que la contiene, y por qué width auto significa dos cosas opuestas según el contexto.

⏱ 18 min

Toda caja de CSS obtiene su tamaño de una de dos fuentes: de fuera, mirando a su contenedor, o de dentro, mirando a su contenido. La especificación CSS Sizing 3 llama a lo primero extrínseco y a lo segundo intrínseco, y ese par de palabras organiza un territorio que sin ellas parece un montón de casos especiales. La prueba de que la distinción es real es que la misma declaración, width: auto, produce comportamientos opuestos según de qué lado caiga la caja.

🎯 Al terminar esta lección sabrás
  • Definir tamaño intrínseco y extrínseco y clasificar cualquier valor de width.
  • Explicar por qué width: auto rellena en un bloque y encoge en un flotante.
  • Describir el algoritmo de ajuste al contenido y dónde se aplica.
  • Predecir el tamaño de una caja sabiendo solo su contexto y su valor de width.

Dos fuentes de verdad

Un tamaño extrínseco se calcula sin mirar el contenido. inline-size: 300px es extrínseco. inline-size: 50% es extrínseco: mide contra el bloque contenedor. inline-size: auto en un bloque en flujo normal es extrínseco, porque lo que hace es rellenar el espacio disponible y ese espacio lo define el contenedor.

Un tamaño intrínseco se calcula midiendo el contenido y descartando el contenedor. inline-size: max-content es intrínseco. inline-size: min-content es intrínseco. inline-size: auto en un flotante o en un inline-block es intrínseco, porque ahí auto significa ajustarse al contenido.

La asimetría de auto no es un capricho: es que auto nunca ha significado un tamaño, significa “el valor que corresponda por el algoritmo de este contexto”. En flujo normal el algoritmo reparte el ancho disponible; en un flotante el algoritmo ajusta al contenido; en un elemento flex el algoritmo mira a flex-basis; en un elemento grid el algoritmo mira a la pista.

/* Extrínseco: ocupa todo el ancho del contenedor, mida lo que mida el texto */
.a { display: block; inline-size: auto; }

/* Intrínseco: se encoge hasta el texto */
.b { float: inline-start; inline-size: auto; }

/* Intrínseco explícito, sin depender del contexto */
.c { inline-size: max-content; }
📝
Los ejes no son simétricos

En el eje en línea, auto suele ser extrínseco. En el eje de bloque, auto es casi siempre intrínseco: la altura de un bloque sale de sus hijos. Esa asimetría es histórica y profunda —el ancho lo impone el papel y el alto lo impone el texto— y es la razón de que block-size: 100% sea problemático y inline-size: 100% sea trivial.

El ajuste al contenido

Cuando auto cae del lado intrínseco, el motor aplica el algoritmo de ajuste al contenido, el shrink-to-fit de CSS 2.1. Su fórmula es exactamente esta:

resultado = min( max( min-content, disponible ), max-content )

En castellano: coge el ancho disponible, no bajes nunca del ancho mínimo del contenido y no subas nunca del ancho máximo del contenido. El resultado es una caja que se encoge hasta el contenido pero que jamás lo parte más de lo imprescindible ni se estira más de lo que el contenido necesita.

Ese algoritmo se aplica en cinco sitios, y conocerlos ahorra mucho tiempo: en los flotantes, en los elementos con position: absolute o fixed sin inset opuestos fijados, en los inline-block, en las celdas de tabla con table-layout: auto, y en los contenedores flex e inline-flex respecto a su tamaño propio.

Todos ellos comparten algo: son cajas que la especificación no puede dimensionar mirando al contenedor, porque el contenedor no les ha reservado una franja de ancho. Un flotante convive con texto que lo rodea; un absoluto no ocupa espacio en el flujo. Sin franja reservada, la única referencia posible es el contenido.

Las palabras clave hacen explícito lo implícito

CSS Sizing 3 sacó ese algoritmo de la sombra y lo convirtió en tres palabras clave que puedes escribir en cualquier sitio: min-content, max-content y fit-content. Con ellas, el ajuste al contenido deja de ser un efecto colateral de flotar y pasa a ser una decisión de diseño.

/* Un título que ocupa exactamente lo que ocupa su texto, sin flotar nada */
.titulo { inline-size: max-content; }

/* Un contenedor que se ajusta al contenido pero no desborda el padre */
.caja { inline-size: fit-content; }

/* Una columna que se estrecha hasta la palabra más larga */
.etiqueta { inline-size: min-content; }

El valor práctico de esto es enorme. Antes de estas palabras clave, para tener una caja ajustada al contenido tenías que aceptar un efecto secundario: flotarla, hacerla inline-block con sus espacios en blanco, o sacarla del flujo. Ahora pides el tamaño que quieres sin cambiar de contexto de formato, sin cambiar el tipo de participación de la caja y sin heredar ningún comportamiento parásito. Es exactamente el mismo movimiento que display: flow-root hizo con el aislamiento.

Cuándo cada uno

La regla operativa es corta. Si el tamaño de la caja lo determina una decisión de diseño —una barra lateral de 20rem, un contenedor de 65 caracteres— usa un valor extrínseco. Si lo determina el contenido —una etiqueta, una pastilla, un botón, una celda— usa un valor intrínseco.

El error caro es el contrario: fijar extrínsecamente algo que debería ser intrínseco. Un botón con inline-size: 120px se rompe en cuanto lo traduces al alemán. Una pastilla con inline-size: 5rem se rompe con dos palabras. Los layouts que sobreviven a un cambio de idioma, a un font-size mayor por accesibilidad o a un dato de longitud inesperada son los que dejan que el contenido hable donde el contenido manda.

/* Frágil: el texto largo desborda o se corta */
.boton { inline-size: 120px; }

/* Robusto: se ajusta al texto, con un mínimo por ergonomía táctil */
.boton {
  inline-size: fit-content;
  min-inline-size: 3rem;
  padding-inline: 1rem;
}
El dimensionado intrínseco es la única defensa real contra el contenido que no controlas

Hay una diferencia estructural entre un layout que aguanta y uno que se rompe, y no está en la técnica que uses sino en dónde has puesto la autoridad sobre el tamaño. Cada vez que escribes un número, estás afirmando que conoces el contenido futuro: su idioma, su longitud, su tipografía, el tamaño de letra que el usuario ha configurado en su sistema. Casi siempre esa afirmación es falsa, y el momento en que se demuestra falsa suele ser meses después, en producción, con un nombre polaco de veintitrés letras o con un usuario que tiene el zoom al 200%. El dimensionado intrínseco es la forma que tiene CSS de dejarte declarar tu ignorancia de manera productiva: no sé cuánto medirá esto, pero sé que debe medir lo que necesite, ni más ni menos. Y hay algo más profundo todavía: los tamaños intrínsecos son la razón de que CSS pueda ser un lenguaje declarativo de verdad. Si tuvieras que expresar todo tamaño en números, estarías escribiendo un programa imperativo con sintaxis de hoja de estilos, y necesitarías JavaScript para medir el contenido y recalcular. Cada max-content que escribes es una restricción que delegas en el motor, que la resuelve mejor que tú porque tiene el contenido delante y tú solo tenías una suposición.