El inspector de flex y el reparto del espacio
El overlay de flexbox, los editores visuales de alineación, y cómo diagnosticar por qué un elemento no crece, no encoge o no se alinea donde esperas.
Flexbox tiene menos estructura visible que grid pero más aritmética invisible: cada elemento tiene una base, un factor de crecimiento y uno de encogimiento, y el resultado final es el reparto de un espacio sobrante o faltante entre todos ellos según esos factores. Cuando un elemento no queda donde debería, la causa está casi siempre en esa aritmética y no en la alineación, que es donde todo el mundo mira primero.
- Activar el overlay de flex y leer las guías de alineación y de distribución.
- Usar los editores visuales de alineación en lugar de recordar la semántica de cada valor.
- Diagnosticar por qué un elemento flexible no crece o no encoge como esperas.
- Distinguir un problema de alineación de uno de dimensionado.
El overlay de flex y qué dibuja
El distintivo de flex aparece en cualquier contenedor con display: flex o inline-flex, y como con grid, la sección de layout del panel lista todos los contenedores flex de la página con casillas independientes.
El overlay dibuja tres cosas.
El contorno del contenedor, que resuelve la duda de dónde acaba realmente la caja flexible cuando su fondo es transparente.
Las líneas divisorias entre elementos, que muestran los límites de cada caja hija incluidos sus márgenes.
El espacio de gap, con un rayado propio que lo distingue del margen. Igual que en grid, esta distinción visual responde en un segundo a la pregunta de si un espacio viene del contenedor o de un hijo.
Cuando el contenedor tiene flex-wrap activo y el contenido se reparte en varias líneas, el overlay dibuja cada línea por separado, lo que permite ver cuántas líneas hay realmente y dónde se produce el salto. Ese dato es el que explica los layouts que “de repente” cambian de aspecto al reducir el ancho unos pocos píxeles.
Los editores visuales de alineación
En el panel de estilos, las propiedades de alineación de un contenedor flex —justify-content, align-items, align-content— muestran junto a su valor un icono. Al pulsarlo aparece una fila de iconos, uno por valor posible, cada uno dibujando esquemáticamente el resultado.
El valor de esto no es la comodidad de no escribir: es que elimina de raíz la confusión entre ejes, que es el error conceptual más persistente de flexbox. justify-content opera en el eje principal, que es el que marca flex-direction, y align-items en el transversal. Cuando flex-direction es column, los dos intercambian su orientación visual, y esa inversión es lo que hace que la gente pruebe las cuatro combinaciones hasta que una funciona.
Con los iconos, no hay que recordar cuál es cuál: se ve. Y como el panel conoce el flex-direction actual, los iconos se dibujan con la orientación correcta.
Los elementos hijos tienen su propio editor para align-self, con la misma lógica.
La propiedad place-content y sus hermanas place-items y place-self son shorthands que fijan las dos alineaciones a la vez. En el panel se expanden como cualquier otro shorthand, lo cual es útil para ver qué valor implícito están escribiendo en el eje que no te interesaba.
La aritmética del reparto
Aquí está el noventa por ciento de los problemas reales de flexbox, y es donde el overlay ayuda menos y los computados ayudan más.
El shorthand flex fija tres cosas, y el orden importa: flex: <grow> <shrink> <basis>. Los valores por defecto de un elemento flexible son flex: 0 1 auto, es decir, no crece, sí encoge, y su base es su tamaño de contenido.
Los tres valores abreviados que la gente usa significan cosas muy distintas.
flex: 1 equivale a flex: 1 1 0%. La base es cero, no automática. Eso significa que el contenido no cuenta para el reparto y todos los elementos con flex: 1 acaban del mismo tamaño independientemente de lo que contengan.
flex: auto equivale a flex: 1 1 auto. Aquí la base sí es el contenido, así que el espacio sobrante se reparte por igual pero partiendo de tamaños distintos, y los elementos con más contenido acaban más grandes.
flex: none equivale a flex: 0 0 auto. Ni crece ni encoge.
Confundir los dos primeros es la causa de la mitad de los “por qué estas dos columnas no son iguales”. Y el panel de computados lo resuelve: mira flex-basis en cada hijo, y si es 0% en unos y auto en otros ya tienes el diagnóstico.
Por qué un elemento no encoge
El otro clásico. Tienes flex-shrink: 1 —que es el valor por defecto— y aun así el elemento se niega a encoger y desborda el contenedor.
La causa es el tamaño mínimo automático. En el eje principal, un elemento flexible tiene un min-width implícito de auto, que resuelve al tamaño mínimo de su contenido. El motor no encogerá por debajo de eso por mucho flex-shrink que declares.
El contenido que produce mínimos grandes: palabras largas sin oportunidad de corte, imágenes con dimensión intrínseca, elementos anidados con anchos fijos, y tablas.
El arreglo canónico es declarar min-width: 0 en el elemento flexible, o overflow: hidden, que también anula el mínimo automático. En un contenedor de columna, el equivalente es min-height: 0.
La comprobación desde la consola, que responde de golpe para todos los hijos.
// Por que no encogen los hijos de un contenedor flex
console.table(
[...$0.children].map(el => {
const cs = getComputedStyle(el);
return {
elemento: el.tagName + (el.className ? '.' + String(el.className).split(' ')[0] : ''),
basis: cs.flexBasis,
grow: cs.flexGrow,
shrink: cs.flexShrink,
minWidth: cs.minWidth,
anchoReal: Math.round(el.getBoundingClientRect().width)
};
})
);
Con el contenedor flex seleccionado en Elements, esa tabla enseña en una pantalla toda la aritmética del reparto, y el elemento cuyo minWidth sea auto y cuyo ancho real no baje es el culpable.
La regla que se repite en todas partes —flex para una dimensión, grid para dos— es cierta y es inútil, porque casi ningún layout real se deja clasificar así. La distinción que de verdad decide es otra y se nota justo cuando estás delante del inspector: en grid, el contenedor define la estructura y los hijos se colocan en ella; en flex, los hijos negocian el espacio entre sí y el contenedor solo arbitra. De ahí se deriva el criterio práctico. Si necesitas que dos elementos que no son hermanos directos queden alineados —una columna de una tarjeta con la columna de la tarjeta de al lado, un pie de tarjeta a la misma altura en toda una fila— flex no puede, porque cada contenedor flex negocia por su cuenta y no sabe nada de sus vecinos; grid sí puede, y con subgrid puede incluso a través de niveles de anidamiento. Y al revés: si lo que necesitas es que un conjunto de elementos de tamaño desconocido se repartan un espacio y se ajusten unos a otros, grid te obliga a declarar una estructura que no conoces y flex lo hace solo. En el inspector la diferencia se ve con claridad: cuando activas el overlay de grid ves una estructura que existe con independencia de lo que haya dentro; cuando activas el de flex ves una estructura que es el resultado de lo que hay dentro. Si al mirar el overlay piensas “estas líneas deberían estar donde yo diga”, quieres grid. Si piensas “estas líneas deberían estar donde el contenido las ponga”, quieres flex.