Lección 5: Grid
El Grid es una de las novedades más importantes de CSS a la hora de maquetar. Nos permite crear estructuras complejas de forma sencilla y sin necesidad de alterar el HTML. Es decir, podemos crear cuadrículas para situar los elementos prácticamente en cualquier lugar sin alterar la estructura del HTML.
Antes de entrar en los estilos debemos comprender como se maqueta con Grid. Para ello voy a enseñarte un ejemplo completo para que entiendas su potencial y a continuación explicaré cada capa de forma individual. ¡No te asustes!
Imaginemos, para el ejemplo que NO vamos a entender, que nuestra web es un tablero de ajedrez.
Podría marcar como quiero colocar la estructura de mis elementos.
Ahora lo implemento en HTML/CSS partiendo de Grid.
<html>
<head>
<!-- CSS -->
<style>
.tablero {
display: grid;
grid-template-columns: 300px 500px;
grid-template-rows: 200px 100px 500px;
width: 800px;
height: 800px;
}
.azul {
background-color: blue;
grid-column: 2 / 3;
grid-row: 2 / 3;
}
.amarillo {
background-color: yellow;
grid-column: 1 / 2;
grid-row: 1 / 4;
}
.rojo {
background-color: red;
grid-column: 2 / 3;
grid-row: 1 / 2;
}
.verde {
background-color: green;
grid-column: 2 / 3;
grid-row: 3 / 4;
}
</style>
</head>
<body>
<!-- HTML -->
<div class="tablero">
<div class="azul"></div>
<div class="amarillo"></div>
<div class="rojo"></div>
<div class="verde"></div>
</div>
</body>
</html>
El resultado sería prácticamente igual:
Sencillo, ¿verdad? Aunque no sepas que ha ocurrido aquí quiero que te quedes con la idea de que Grid nos permite crear estructuras complejas de forma sencilla. Y que no es necesario alterar el HTML.
Ahora pasemos a explicar cada elemento.
Conceptos básicos
Para empezar debemos tener claro que existen dos partes bien diferenciadas: un padre y sus hijos. El padre será el tablero o la etiqueta que envuelva todo. Llevará el estilo display: grid. Y los hijos son los contenedores o elementos que queremos posicionar dentro de nuestro tablero. Si has trabajado con flex notarás que el funcionamiento es clónico.
Un ejemplo.
<html>
<head>
<!-- CSS -->
<style>
.tablero {
display: grid;
width: 800px;
height: 800px;
}
.azul {
background-color: blue;
}
.amarillo {
background-color: yellow;
}
.rojo {
background-color: red;
}
.verde {
background-color: green;
}
</style>
</head>
<body>
<!-- HTML -->
<div class="tablero">
<div class="azul"></div>
<div class="amarillo"></div>
<div class="rojo"></div>
<div class="verde"></div>
</div>
</body>
</html>
De acuerdo, tal vez te sientes decepcionado. ¡Paciencia! Aún tenemos que indicar a cada hijo donde debe colocarse :)
El padre va a indicar cual va a ser el número de filas y columnas que va a tener nuestro tablero. Incluso va a decir cuanto va a medir cada una.
Si quisiera una estructura de 2x2. O lo que es lo mismo, si partimos de que nuestro tablero mide 800px por 800px: 2 columnas de 400px y 2 filas de 400px.
<html>
<head>
<!-- CSS -->
<style>
.tablero {
display: grid;
/* Columnas */
grid-template-columns: 400px 400px;
/* Filas */
grid-template-rows: 400px 400px;
width: 800px;
height: 800px;
}
.azul {
background-color: blue;
}
.amarillo {
background-color: yellow;
}
.rojo {
background-color: red;
}
.verde {
background-color: green;
}
</style>
</head>
<body>
<!-- HTML -->
<div class="tablero">
<div class="azul"></div>
<div class="amarillo"></div>
<div class="rojo"></div>
<div class="verde"></div>
</div>
</body>
</html>
Sencillo, ¿no?
Por supuesto puedo cambiar los tamaños.
<html>
<head>
<!-- CSS -->
<style>
.tablero {
display: grid;
/* Columnas */
grid-template-columns: 100px 700px;
/* Filas */
grid-template-rows: 500px 300px;
width: 800px;
height: 800px;
}
.azul {
background-color: blue;
}
.amarillo {
background-color: yellow;
}
.rojo {
background-color: red;
}
.verde {
background-color: green;
}
</style>
</head>
<body>
<!-- HTML -->
<div class="tablero">
<div class="azul"></div>
<div class="amarillo"></div>
<div class="rojo"></div>
<div class="verde"></div>
</div>
</body>
</html>
Posicionando los hijos
En esta ocasión vamos a colocar cada hijo donde nosotros queramos. Partimos de un tablero de 3x3.
Nuestro objetivo final será colocar 5 elementos con esta estructura.
Preparamos nuestro código.
<html>
<head>
<!-- CSS -->
<style>
.tablero {
display: grid;
grid-template-columns: 300px 300px 300px;
grid-template-rows: 300px 300px 300px;
width: 900px;
height: 900px;
}
.azul {
background-color: blue;
}
.amarillo {
background-color: yellow;
}
.rojo {
background-color: red;
}
.verde {
background-color: green;
}
.rosa {
background-color: pink;
}
</style>
</head>
<body>
<!-- HTML -->
<div class="tablero">
<div class="azul"></div>
<div class="amarillo"></div>
<div class="rojo"></div>
<div class="verde"></div>
<div class="rosa"></div>
</div>
</body>
</html>
Cada hijo debe ser posicionado en un inicio y un final de columna y fila. Nuestro tablero tiene las siguientes líneas.
Empezamos con el hijo amarillo. Ocupa el área entre la columna 1 y la columna 2.
.amarillo {
background-color: yellow;
grid-column-start: 1;
grid-column-end: 2;
}
Y de la fila 1 a la fila 4.
.amarillo {
background-color: yellow;
grid-column-start: 1;
grid-column-end: 2;
grid-row-start: 1;
grid-row-end: 4;
}
Una versión resumida de lo anterior.
.amarillo {
background-color: yellow;
grid-column: 1 / 2;
grid-row: 1 / 4;
}
Aplicando la misma técnica se quedaría el ejemplo de la siguiente forma.
<html>
<head>
<!-- CSS -->
<style>
.tablero {
display: grid;
grid-template-columns: 300px 300px 300px;
grid-template-rows: 300px 300px 300px;
width: 900px;
height: 900px;
}
.azul {
background-color: blue;
grid-column: 2 / 4;
grid-row: 3 / 4;
}
.amarillo {
background-color: yellow;
grid-column: 1 / 2;
grid-row: 1 / 4;
}
.rojo {
background-color: red;
grid-column: 2 / 3;
grid-row: 1 / 3;
}
.verde {
background-color: green;
grid-column: 3 / 4;
grid-row: 1 / 2;
}
.rosa {
background-color: pink;
grid-column: 3 / 4;
grid-row: 2 / 3;
}
</style>
</head>
<body>
<!-- HTML -->
<div class="tablero">
<div class="azul"></div>
<div class="amarillo"></div>
<div class="rojo"></div>
<div class="verde"></div>
<div class="rosa"></div>
</div>
</body>
</html>
grid-template-columns
Define el número de columnas y su tamaño.
Fijo
.cuadricula {
display: grid;
grid-template-columns: 10rem 10rem;
}
Fracciones
Reparte el espacio disponible.
.cuadricula {
display: grid;
/* 50% y 50% */
grid-template-columns: 1fr 1fr;
/* 75% y 25% */
grid-template-columns: 3fr 1fr;
/* todo el espacio diponible + 10rem */
grid-template-columns: 1fr 10rem;
}
Mínimo y máximo
Define una medida mínima y máxima.
.cuadricula {
display: grid;
/* Entre 20rem y 30rem */
grid-template-columns: minmax(20rem, 30rem);
/* Entre 20rem y 100% */
grid-template-columns: minmax(20rem, 1fr);
}
Repeat
Repite una medida un número de ocasiones.
.cuadricula {
display: grid;
grid-template-columns: repeat(3, 10rem);
}
grid-row-start/grid-row-end/grid-row
Define en que fila empezará y terminará dentro de la cuadrícula.
.elemento {
grid-row-start: 1;
grid-row-end: 2;
}
Una forma abreviada es usando grid-row
.
.elemento {
grid-row: 1 / 2;
}
grid-column-start/grid-column-end
Define en que columna empezará y terminará dentro de la cuadrícula.
.elemento {
grid-column-start: 1;
grid-column-end: 2;
}
Una forma abreviada es usando grid-column
.
.elemento {
grid-column: 1 / 2;
}
grid-row-gap
Añade espacio entre las filas.
.cuadricula {
grid-row-gap: 2rem;
}
grid-column-gap
Añade espacio entre las columnas.
.cuadricula {
grid-column-gap: 2rem;
}
gap
Añade espacio entre las columnas y las filas. Ya lo estuvimos usando con Flex.
.cuadricula {
gap: 2rem;
}
grid-template-rows
Define el número de filas y su tamaño. Comparte las mismas medidas de grid-template-columns
.
.cuadricula {
display: grid;
grid-template-rows: 1fr 1fr;
}
grid-auto-flow
Automáticamente posiciona los elementos en los espacios que pueden entrar, siguiendo su orden o no.
Orden horizontal
.cuadricula {
display: grid;
grid-auto-flow: row;
grid-template-columns: repeat(3, 1fr);
grid-template-rows: repeat(3, 10rem);
gap: 1rem;
}
.elemento {
border: 5px solid #d66853;
background-color: #f7b143;
color: white;
font-size: 3rem;
display: flex;
justify-content: center;
align-items: center;
}
.elemento-ancho {
grid-column: auto / span 2;
}
<section class="cuadricula">
<article class="elemento">1</article>
<article class="elemento">2</article>
<article class="elemento elemento-ancho">3</article>
<article class="elemento">4</article>
<article class="elemento">5</article>
<article class="elemento elemento-ancho">6</article>
</section>
Orden vertical
.cuadricula {
display: grid;
grid-auto-flow: column;
grid-template-columns: repeat(3, 1fr);
grid-template-rows: repeat(3, 10rem);
gap: 1rem;
}
.elemento {
border: 5px solid #d66853;
background-color: #f7b143;
color: white;
font-size: 3rem;
display: flex;
justify-content: center;
align-items: center;
}
.elemento-ancho {
grid-column: auto / span 2;
}
<section class="cuadricula">
<article class="elemento">1</article>
<article class="elemento">2</article>
<article class="elemento elemento-ancho">3</article>
<article class="elemento">4</article>
<article class="elemento">5</article>
<article class="elemento elemento-ancho">6</article>
</section>
Sin orden, prima condensar
.cuadricula {
display: grid;
grid-auto-flow: row dense;
grid-template-columns: repeat(3, 1fr);
grid-template-rows: repeat(3, 10rem);
gap: 1rem;
}
.elemento {
border: 5px solid #d66853;
background-color: #f7b143;
color: white;
font-size: 3rem;
display: flex;
justify-content: center;
align-items: center;
}
.elemento-ancho {
grid-column: auto / span 2;
}
<section class="cuadricula">
<article class="elemento">1</article>
<article class="elemento">2</article>
<article class="elemento elemento-ancho">3</article>
<article class="elemento">4</article>
<article class="elemento">5</article>
<article class="elemento elemento-ancho">6</article>
</section>
Definiendo el nombre de las áreas
Marcar con aristas, o cortes, la posición de cada elemento en la cuadrícula llega a ser confuso además de duro de mantener. Para ello, Grid nos permite definir el nombre de cada área y asignarle un elemento.
Vamos a repetir el ejemplo de la explicación, pero esta vez, definiendo el nombre de las áreas.
El primer paso es definir sus filas y columnas.
.cuadricula {
display: grid;
grid-template-columns: repeat(3, 1fr);
grid-template-rows: repeat(3, 1fr);
width: 900px;
height: 900px;
}
De momento no ha ocurrido ningún cambio. Ahora vamos a dar un alias a cada zona, y para ello usaremos la propiedad grid-template-areas
.
.cuadricula {
display: grid;
grid-template-columns: repeat(3, 1fr);
grid-template-rows: repeat(3, 1fr);
width: 900px;
height: 900px;
grid-template-areas:
"amarillo rojo verde"
"amarillo rojo rosa"
"amarillo azul azul";
}
Los nombres de las áreas se definen entre comillas, y cada fila se separa por un salto de línea. En este caso, hemos definido tres filas y tres columnas, por lo que tenemos nueve áreas pero con el nombre que nosotros queramos.
Ahora, para asignar un elemento a una zona, usaremos la propiedad grid-area
y le asignaremos el nombre de la zona.
.amarillo {
grid-area: amarillo;
}
.rojo {
grid-area: rojo;
}
.verde {
grid-area: verde;
}
.rosa {
grid-area: rosa;
}
.azul {
grid-area: azul;
}
El HTML no cambiaría.
<section class="cuadricula">
<article class="amarillo"></article>
<article class="rojo"></article>
<article class="verde"></article>
<article class="rosa"></article>
<article class="azul"></article>
</section>
Apuntes finales
Es curioso porque para crear diseños sencillos de una dirección Flex es más que suficiente, y Grid se vuelve tedioso. Mientras que en estructuras complejas se dan la vuelta las tornas, Flex se vuelve lioso mientras que Grid se transforma en una herramienta afilada para gestionar todo tipo de espacios. La experiencia te irá enseñando a palos cuando debe usar cada una, pero no olvides mi consejo anterior. No te puedes casar con ninguna, ambas existen para resolver problemas diferentes.
Actividad 1
A partir de la siguiente imagen, maqueta usando Grid.
Actividad 2
A partir de la siguiente imagen, maqueta usando Grid.
Actividad 3
A partir de la siguiente imagen, maqueta usando Grid.
Actividad 4
A partir de la siguiente imagen, maqueta usando Grid.
Actividad 5
A partir de la siguiente imagen, maqueta usando Grid enfocado a smartphone (menos de 500px de ancho.
Actividad 6
A partir de la siguiente imagen, maqueta usando Grid.
Actividad 7
A partir de la siguiente imagen, maqueta usando Grid.
Esta obra está bajo una Licencia Creative Commons Atribución-NoComercial-SinDerivadas 4.0 Internacional.
¿Me invitas a un café? ☕
Puedes hacerlo usando el terminal.
ssh customer@andros.dev -p 5555
Comentarios
Nuevo comentario
Nueva replica {{ formatEllipsisAuthor(replyComment.author) }}
Escribe el primer comentario
{{ comments.length }} comentarios