soy Kseso y esto EsCSS

CSS Grid Layout: guía básica para comenzar a usarlo

La guía más completa (hoy por hoy) en español para iniciarse en la construcción de layouts con puro CSS en base al módulo CSS Grid Layout y las propiedades en él desarrolladas. Incluye, además de la teoría, demos y enlaces a bibliografía sobre este módulo y otros complementarios como el CSS Box Alignment.

CSS Grid Layout: guía básica para comenzar a usarlo

·Por Kseso ✎ 5
CSS Grid Layout: guía básica para comenzar a usarlo

El flexbox nunca fue concebido, al igual que las tablas o los flotados, como herramienta para estructurar un documento o generar layouts. Pese a la imaginación y habilidad de los autores para adaptarlo a esta necesidad.

Lo que hace el flexbox es manejar y controlar a sus ítems de forma conjunta declarando a la caja flexible una serie de propiedades o a alguno de sus ítems de forma individual mediante otras:

  1. Elijes cuál es el eje principal (el horizontal o vertical) [flex-direction: row / column]
    • y el sentido en él (LTR vs RTL o de arriba abajo o contrario) [flex-direction: row-reverse / column-reverse]
    para acomodar sus ítems.
  2. Controla si ocupan una sóla línea o fuerzan la creación de nuevas [flex-wrap: nowrap / wrap / wrap-reverse;]
  3. Decides su distribución:
    • En el eje principal [justify-content: flex-start / flex-end / center / space-between / space-around]
    • En eje secundario [align-content: flex-start / flex-end / center / space-between / space-around / stretch]
    • Y también la alineación de los ítems respecto a ellos mismos [align-items: flex-start / flex-end / center / baseline / stretch]
  4. Puedes actuar sobre cada ítems de forma individual:
    • Los dibuja con independencia del orden de su aparición en el documento [order]
    • Gestiona cómo reparten sus ítems el espacio sobrante en cada línea de la caja flex [flex-grow]
    • Alterar la alineación general de 'align-content' de un ítem en particular [align-self: auto / flex-start / flex-end / center / baseline / stretch]

Entre otros aspectos.

Si te fijas verás que en el flexbox todo está enfocado a la gestión de sus ítems de forma lineal, incluidas las propiedades que se declaran a la caja flexible, todas se traducen en un comportamiento de sus ítems.

La gran diferencia del CSS Grid Layout respecto al Flexbox es que actúa sobre la propia caja grid: Estructura su espacio.

CSS Grid Layout genera una rejilla: divide el espacio del propio elemento en distintos compartimentos desde el CSS (sin necesidad de tocar el HTML) y controla la ocupación de estas zonas virtuales por los ítems del grid.

Si necesitas un ejemplo (salvando las distancias) para comprender mejor este aspecto piensa en las columnas CSS (o las regiones o exclusiones CSS). Aunque posíblemente la mejor analogía sería decir que el espacio del grid box sería como una tabla supervitaminada.

Qué es el CSS Grid Layout

En palabras de Rachel Andrew:

CSS Grid Layout es una especificación para la creación de rejillas bidimensionales. Te da la posibilidad de establecer en la página web una grilla y colocar con precisión los elementos ella. La especificación se encuentra actualmente en estado de borrador de trabajo.
El módulo CSS Grid Layout y el de Caja flexible (FlexBox) son complementarios. Flexbox está diseñado para el diseño en una sola dimensión, así que las cosas se pueden manejar en una línea ininterrumpida. CSS Grid Layout está diseñado para la disposición en dos dimensiones, es decir, sus ítems no tienen que ubicarse uno al lado del otro. En el futuro es seguro que utilicen conjuntamente: Diseño de cuadrícula depara los bloques principales de la página y FlexBox para los elementos de interfaz de usuario más pequeños.

Terminología del CSS Grid Layout

Antes de continuar, un poco de terminología propia del CSS Grid Layout para tener claros sus conceptos básicos:

Terminología básica del Css Grid Layout
Terminología básica del Css Grid Layout
Grid container o contenedor grid
Es el elemento contenedor en el que se establece la rejilla o grilla.
Grid Items
Los elementos hijos directos de la caja grid.
Grid lines o líneas de la rejilla
Son los divisores horizontales y verticales. Se utilizan para crear "grid tracks", "grid cells" y "grid areas". Por defecto y para identificarlas tienen un índice numérico, u opcionalmente se les puede dar nombres específicos.
Grid track
El espacio entre dos líneas paralelas. Las líneas son de utilidad para indicar dónde empieza y termina el contenido y los tracks en dónde se aloja.
Grid cell
Una celda es el espacio definido por dos líneas horizontales y dos verticales consecutivas.
Grid area
Un área es una figura rectangular que cubre un número arbitrario de celdas adyacentes. A las áreas, como a las líneas, puede dárseles nombres.

Creando el Grid Layout

Para lograr que un elemento genere una rejilla, a semejanza del flexbox, hay que declarar al elemento display: grid; o display:inline-grid

Pero este valor de la propiedad display únicamente prepara el terreno. Por sí sólo aún no ha creado ninguna rejilla. Para ello la especificación define tres propiedades más:

  1. grid-template-rows
  2. grid-template-columns
  3. grid-template-areas

Veamos un ejemplo relativamente sencillo de rejilla CSS. De momento necesitas un navegador con motor Blink (Xhrome, Canary, Cromium) y en chrome://flags habilitar 'experimentos de Web Platform'.

See the Pen obLevg by Kseso (@Kseso) on CodePen.

Para quienes accedan con un navegador que no de soporte al CSS Grid Layout a continuación tienes el resultado del pen anterior:

Composición con CSS Grid Layout
Composición con CSS Grid Layout

Vamos con sus códigos. Como ves el HTML no tiene nada de especial. Un section class='grid' como contenedor general y cuatro div´s en él:

<section class="grid"> <div class="item a">item A</div> <div class="item b">item B</div> <div class="item c">item C</div> <div class="item d">item D</div> </div>

Lo primero es hacer que el contenedor general pueda generar la grilla y cómo será:

.grid { display: grid; grid-template-columns: 30vw 2.5vw 30vw 2.5vw 30vw; grid-template-rows: auto 2.5vw auto; background: tomato; border: 2.5vw solid orange; }

Para ello declaramos su display con uno de los dos valores que lo convierten en un Grid container: grid. Y a continuación crear las filas y columnas que la seccionarán.

grid-template-rows: auto 2.5vw auto;: Creamos tres filas. La segunda fila la usaremos como separación entre contenidos (no colocaremos nada en ella) de una altura de 2.5vw y la altura de la primera y tercera en 'auto' para que sea resultado del contenido de los ítems.

grid-template-columns: 30vw 2.5vw 30vw 2.5vw 30vw;: Esta declaración crea una estructura de 5 columnas. Igual que antes las dos estrechas (2.5vw) servirán como separación y las tres restantes para ubicar en ellas los ítems del grid.

Las dos declaraciones restantes (fondo y borde) sólo están a efectos complementarios.

Las propiedades grid-template-rows y grid-template-columns admiten otras formas de declaración para facilitar la creación de rejillas complejas de forma más simple que usando medidas precalculadas. Volveremos a esto más adelante.

El siguiente paso será ubicar los ítems del grid en la grilla creada. Para ello podemos servirnos de las "grid lines" o "template areas".

Ubicando los ítems del CSS Grid Layout por líneas

Grid lines generadas al definir filas y columnas
Grid lines (en color blanco y numeradas) generadas al definir filas y columnas

Para utilizar las "Grid lines" nos servimos de las líneas generadas al definir el número de filas y columnas del grid layout. En la imagen previa las tienes dibujadas en blanco y numeradas.

.a { grid-column: 1 / 4; grid-row: 1 / 2; } .b { grid-column: 5 / 6; grid-row: 1 / 4; } .c { grid-column: 1 / 2; grid-row: 3 / 4; } .d { grid-column: 3 / 4; grid-row: 3 / 4; }

Al ítem a lo situamos en el área conformada por las líneas verticales número 1 y 4 y las horizontales número 1 y 2. Como ves este área ocupa 3 columnas y una sola fila.

El ítem b será dibujado en el área creada por las líneas horizontales número 1 y 4 (la primera y la última por lo que será toda la altura del grid container) y por las líneas verticales número 5 y 6 (al ser las últimas quedará situado junto al borde derecho del grid).

Los ítems c y d al estar sus áreas definidas por líneas adyacentes entre ellas ya nos indica que ocuparán una sola celda cada uno.

Forma extendida de grid-column y grid-row

Las propiedades grid-column y grid-row es la forma acortada (o shorthand). Cada una de ellas se puede desglosar en dos: su inicio y final. Así la regla .a {} del ejemplo previo podría declararse así:

.a { grid-row-start: 1; grid-row-end: 2; grid-column-start: 1; grid-column-end: 4; }

Declaración conjunta de grid-column y grid-row

También puedes optar por declarar conjuntamente ambas propiedades (usando una sola propiedad):

.a { grid-area: 1 / 1 / 2 / 4; }

Cuyo orden es grid-row-start, grid-column-start, grid-row-end, grid-column-end

Ubicando los ítems del CSS Grid Layout por "template areas"

La segunda forma de crear un CSS Grid Layout es definiendo áreas en vez filas y columnas. Y al mismo tiempo asignando nombres elegidos por nosotros a cada una de ellas. Esto facilita su identificación y trabajo con ellas.

Tengamos una página que queremos estructurar en los típicos encabezado, pie de página, dos columnas laterales y una sección con el contenido principal.

<div class="grid"> <header>h1</header> <div class="content" /> <nav /> <aside /> <footer /> </div>

Como en el ejemplo anterior al posicionar por líneas lo primero es hacer que nuestro div class='grid' genere la grilla y estructurarla:

.grid { display: grid; grid-template-columns: repeat(5, 1fr); grid-template-rows: repeat(3, auto); grid-template-areas: "header header header header header" "nav content content content sidebar" "footer footer footer footer footer"; }

Para generar las filas y columnas ahora usamos la función CSS con la palabra clave repeat() y dentro del paréntesis el número de ellas y su tamaño (altura en las filas y anchura en columnas).

El resultado es una rejilla de 3 filas de altura 'auto' == 'la que fuerce el contenido de los ítem' y 5 columnas de anchura definida con la nueva unidad fr: fracción del espacio libre en el grid container.

La declaración grid-template-columns: repeat(5, 1fr); es equivalente a grid-template-columns: 1fr 1fr 1fr 1fr 1fr; y su resultado se traduce en una anchura de 1/5 del grid container.

En este caso al Grid Container añadimos una nueva declaración con la propiedad grid-template-areas cuyo valor es una relación de nombres entre comillas separados por espacios en blanco.

A poco que fijes tu atención verás que hay tantas series entre comillas como filas (3) y dentro de cada una de ellas tantos nombres como columnas (5).

grid-template-areas: "header header header header header" "nav content content content sidebar" "footer footer footer footer footer";

Las Grid areas generadas por esta declaración CSS sería el esquema de bloques siguientes:

+--------+--------+--------+--------+
|              header               |
+--------+--------+--------+--------+
| nav    |     content     | sidebar|
+--------+--------+--------+--------+
|              footer               |
+--------+--------+--------+--------+

La coincidencia del nombre de las áreas con el nombre de elementos del HTML no es obligatoria. Puedes asignarle aquellos que prefieras.

Ocupando las áreas de la rejilla CSS

Ya tenemos nuestro HTML con una grilla creada con puro CSS en el contenedor general. Sólo nos queda colocar cada ítem del grid container en él utilizando los nombres de cada celda:

header { grid-area: header; } .content { grid-area: content; } nav { grid-area: nav; } aside { grid-area: sidebar; } footer { grid-area: footer; }

El resultado de todo esto lo puedes ver en el siguiente pen (si usas un navegador que le de soporte) fork del original de Rachel Andrew

See the Pen Grid Template Areas by Kseso (@Kseso) on CodePen.

Y en caso de que quisieses que tu footer sólo ocupe la anchura de 'content' sin extenderse por debajo del nav y aside basta con declarar los nombres de las áreas así:

grid-template-areas: "header header header header header" "nav content content content sidebar" ". footer footer footer .";

CSS Grid Layout y RWD

Conseguir que una estructura creada en base al CSS Grid Layout sea "responsive" es aún más sencillo que con cualquiera de las técnicas empleadas hasta ahora.

Esta última demo basta con declararle una media query para que, en pantallas estrechas, los ítems del grid ocupen toda la anchura:

@media (max-width: 550px) { .grid { grid-template-areas: "header header header header header" "nav nav nav nav nav" "content content content content content" "sidebar sidebar sidebar sidebar sidebar" "footer footer footer footer footer"; } }

Propiedades y módulos complementarios del CSS Grid Layout

La especificación además de las propiedades del CSS Grid Layout que hemos visto en esta pequeña guía para iniciarse viene con otras novedades para el control y la gestión de la rejilla creada desde CSS.

Gutters o espaciado entre celdas

Entre otras define la propiedad grid-gap que controla el espacio libre entre líneas lo que se traduce en crear huecos entre las celdas del grid. Es la forma acortada de grid-column-gap y grid-row-gap. Es similar a su homónima de las multicolumnas column-gap o al atributo de las celdas en tablas cellspacing

Así en la primera rejilla de esta demo se podrían evitar declarar las filas y columnas estrechas (de 2.5vw) utilizando la propiedad grid-gap

La propiedad Grid

'Grid' además de ser el valor de la propiedad display para convertir cualquier elemento contenedor en un grid container también es una propiedad del grupo del CSS Grid Layout.

La propiedad grid es la forma acortada (shorthand) para declarar conjuntamente las propiedades del grid:

  • Las propiedades explícitas
    • grid-template-rows
    • grid-template-columns
    • grid-template-areas
  • Las propiedades implícitas
    • grid-auto-rows
    • grid-auto-columns
    • grid-auto-flow
  • Sin embargo aunque las propiedades del grupo grid-gap no pueden declararse en el valor de la propiedad grid quedan reseteadas a su valor inicial: cero. Por lo que si declaras la propiedad grid y deseas establecer "gutters" tienes que declararlos (grid-gap) obligatoriamente después de ella.

Alineación y distribución en el CSS Grid Layout

Otro aspecto desarrollado en el módulo "CSS Grid Layout" es la distribución y alineación de los ítems del grid en ambos ejes y respecto a ellos mismo. A semejanza del flexbox.

Así tienes disponibles las diferentes propiedades:

  1. La alineación en el eje de las filas con las propiedades:
    • justify-self
    • justify-items
  2. La alineación en el eje de las columnas con las propiedades:
    • align-self
    • align-items
  3. La alineación de la grilla en la caja del propio grid container con las propiedades:
    • justify-content
    • align-content

El módulo CSS Box Alignment

Pese a que la distribución y alineación de los ítems haya sido contemplada tanto en la caja flexible (flexbox) como en la rejilla CSS un grupo de trabajo del W3c está desarrollando el nuevo módulo "CSS Box Alignment". En él se dan soluciones más completas y versátiles para este control.

Hace escasas fechas dediqué el artículo "CSS Grid y el módulo Box Alignment" en el que lo tienes explicado en profundidad.

Estado del CSS Grid Layout

Algunas cuestiones puntuales de este apartado ya no será tan "actuales" en el momento que puedas leer esta guía del CSS Grid Layout ya que fue escrita inicialmente en Diciembre de 2015. Otras sí, pues la he ido actualizando periódicamente.

De inminente uso. Ya está en uso aunque de momento apoyado en algún seguro pa´los viejos navs. Por lo tanto de conocimiento obligado. Aunque no lo creas el módulo relativo al CSS Grid Layout comenzó su andadura allá por el año 2011 a propuesta de Microsoft.

El 29 de Septiembre de 2016 el documento CSS Grid Layout Module Level 1 alcanzó el estatus de W3C Candidate Recommendation.

7 Mayo 2017: Firefox 52 cumple con sus previsiones e implementa soporte al CSS Grid Layout.
Chrome lo incluirá en su versión 57 prevista para el 14 de Marzo de 2017 y poco después Safari.

Si por algo se recuerda el desarrollo del módulo del Flexbox es por tantos vaivenes como sufrió. Cambio de nombres de propiedades y sus valores incluidos.

Parecía que los desarrolladores de los navegadores tenían una carrera por ver quién era el primero que implementaba su soporte en base a prefijos privativos. El resultado es toda la morralla de código obsoleto que necesitas declarar si deseas dar soporte a esas viejas versiones.

Todo ese accidentado camino no ha sido en balde. La experiencia de los errores en el desarrollo del flexbox ha sido de vital importancia en la formulación de los nuevos módulos surgidos tras él.

La nueva política de consorcio W3c respecto al uso de prefijos privativos también ayuda. Desautoriza y reniega de su uso y recomienda que cualquier novedad sea incluida sin ellos, sólo con el nombre y valores oficiales. Ver artículo "CSS Snapshot 2015".

Fruto de ello es que hoy día (Diciembre de 2015) el módulo CSS Grid Layout es toda una realidad que ha de ser tenida en cuenta y es de obligado seguimiento y conocimiento.

Si no lo haces así te encontrarás dentro de 6 u 8 meses que te habrás quedado desfasado por completo. Porque creo que como muy tarde a finales de 2016 el CSS Grid Layout se encontrará como el flexbox hace un año. Y lo sustituirá como herramienta para crear layouts basados en grillas.

Estamos obligados a experimentar ya con él para irlo dominando. Y has de exigir a quienes nos dedicamos a la divulgación de CSS que lo hagamos.

Para saber el estado actual en cualquier momento, recuerda que existe canIuse. A fecha de publicación de esta guía (12/2015):

  • IE´s: las últimas versiones implementan soporte a la inicial y vieja por obsoleta versión del documento.
  • Firefox y Chrome (ámbos) lo soportan en su mayor parte previa habilitación por el usuario.
Desconfía de quien hoy te "venda maquetar con CSS" y obvie cualquier referencia al CSS Grid Layout (lo llame "curso avanzado" o no es lo de menos).

Recursos y herramientas para el CSS Grid Layout

<ya_no_tanto>En español apenas si hay material con un mínimo de calidad sobre la construcción de grillas CSS en base al módulo CSS Grid Layout. Yo al menos las desconozco.

Por desgracia en los sitios de renombre en español dedicados a "enseñar CSS" tengo la sensación de que aún no consideran que merezca la pena dedicar su tiempo, recursos y esfuerzo a este módulo. Me fue imposible localizar nada para compartirlo aquí contigo.</ya_no_tanto>

Para conocer y dominar el CSS Grid Layout

Así que sólo me resta enlazarte artículos en español sobre el módulo CSS Grid Layout de este mismo blog y el resto de trabajos en inglés:

  1. CSS Grid Layout Module Level 1

    La especificación. Editor’s Draft, 17 December 2015.
  2. CSS Grid Layout en EsCss:

  3. Si hay quien está realizando una gran labor (encomiable) sobre el CSS Grid Layout esa es Rachel Andrew [aka @rachelandrew]. Obligados son sus artículos de investigación y divulgación del CSS Grid Layout así como demos de rejillas CSS construidas con él:
    • El blog de Rachel Andrew

      en él encontrarás multitud de artículos sobre el CSS Grid Layout.
    • Grid by Example

      sitio de Rachel Andrew dedicado en exclusiva el Grid Layout. Incluye además de cuestiones teóricas multitud de grillas CSS construidas en base al él comentadas y explicadas.
    • CSS Layout News

      Una colección semanal de tutoriales, noticias e información sobre los diferentes CSS Layout.
    • The New CSS Layout - dotCSS

      slides de la conferencia de Rachel Andrew en dotCSS 2015
  4. How to create an adaptive layout with CSS Grid

    De Microsoft. OjO Cuidao con este artículo porque sólo usa propiedades con su prefijo privativo -ms-. Lo traigo aquí por el proceso, no por los códigos.
  5. CSS Grid Layout Examples

    Más ejemplos, estos en Github.

avatar del Editor del blog

the obCSServer ᛯ Ramajero Argonauta, Enredique Amanuense de CSS.
#impoCSSible inside
Dicen que, en español, EsCss es el mejor blog de CSS. Posíblemente exageren.
@Kseso EsCss Kseso