Apuntes Curso Web

HTML, CSS y JavaScript

Propiedad Grid

Grid es una herramienta de diseño para CSS que permite organizar la presentación del documento sobre una rejilla o cuadrícula al modo en que se trabaja en diseño gráfico. Es una propiedad tremendamente flexible que permite hacer grandes cambios en la composición del diseño con unas pocas modificaciones, permitiendo escapar de las limitaciones y complicaciones del diseño web tradicional.

Su utilización simplifica también las modificaciones en la estructura del documento derivadas del diseño responsive, haciendo fácil la redistribución del los elementos del documento en diferentes resoluciones de pantalla y dispositivos.

Aunque inicialmente pueda parecer algo intimidante, la correcta comprensión de unas pocas propiedades básicas hará que resulte sencillo su uso de forma habitual.

En qué consiste Grid

Grid es un nuevo valor disponible para la propiedad display, lo que quiere decier que es un modo de cambiar la presentación de un determinado elemento. Pero, del mismo modo que ocurre con display: flex, el valor grid no afecta visualmente al propio elemento, sino que cambia la presentación de los elementos directamente contenidos en él.

Cuando definimos la presentación de un elemento como grid estamos diciendo al navegador que el contenido de ese elemento va adoptar una forma de rejilla o cuadrícula, o también de tabla con su número de filas y columnas definido. Al mismo tiempo, lo que vamos a hacer con ese contenido de la rejilla es ubicarlo en ella indicando en qué posición y cuanto espacio debe ocupar en ella.

De este modo, para configurar correctamente una presentación cuadricular tendremos que declarar por un lado las propiedades de ese contenedor grid y, por otra parte, las propiedades de los elementos contenidos. Para esto es necesario indicar que tenemos dos formas principales de configurar nuestra rejilla, una es a través de una plantilla de columnas de la retícula, y la otra a través de un sistema de plantilla de áreas de la retícula. Ambos permiten hacer exáctamente lo mismo con nuestra rejilla, pero tienen diferentes formas (propiedades) para hacerlo. El que elijamos un sistema u otro es una cuestión personal, dependiendo de cuál nos resulte más cómodo. Más adelante veremos un ejemplo cada tipo.

Propiedades del contenedor

Con independencia del sistema elegido para construir la retícula lo primero que tendremos que definir es nuestro contenedor grid, y eso lo haremos con la propiedad display: grid;. A partir de ahí, si queremos usar un sistema de plantilla de columnas (y opcionalmente filas), usaremos la propiedad grid-template-columns, y opcionalmente grid-template-rows

Con grid-template-columns lo que hacemos es definir el número y tamaño de cada una de las columnas que va a tener nuestra rejilla. Como es una propiedad CSS la podemos ir variando usando media-queries lo que va a permitir que nuestro diseño pueda tener diferente número de columnas según el dispositivo de salida.

Diseño con columnas

La forma de definir las columnas es escribiendo la anchura de cada una de ellas separadas por espacios dentro del valor de la propiedad. Por ejemplo, grid-template-columns: 250px auto 90rem; indica que nuestro diseño tendrá 3 columnas, la primera y tercera con una anchura fija (250px y 90rem) y la central tendrá un tamaño automático.

Unidad fr

En la definición de la anchura de las columnas es muy habitual usar la undidad fr. Es una medidad proporcional que hace referencia a fracciones del espacio libre disponible en el contenedor grid. Por ejemplo, grid-template-columns: 1fr 3fr 2fr quiere decir que tendremos 3 columnas donde la primera ocupa una sexta parte del espacio disponible, y además es la mitad de ancha que la tecera columna y una tercera parte de la segunda; la segunda columna ocupa la mitad del espacio libre; y la tercera ocupa un tercio del espacio.

Función repeat

Si tenemos que definir muchas columans en nuestro diseño puede ser útil usar la función de CSS repeat() que nos ahorrará el trabajo de escribir los mismos valores una y otra vez. El código grid-template-columns: repeat(12, 1fr) hará que nuestro diseño tenga 12 columnas de igual tamaño todas ellas.

Diseño por áreas

Si optamos por esta configuración de retícula para el contenedor grid aquí usaremos la propiedad grid-template-areas que nos permite escribir en ella el nombre de cada una de las zonas de la plantilla que queramos crear. Hay que notar aquí que nuestra plantilla puede tener tantas zonas (o áreas) como queramos, y que los nombres para estas zonas no están predefinidos, pueden ser los que nosotros queramos, manteniendo las normas habituales de nombres de objetos, como siempre.

Para definir las zonas debemos tener en cuenta que iremos nombrando filas en el diseño (tantas como queramos), y que estas filas pueden contener tantas columnas como necesitemos. La definición de cada fila viene identificada por texto entre comillas simples 'fila'; y cada columna dentro de la fila se identifica con espacios: 'cabecera cabecera cabecera'.

De este modo, grid-template-areas: 'cabecera' 'navegacion' 'cuerpo' 'pie' está construyendo una plantilla de cuadrícula de 1 sola columna con cuatro filas. Y grid-template-areas: 'cabecera cabecera cabecera' 'navegacion cuerpo cuerpo' 'pie pie pie' crea una retícula de 3 filas y 3 columnas, donde cabecera y pie ocupan las 3 columnas de anchura, y navegación y cuerpo comparten una fila, en la que la zona de cuerpo ocupa 2 columnas y navegación una sola.

Propiedad gap

Tanto para el diseño por áreas como para el diseño por columnas podemos usar una propiedad que defina las separaciones entre cada uno de los elementos de manera homogénea. Se trata de la propiedad gap y se aplica al contenedor grid, de la misma forma que lo hacemos para un diseño flex. El código gap: 1rem 2rem aplicará una separación de 1 rem entre las filas de la rejilla y de 2 rems entre sus columnas.

Propiedades del contenido

Una vez definido el contenedor grid por áreas o por columnas, la siguiente fase es establecer cómo se van a ajustar los elementos de ese contenedor a la rejilla. El navegador de momento sólo sabe que hay un elemento con presentación de rejilla, pero no sabe nada de cómo adecuar los elementos a ella. Este proceso usa diferentes propiedades según el tipo de plantilla elegido.

Plantilla de columnas

Si tenemos la cuadrícula configurada por columnas la forma de llevar los elementos a la rejilla es indicando para cada uno de ellos en qué columna debe ubicarse y cuantas columnas a lo ancho va a ocupar. Esto lo hacemos con la propiedad grid-column, en ella indicamos el número de columna en la que se ubica el elemento y el número de columna en la que termina. Así grid-column: 1 / 12 indica a ese elemento que empiece en la columna 1 y termine en la 12, pero ATENCIÓN! terminará antes de la 12, sin ocuparla. Si queremos que ocupe las 12 tendremos que decir grid-column: 1 / 13;

Propiedad span

Otra forma de indicar la anchura del elemento es reemplazando el número de columna final por el número de columans que se va a expandir el elemento. Para eso haremos grid-column: 1 / span 12;. En este caso le indicamos que empiece en la primera columna y se expanda 12 columnas por lo que de esta forma sí que ocupará las 12 columnas de anchura.

Propiedades adicionales

La propiedad grid column es una forma abreviada para las propiedades grid-column-start y grid-column-end. Es decir, Así grid-column: 1 / 12 equivale a Así grid-column-start: 1; grid-column-end: 12;.

Y tenemos una propiedad grid-row que hace los mismo que grid-column pero para ubicar a los elementos en filas, y que tiene también su versión extendida con grid-row-start y grid-row-end.

Plantilla de áreas

Si optamos por trabajar con zonas de plantilla en este caso lo que tenemos que hacer es indicar a cada elemento del contenedor grid en qué área debe mostrarse, y la configuración de la plantilla que hayamos definido establecerá de forma automática las dimensiones de cada elemento.

Para este propósito usamos la propiedad grid-area definiendo com valor un nombre de las zonas de plantilla que previamente hemos creado. Por ejemplo grid-area: encabezado aplicado a un elemento header que se encuentre directamente anidado en nuestro contenedor grid hará que ese header ocupe todas las columnas que nuestra área encabezado ocupe en la plantilla.

Ejemplo de configuración de rejilla

En este ejemplo tenemos un contenedor grid con una rejilla en la cuál podemos configurar su número de columnas con el primer desplegable. Dentro del contenedor hay 12 elementos que se posicionan automáticamente en cada una de las columnas, de los cuales podemos cambiar su anchura, entendida como número de columnas de la rejilla en las que se pueden expandir, con el siguiente desplegable.
Comprueba cómo cambia la presentación del elemento modificando alguno de estos valores.

                            
    .contenedor-grid {
        grid-display-columns:  repeat(12, 1fr); 
    }
    .columnas-grid {
        grid-column:  auto / span 1; 
    }
                        
                    
1
2
3
4
5
6
7
8
9
10
11
12

Propiedades CSS grid

Estas son las propiedades que podemos usar para configurar un componente grid. Se dividen entre las propiedades que se aplican al contenedor y las que se aplican a los elementos de la rejilla.

Propiedades compartidas con display flex

Si optamos por una configuración de rejilla básica, en la que solamente definimos el número de columans y el número de filas de la cuadrícula, podemos usar justify-content con sus valores habituales para distribuir el espacio total que ocupan las columnas dentro del contenedor grid, y align-content para distribuir la altura total de las filas en el contenedor.
Para que estas propiedades tengan efecto las dimensiones del contenedor grid deben ser mayores que la suma de las anchuras de cada columna y de las alturas de cada fila, como ocurre en flex.

Del mismo modo, si las dimensiones de un elemento de rejilla son menores que las de la propia celda, podemos usar justify-item para posicionar el elemento sobre el espacio horizontal de la celda, y align-item para posicionarlo sobre su eje vertical.

También como ocurre en flex, estas son propiedades que aplicamos al contenedor grid y no a los elementos de la rejilla. Y de igual modo, si lo qe queremos es cambiar el espaciado, la alineación o el orden de un elemento de la rejilla en concreto podemos usar las propiedades disponibles para el contenido de la rejilla justify-self, align-self, order, que tienen efecto puntual sobre el elemento al que se le apliquen.

Propiedades del contenedor grid

  1. display grid y inline-grid convierten al elemento en un contenedor de tipo rejilla o cuadrícula.
  2. grid-template-columns Especifica el tamaño y número de columnas. Si son muchas columnas puede ser útil usar la función repeat.
  3. grid-template-rows Establece el tamaño y número de filas. Como en el caso anterior, repeat y minmax són útiles.
  4. grid-template-areas Permite crear un sistema de áreas de plantilla dentro de la cuadrícula. Sobre ellas se irán colocando los distintos elementos del diseño.
  5. grid-auto-columns Permite crear columnas de forma automática estableciendo su anchura.
  6. grid-auto-rows Permite crear filas de forma automática estableciendo su altura.
  7. grid-auto-flow Establece como se ubicarán los elementos en la rejilla, primero por columnas y luego por filas, o viceversa. Tiene un valor, dense, que permite saltar los huecos que puedan generarse.
  8. grid Es un shorthand para todas las propiedades grid que empiezan por grid-template- y por grid-auto-. Aquellas de estas que no se declaren de forma explícita toman sus valores predeterminados.
  9. gap Separación entre filas y columnas. Puede definir valores diferentes para el espacio de las filas y de las columnas.
  10. justify-content Alinea la cuadrícula sobre el eje horizontal del contenedor, siempre y cuando el tamaño de esta sea menor que el tamaño del contenedor grid.
  11. align-content Alinea la cuadrícula sobre el eje vertical del contenedor. También la suma de las alturas de las filas debe ser menor que la del contenedor.
  12. place-content Combinación de align-content y justify-content en una misma propiedad.
  13. justify-items Alinea cada elemento de la rejilla dentro de su celda sobre el eje horizontal. Es necesario que el tamaño del contenido sea menor que el tamaño de la celda para que tenga efecto.
  14. align-items Lo mismo que la anterior, pero respecto al eje vertical.
  15. place-items Combinación de align-items y justify-items.

Propiedades de los elementos de la cuadrícula

  1. grid-column Combina las propiedades grid-column-start y grid-column-end para definir la línea de columna inicial y final de un elemento. Si usamos el valor span entonces indica el número de columna en lugar de el número de línea.
  2. grid-row Hace lo mismo que la propiedad anterior, pero para las propiedades grid-row-start y grid-row-end.
  3. grid-area Asigna un elemento a una zona de la cuadrícula que previamente ha sido definida en el contenedor con la propiedad grid-template-areas.
  4. place-self Combina las propiedades de align-self y justify-self para ubicar un elemento en su celda.

Ejemplos de código

En este primer caso vemos una configuración para una estructura completa de documento web responsive, usando las propiedades grid basadas en la configuración por columnas:

Ejemplo de maqueta Grid

Zona de Contenido Principal

                                    
.grid-2 { display: grid; grid-template-columns: 1fr; gap: 0.5rem; } .grid-2>* { border: 4px solid var(--color-base-luz); padding: 2rem 0.5rem; } .grid-2 p { margin: 0; font-family: var(--txt-mono); color: var(--color-base-luz); }
@media (min-width: 650px) { .grid-2 { grid-template-columns: repeat(12, 1fr); header { grid-column: 1 / span 12; } nav { grid-column: 1 / span 4; } main { grid-column: 5/ span 8; } aside { grid-column: 1 / span 12; } footer { grid-column: 1 / span 12; } } }
@media (min-width: 960px) { .grid-2 { nav { grid-column: 1/ span 12; } main { grid-column: 1 / span 8; } aside { grid-column: 9 / span 4; } } }
@media (min-width: 1600px) { .grid-2 { nav { grid-column: 1/ span 2; } main { grid-column: 3 / span 7; } aside { grid-column: 10 / span 3; } } }

Zona de Pie de Página

Código usado

                        

HTML

<article class="grid-2"> <header> <p>Ejemplo de maqueta Grid</p> </header> <nav> <p>Zona de menú</p> </nav> <main> <p>Zona de Contenido Principal</p> </main> <aside> <p>Zona de Elementos Relacionados</p> </aside> <footer> <p>Zona de Pie de Página</p> </footer> </article>

CSS

.grid-2 { display: grid; grid-template-columns: 1fr; gap: 0.5rem; } .grid-2>* { border: 4px solid var(--color-base-luz); padding: 2rem 0.5rem; } .grid-2 p { margin: 0; font-family: var(--txt-mono); color: var(--color-base-luz); } @media (min-width: 650px) { .grid-2 { grid-template-columns: repeat(12, 1fr); header { grid-column: 1 / span 12; } nav { grid-column: 1 / span 4; } main { grid-column: 5/ span 8; } aside { grid-column: 1 / span 12; } footer { grid-column: 1 / span 12; } } } @media (min-width: 960px) { .grid-2 { nav { grid-column: 1/ span 12; } main { grid-column: 1 / span 8; } aside { grid-column: 9 / span 4; } } } @media (min-width: 1600px) { .grid-2 { nav { grid-column: 1/ span 2; } main { grid-column: 3 / span 7; } aside { grid-column: 10 / span 3; } } }

En este caso vamos a usar la configuración de la plantilla de áreas para configurar el documento. Fíjate en cómo cambian las zonas de la plantilla para diferentes resoluciones de pantalla.

HEADER

MAIN

FOOTER

El código:

                        

HTML

<article class="grid-3"> <header class="encabezado"> <p>HEADER</p> </header> <nav class="navegacion"> <p>NAV</p> </nav> <main> <p>MAIN</p> </main> <aside class="relacionado"> <p>ASIDE</p> </aside> <footer class="pie-grid"> <p>FOOTER</p> </footer> </article>

CSS

.grid-3 { display: grid; gap: 0.5rem; grid-template-areas: 'cabecera' 'menu' 'lateral' 'principal' 'pie'; } .grid-3>* { border: 4px solid var(--color-base-luz); padding: 1rem; } .grid-3 .encabezado { grid-area: cabecera; } .grid-3 .navegacion { grid-area: menu; } .grid-3 main { grid-area: principal; } .grid-3 .relacionado { grid-area: lateral; } .grid-3 .pie-grid { grid-area: pie; } @media (min-width: 650px) { .grid-3 { grid-template-areas: 'cabecera cabecera cabecera' 'menu principal principal' 'lateral lateral lateral' 'pie pie pie'; } } @media (min-width: 1400px) { .grid-3 { grid-template-areas: 'menu cabecera cabecera cabecera cabecera lateral' 'menu principal principal principal principal lateral' 'pie pie pie pie pie lateral' ; } }