Lección 5: Grid | Curso de Maquetación Web

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.

Tablero

Podría marcar como quiero colocar la estructura de mis elementos.

Tablero con colores

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:

Resultado

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>

Estructura básica

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>

Estructura básica

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>

Estructura básica

Posicionando los hijos

En esta ocasión vamos a colocar cada hijo donde nosotros queramos. Partimos de un tablero de 3x3.

Tablero 3x3

Nuestro objetivo final será colocar 5 elementos con esta estructura.

Tablero con posiciones

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>

Resultado sin posicionar

Cada hijo debe ser posicionado en un inicio y un final de columna y fila. Nuestro tablero tiene las siguientes líneas.

Tablero con marcas

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;
}

Posicionando amarillo

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>

Posicionando amarillo

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>
1
2
3
4
5
6

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>
1
2
3
4
5
6

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>
1
2
3
4
5
6

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.

Posicionando amarillo

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.

Previa actividad 23-1

Actividad 2

A partir de la siguiente imagen, maqueta usando Grid.

Previa actividad 23-2

Actividad 3

A partir de la siguiente imagen, maqueta usando Grid.

Previa actividad 23-3

Actividad 4

A partir de la siguiente imagen, maqueta usando Grid.

Previa actividad 23-4

Actividad 5

A partir de la siguiente imagen, maqueta usando Grid enfocado a smartphone (menos de 500px de ancho.

Previa actividad 23-5

Actividad 6

A partir de la siguiente imagen, maqueta usando Grid.

Previa actividad 23-6

Actividad 7

A partir de la siguiente imagen, maqueta usando Grid.

Previa actividad 23-7

Esta obra está bajo una Licencia Creative Commons Atribución-NoComercial-SinDerivadas 4.0 Internacional.

Atribución/Reconocimiento-NoComercial-SinDerivados 4.0 Internacional

¿Me ayudas?

Comprame un café
Pulsa sobre la imagen

No te sientas obligado a realizar una donación, pero cada aportación mantiene el sitio en activo logrando que continúe existiendo y sea accesible para otras personas. Además me motiva a crear nuevo contenido.

Comentarios

{{ comments.length }} comentarios

Nuevo comentario

Nueva replica  {{ formatEllipsisAuthor(replyComment.author) }}

Acepto la política de Protección de Datos.

Escribe el primer comentario