Curso de CSS / Grid: repeat, auto-fit, auto-fill y áreas con nombre

CSS Grid puede repetir pistas con repeat() y adaptar el número de columnas con auto-fit o auto-fill. Los dos modos de repetición automática difieren en cómo manejan las pistas vacías; las áreas con nombre proporcionan otra forma de describir regiones más grandes de la página.

Compara repetición fija y automática

.cards {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 16px;
}

repeat(3, ...) define tres columnas sin importar el número de tarjetas. Un cuarto elemento colocado automáticamente va a la siguiente fila; esto no aumenta el número de columnas. Esto difiere de la repetición automática, que calcula cuántas pistas caben. Consulta fundamentos de Grid: pistas, líneas y colocación.

.cards {
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 192px), 1fr));
}

auto-fit calcula cuántas columnas cabrán con el tamaño mínimo especificado. El primer valor de minmax es el mínimo, el segundo valor es el máximo, y 1fr divide el espacio restante. Aquí min(100%, 192px) garantiza que el ancho mínimo de columna no sea mayor que el de su contenedor padre. Fijar el mínimo para las columnas solo en 192px puede causar que incluso una sola columna se desborde más allá de su contenedor cuando este es más estrecho que 192px.

Para un contenedor de 800px, con columnas mínimas de 192px y espacios de 16px, tres columnas necesitan 608px, mientras que cuatro necesitan 816px. Solo caben tres columnas. Este cálculo determina el número de columnas; la distribución posterior del espacio libre determina sus anchos finales. El texto largo aún necesita una estrategia de ajuste.

Compara auto-fill y auto-fit

valor Pistas repetidas vacías tras colocar los elementos Pantalla grande con pocos elementos
auto-fill Mantener pistas vacías Se conserva espacio para columnas vacías
auto-fit Colapsar pistas de repetición sin elementos Las pistas ocupadas se expanden en el espacio disponible

Ambos valores calculan inicialmente las columnas que se pueden repetir dentro de ellos. La diferencia con auto-fit reside en el proceso de colapsar pistas repetidas vacías después de la colocación. Si los elementos llenan todas las columnas, los dos valores pueden parecer similares, así que compara con contenedores anchos y pocas tarjetas. Incluso cuando todas las tarjetas caben en una columna en una pantalla pequeña, la diferencia es difícil de ver. Consulta las reglas de repetición automática en la descripción de repeat() de MDN .

Comprende la colocación automática y dense

Los elementos que no especifican una posición se colocan por filas según el grid-auto-flow: row predeterminado. Incluso si el elemento anterior ocupa un área grande y se crea un espacio vacío, la colocación predeterminada no sigue regresando al espacio vacío al colocar el siguiente elemento. Este comportamiento predeterminado hace que la ordenación HTML y la progresión visual sean más fáciles de entender.

grid-auto-flow: row dense puede llenar el espacio vacío al frente con pequeños elementos en la parte trasera. Aunque queden menos huecos, el orden en que aparece en la pantalla y el orden del DOM (Modelo de Objetos del Documento) puede diferir. La colocación con CSS no reordena el HTML, por lo que el foco del teclado y el orden de lectura deben considerarse juntos. Para pasos con numeración significativa, registros cronológicos y entradas de formularios, mantener el orden es más importante que eliminar espacios en blanco. Puedes verificar las condiciones de colocación automática en la descripción de grid-auto-flow de MDN.

Ejecuta el ejemplo de repetición automática

Guarda el ejemplo como grid-auto-repeat.html. La primera sección tiene dos tarjetas en un contenedor limitado a 800px. La segunda sección utiliza dos enlaces que abarcan dos columnas y dos que abarcan una columna, dejando un hueco que permite comparar la colocación ordinaria con dense.

<!doctype html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>grid-auto-repeat.html</title>
  <style>
* { box-sizing: border-box; }
body { margin: 16px; font: 16px/1.6 sans-serif; color: #243447; }
h1 { font-size: 24px; } h2 { font-size: 20px; margin-top: 32px; }
a { color: #145f8f; } a:focus-visible { outline: 3px solid #b4470b; outline-offset: 3px; }
.cards { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(100%, 192px), 1fr));
 gap: 16px; width: min(100%, 800px); }
 .cards > div { min-width: 0; padding: 16px; background: #dceefa; overflow-wrap: anywhere; }
 .flow { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 12px;
 grid-auto-flow: row; max-width: 600px; margin-top: 16px; }
 .flow > a { padding: 12px; background: #e8f5de; }
 .flow > .wide { grid-column: span 2; }
  </style>
</head>
<body>
<h1>Comparing empty repeated columns</h1><div class="cards"><div>First card</div><div>Second card</div></div>
<h2>Default auto-placement</h2><div class="flow"><a class="wide" href="#result">1: two spaces</a><a class="wide" href="#result">2: two spaces</a><a href="#result">3: One space</a><a href="#result">4: one space</a></div>
<p id="result">This is the destination of the automatic-layout link.</p>
</body>
</html>
  1. En una pantalla ancha, si la primera sección es de 800px, las dos tarjetas en auto-fit ocuparán 392px cada una. Reemplazar solo auto-fit por auto-fill mantiene las tres columnas, dejando las dos primeras columnas de tarjetas en aproximadamente 256px y una columna vacía. Después de la confirmación, restaura a auto-fit.
  2. Copia más divs en la primera sección para que sean cuatro. Tres columnas están completas y se coloca una cuarta tarjeta en la siguiente fila. En esta condición, no hay columnas repetidas vacías, lo que reduce la diferencia entre los dos valores. Después de practicar, vuelve a las dos tarjetas originales.
  3. Reduce el ancho de la pantalla para comprobar de que el ancho del contenedor sea menor a 192px. Gracias a min(100%, 192px) una columna se ajustará a su contenedor. Cambiar el mínimo a solo 192px puede causar desbordamiento en áreas más ajustadas. Después de la comparación, restaura la expresión original.
  4. Comprueba el espacio vacío después del enlace 1 y la ubicación del enlace 3 en .flow. Si cambias solo grid-auto-flow a row dense, el número 3 se colocará en el espacio vacío anterior. Con Tab, comprueba si se mantiene el orden 1 → 2 → 3 → 4. Vuelve a row después de la práctica.

Define regiones de página con áreas con nombre

En lugar de calcular los números de columna y fila por separado, es más fácil leer la intención del diseño de la página expresando secciones grandes con nombres como header·main·aside·footer. Cada cadena en grid-template-areas es una fila, y los nombres separados por espacios dentro de la cadena son celdas. El valor grid-area del hijo debe coincidir con su nombre para entrar en esa área. Cómo cambiar la configuración de columnas según el ancho de la pantalla se explica en consultas de medios CSS y puntos de cambio según el contenido.

Repetir el mismo nombre en varias celdas crea un área rectangular. Las áreas no pueden tener forma de L ni ser una isla aislada. Cada fila debe tener el mismo número de celdas, y las celdas que deben dejarse en blanco se indican con un punto (.). Si una declaración no es válida, el navegador no la aplicará, lo que puede dar la impresión de colocación automática. Puedes comprobar las condiciones de área válidas en la descripción de grid-template-areas de MDN.

Guarda el código siguiente como grid-areas.html. En escritorio, el contenido principal y la información complementaria se colocan uno al lado del otro, y a 640px o menos, están en una columna. El HTML mantiene el contenido principal antes de la información complementaria en ambas distribuciones.

<!doctype html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>grid-areas.html</title>
  <style>
* { box-sizing: border-box; }
body { margin: 16px; font: 16px/1.6 sans-serif; color: #243447; }
h1 { font-size: 24px; } h2 { font-size: 20px; margin-top: 32px; }
a { color: #145f8f; } a:focus-visible { outline: 3px solid #b4470b; outline-offset: 3px; }
.page { display: grid; grid-template-columns: minmax(0, 2fr) minmax(0, 1fr);
 grid-template-areas: "header header" "main aside" "footer footer"; gap: 16px; max-width: 1000px; }
 .page > * { min-width: 0; padding: 20px; background: #dceefa; overflow-wrap: anywhere; }
 header { grid-area: header; } main { grid-area: main; } aside { grid-area: aside; } footer { grid-area: footer; }
 @media (max-width: 640px) {
 .page { grid-template-columns: minmax(0, 1fr); grid-template-areas: "header" "main" "aside" "footer"; }
 }
  </style>
</head>
<body>
<h1>Page area names</h1><div class="page"><header>Site title</header><main><h2>Main content</h2><p>This is the main content area. The HTML order keeps it first on mobile, too.</p></main><aside>Related information</aside><footer>Contact and site information</footer></div>
</body>
</html>
  1. Asegúrate de que el encabezado y el pie de página ocupen dos columnas en una pantalla ancha. Si reduces la pantalla a 640px o menos, encabezado → principal → aside → pie de página estarán en una columna. Observa por qué necesitas cambiar las definiciones de columna y las cadenas de áreas juntas.
  2. Cambia solo el grid-area de aside a un nombre diferente. La conexión entre el área aside reservada en la plantilla y el elemento real puede desconectarse y no colocarse en la ranura prevista. Restaura el nombre a aside.
  3. Si cambias solo la plantilla de pantalla ancha a "header header" "header aside" "footer footer", el encabezado tendrá forma de L y la declaración de grid-template-areas será inválida. Después de confirmar la aplicación en las Herramientas de Desarrollador, restaura las tres cadenas originales.

En la práctica, es más fácil de mantener si distingues el contenedor que adapta las columnas de tarjetas del que define las regiones de la página. La repetición automática determina el número y el ancho mínimo, mientras que los nombres de las regiones determinan la estructura de la página y los puntos de transición. Antes de intentar forzar a que los dos estén en una sola regla, decide qué problema está intentando resolver cada contenedor.