CSS: Grid - Distribución

La estructura principal de una cuadrícula (grid) está compuesta por bandas, es decir, filas y columnas, a partir de las cuales se distribuyen los elementos hijos (ítems). La estructura cuadricular se crea definiendo el número de filas, el número de columnas y su tamaño, de forma explícita e intencional.

No obstante, cuando hay elementos por reubicar en la cuadrícula pero no hay ni filas ni columnas que estén definidas de forma explícita, se crearán nuevas bandas (filas o columnas) de forma automática (implícitamente).

También es posible distribuir los elementos hijos (ítems) de una cuadrícula haciendo uso de las áreas. Este método es un complemento que permite componer plantillas o estructuras de elementos de una forma mucho más intuitiva y visual.

Lista de propiedades descritas en este artículo:

Propiedad Descripción
grid-template-rows Indica el tamaño de cada fila.
grid-template-columns Indica el tamaño de cada columna.
grid-template-areas Indica la ubicación de las áreas.
grid-template Abreviatura de las tres anteriores.
grid-area Indica el nombre de las áreas sobre los ítems.

Definir filas y columnas

Para definir filas y columnas en una cuadrícula CSS se usa principalmente dos propiedades: grid-template-rows y grid-template-columns. Sus valores son el tamaño, ya sea en unidades relativas, absolutas o fraccionales (fr). El número de tamaños indicados especifica la cantidad de filas o columnas.

Por ejemplo, el valor 100px 200px definirá dos filas o dos columnas, siendo de 100 píxeles la primera y de 200 píxeles la segunda.

Vamos a crear un ejemplo usando unidades fraccionales.

Código CSS:

.cuadricula {
  display: grid;
  grid-template-columns: 1fr 2fr 1fr;
  grid-template-rows: 3fr 1fr;
  height: 200px;
  width: 200px;
}

Código HTML:

<div class="cuadricula">
  <div class="item">1</div>
  <div class="item">2</div>
  <div class="item">3</div>
  <div class="item">4</div>
  <div class="item">5</div>
  <div class="item">6</div>
</div>

Resultado:

1
2
3
4
5
6

El contenedor mide 200×200 píxeles. La columnas 1 y 3 miden 1fr de ancho, equivalente a 50 píxeles, mientras que la del medio mide 2fr, equivalente a 100 píxeles (el doble). La primera fila mide 3fr de alto (150 píxeles), el triple que la segunda fila, de solo 1fr. Por tanto, las celdas 4 y 6 resultantes de la intersección miden exactamente 50×50 píxeles.

En los próximos ejemplos se seguirá usando la misma estructura HTML, es decir, un elemento contenedor con seis ítems (elementos hijos).

A la hora de definir el tamaño y la cantidad de las filas y las columnas, hay que tener claro el número de elementos hijos que hay en el contenedor, con el fin de hacer que cuadren según las expectativas deseadas.

Por ejemplo, si hay 8 elementos en una cuadrícula de 3×3, tendremos 3 elementos en la primera fila, 3 elementos en la segunda y otros 2 en la tercera. En casos como este, quedará una celda vacía al final de la cuadrícula.

La función ‘repeat()’

Con la función repeat() es posible definir varias filas o columnas que tengan el mismo tamaño. Admite dos parámetros mínimos: el primero es el número de columnas y el segundo es el tamaño. Esta función se usa con las siguientes propiedades CSS: grid-template-columns y grid-template-rows.

Vamos a ver un ejemplo básico.

Código CSS:

.con-repeat1 {
  display: grid;
  grid-template-columns: repeat(6, 1fr);
}

Resultado:

1
2
3
4
5
6

Lo que establece la función repeat(6, 1fr) es que debe repetir 6 veces el valor 1fr, equivalente a escribir 1fr 1fr 1fr 1fr 1fr 1fr. En caso de tener más elementos hijos, se crearía más filas a continuación.

La función repeat() permite añadir más tamaños a continuación del segundo parámetro. En el ejemplo siguiente vamos a indicarle que queremos las 6 columnas agrupadas en una de 1fr y otra de 3fr, de forma repetida. Es por eso que hay que indicar 3 columnas de 2 columnas de 1fr 3fr (3×2=6 columnas).

Código CSS:

.con-repeat2 {
  display: grid;
  grid-template-columns: repeat(3, 1fr 3fr);
}

Resultado:

1
2
3
4
5
6

Ahora hay seis columnas compuestas por tres grupos de columnas formados por una columna de 1fr y otra de 3fr.

Se puede agregar columnas antes y después de usar la función repeat(). Vamos a crear un ejemplo con un patrón de repetición de dos columnas, añadiendo una tercera columna con un ancho fijo de 100 píxeles.

Código CSS:

.con-repeat3 {
  display: grid;
  grid-template-columns: repeat(2, 1fr) 100px;
  height: 50px;
}

Resultado:

1
2
3
4
5
6

¿Lo ves? Las dos primeras columnas tienen un ancho de 1fr, mientras que la tercera columna mide 100 píxeles. Como hay seis elementos hijos, los tres restantes se han reorganizado en la segunda fila de la cuadrícula.

La función ‘minmax()’

La función minmax() permite definir un rango permitido para el tamaño de un elemento. El primer parámetro será el tamaño mínimo permitido para el elemento, mientras que el segundo será el tamaño máximo permitido. Esta función se usa con las propiedades grid-template-columns y grid-template-rows dentro de la función repeat(), actuando como un parámetro más.

Por ejemplo, si se indica una anchura mínima de 100 píxeles y una anchura máxima de 200 píxeles, estas son las medidas de referencia para decidir el ajuste de las columnas. En caso de que la ventana del navegador se haga más pequeña, la anchura mínima se quedará en los 100 píxeles indicados.

Código CSS:

.con-minmax {
  display: grid;
  grid-template-columns: repeat(2, minmax(100px, 200px));
}

Resultado:

1
2
3
4
5
6

En este ejemplo, las columnas medirán entre 100 píxeles y 200 píxeles, cada una. Por tanto, si la anchura del contenedor es mayor de 400 píxeles, quedará espacio restante. Pero si la anchura del navegador es menor de 200 píxeles, los ítems se desbordarán del elemento contenedor.

Los valores ‘auto-fill’ y ‘auto-fit’

Cuando se usa la función repeat() junto con la función minmax(), es interesante que el número de las filas o las columnas se ajuste de forma automática según el tamaño del contenedor y del contenido. Lo que se hace en estos casos es no indicar un número de columnas sino usar los valores auto-fill o auto-fit.

Lo que harán auto-fill o auto-fit es crear tantas filas o columnas como sea necesario, basándose en los tamaños mínimo y máximo. Así, mostrará más o menos filas o columnas dependiendo del tamaño del contenedor.

También pueden usarse sin la función minmax(). Pero la combinación de las funciones repeat() y minmax() con auto-fill o auto-fit proporciona un control más flexible sobre la expansión de los ítems.

La diferencia que hay entre auto-fill y auto-fit es que auto-fill creará filas o columnas adicionales dejando espacio libre en el contenedor (si está disponible), mientras que auto-fit lo hará sin dejar espacio libre, por lo que llenará todo el espacio disponible, adaptándose al contenedor.

Vamos a ver un ejemplo de cuadrícula usando auto-fill.

Código CSS:

.con-auto {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
}

Resultado:

1
2
3
4
5
6

Haciendo la ventana del navegador cada vez más pequeña, el número de columnas se irá reduciendo. Si el contenedor mide más de 450 píxeles de ancho cabrán más columnas, pero si mide menos ya solo cabrán dos columnas. Por debajo de los 300 píxeles ya solo cabrá una columna.

Ahora vamos a crear dos ejemplos con un ancho de columna más pequeño (50 píxeles) para visualizar la diferencia entre estos dos valores.

Código CSS:

.con-auto-fill {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(50px, 1fr));
}

.con-auto-fit {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(50px, 1fr));
}

Resultado con auto-fill:

1
2
3
4
5
6

Resultado con auto-fit:

1
2
3
4
5
6

Definir áreas

En las cuadrículas CSS también es posible definir áreas, que permiten crear plantillas de una forma “gráfica”. Para ello se usa las siguientes propiedades CSS: con grid-template-areas se indica la disposición de las áreas en el contenedor, y con grid-area se indica el nombre de las áreas sobre los ítems.

Cabe señalar que las áreas no son una alternativa a la definición de filas y columnas (mediante las propiedades grid-template-rows y grid-template-columns), sino que son un complemento.

La propiedad ‘grid-template-areas’

La propiedad grid-template-areas permite indicar la localización de las áreas en el contenedor y, por tanto, se usa sobre el elemento contenedor (padre). Como valor admite cadenas de texto, y cada cadena de texto simboliza una fila; dentro de cada fila se introducen los nombres de las áreas separados por un espacio.

Vamos a ver un ejemplo con nombres de una letra.

.mis-areas {
  grid-template-areas:
    "a a a"
    "b c c"
    "d d d";
}

En las cadenas de texto, el número de áreas debe coincidir. Si hay tres áreas en una cadena de texto, deberá haber otras tres áreas en el resto. Si se quiere dejar una celda vacía se puede usar el punto como recurso. Así:

.mis-areas {
  grid-template-areas:
    "a a a"
    "b . c"
    "d d d";
}

La celda del medio no tiene ninguna área asignada y se mostrará vacía.

La propiedad ‘grid-area’

Para que el resultado tenga efecto, hay que asignar los nombres de las áreas a los elementos hijos (ítems). Para ello se utiliza la propiedad grid-area. Su valor será el nombre del área, y se puede introducir sin comillas.

Código CSS:

head {
  grid-area: cabecera;
}

Si se define la misma área sobre más de un elemento hijo, su contenido se superpondrá, quedando como visible el último que esté declarado en el documento HTML. Se recomienda no repetir áreas dentro de un contenedor.

Ejemplo de creación de áreas

Imaginemos que queremos una cuadrícula para los seis elementos que hemos usado hasta ahora. Vamos a crear seis áreas: head, menu, side, main, form y foot. Al tener cuatro letras ayudará a su comprensión visual.

Código CSS:

.mis-areas {
  display: grid;
  grid-template-areas:
    "head head head"
    "menu menu menu"
    "side main form"
    "foot foot foot";
}

.area1 {
  background: goldenrod;
  grid-area: head;
}

.area2 {
  background: salmon;
  grid-area: menu;
}

.area3 {
  background: deepskyblue;
  grid-area: side;
}

.area4 {
  background: slategray;
  grid-area: main;
}

.area5 {
  background: mediumpurple;
  grid-area: form;
}

.area6 {
  background: lightgreen;
  grid-area: foot;
}

Código HTML:

<div class="mis-areas">
  <div class="area1">1</div>
  <div class="area2">2</div>
  <div class="area3">3</div>
  <div class="area4">4</div>
  <div class="area5">5</div>
  <div class="area6">6</div>
</div>

Resultado:

1
2
3
4
5
6

Las áreas se pueden combinar con las filas y las columnas, de modo que con la propiedad grid-template-rows podríamos definir una altura para cada una de las cuatro filas, mientras que con grid-template-columns podríamos definir la anchura para cada una de las tres columnas.

Código CSS adicional:

.adicional {
  grid-template-rows: 2fr 1fr 4fr 1.5fr;
  grid-template-columns: 50px 1fr  50px;
}

Resultado:

1
2
3
4
5
6

La propiedad ‘grid-template’

La propiedad grid-template es una abreviatura (shorthand) que permite definir a la vez los valores de las siguientes propiedades CSS: grid-template-rows, grid-template-columns y grid-template-areas.

Primero se define las áreas entre comillas, separadas por un espacio. Después de cada área se define el tamaño (altura) de las filas. Al final de todo, tras una barra inclinada (/) se define el tamaño (anchura) de las columnas.

Sintaxis:

grid-template: "areas" filas / columnas;

Veamos algunos ejemplos:

/* Filas y columnas */
.ejemplo1 {
  display: grid;
  grid-template: repeat(2, 100px) / 300px 1fr;
}

/* Áreas y filas */
.ejemplo2 {
  display: grid;
  grid-template:
    "a a b" 1fr
    "c c c" 3fr;
}

/* Áreas, filas y columnas */
.ejemplo3 {
  display: grid;
  grid-template:
    "a a b" 1fr
    "c c c" 3fr / 100px repeat(2, 1fr);
}

En el último ejemplo, las tres columnas que se “visualiza” en las áreas han sido definidas después de una barra inclinada (/). Así, la primera columna tendrá un ancho de 100 píxeles, y las otras serán de 1fr.

Volviendo al ejemplo en el que creamos seis áreas y definimos el tamaño tanto de las filas como de las columnas, podríamos haberlo declarado todo con la propiedad grid-template, de esta manera:

.mis-areas {
  display: grid;
  grid-template:
    "head head head" 2fr
    "menu menu menu" 1fr
    "side main form" 4fr
    "foot foot foot" 1.5fr / 50px 1fr  50px
}
← Artículo anterior
Artículo siguiente →