soy Kseso y esto EsCSS

CSS Grid Layout: la revolución que esperas y que ya ha comenzado

CSS Grid Layout: la revolución que esperas y que ya ha comenzado

✎ 3
COLABORACIÓN AUTOR INVITADO
CSS Grid Layout: la revolución que estabas esperando ya llegó

Yo suelo dividir el corpus de Css, de forma informal o coloquial, en tres grandes grupos:

  1. Estructural: Los documentos (y las propiedades desarrolladas en ellos) dedicados a la composición de la página (su estructura o layout).
  2. Tipográficos: Los que permiten controlar los aspectos relativos a la cuestión tipográfica. Tan vital como el anterior. Unos contenidos ilegibles o o que no inviten a ello hacen abandonar la página tanto como un layout descompuesto.
  3. Decorativos: Aquellas otras que son estéticas o decorativas (para hacerla bonita según gustos).

Y son los englobados en el primero, los estructurales, los que mayor impacto tienen en eso de hacer webs. Como el Flexbox, que posíblemente sea el desarrollo que mayores cambios ha supuesto, hasta la fecha.

Dentro de estos, y una vez que parece ha alcanzado suficiente madurez (creo), ha llegado el momento de fijar nuestra atención en otro de los documentos del consorcio que, de nuevo creo yo, va a suponer otra revolución como lo fue el flexbox.

Para ello me tomo la libertad de transcribir el artículo de Patrick Brosset aka @patrickbrosset publicado en medium sobre el Grid Layout de Css.

Ya tienes disponible en el blog el artículo:

CSS Grid Layout: guía básica

El futuro del layout con Css: Grid Layout

En este artículo vamos a echar un vistazo al maravilloso mundo del grid layout de CSS , una relativamente nueva especificación del W3C, que ya ha comenzado a tener soporte (en parte) en algunos navegadores.

Pero antes de sumergirse en lo que es esta nueva técnica de CSS y cómo usarlo, revisemos rápidamente la teoría del grid layout.

Mi brevísima introducción a la teoría de la rejilla

Yo no soy un diseñador ni conozco mucho sobre la teoría de la rejilla antes de tropezar con la especificación CSS Grid Layout, así que no te quedes con mi idea sobre ella y busca otras por ti mismo. Pero si no te importa que la aporte, aquí va mi opinión al respecto:

En esencia, una rejilla es un conjunto de líneas verticales y horizontales invisibles para colocar los contenidos (o sus partes y diseños) de una página web, revista o periódico.

El objetivo de una red es la de servir como base para la colocación de las diferentes partes de contenido y para asegurarse que están alineados y espaciados uniformemente. Una rejilla, incluso si no es visible, ofrece al usuario una ayuda visual para navegar por el contenido.

Entonces, ¿qué tiene que ver Css con eso?

CSS nos ofrece un conjunto de propiedades totalmente nuevas que, cuando se usan conjuntamente, permiten definir la cuadrícula y el contenido que irá en ellas.

Estas propiedades se definen en el documento CSS Grid Layout.

CSS no es conocido precisamente por su capacidad de manejar diseños complejos. Aunque esto pudo no ser un problema cuando CSS salió por primera vez, con el paso de los años se ha convertido en algo común: la complejidad de los diseños y su gestión con Css.

La gente ha sido muy creativa mediante el uso de flotados o posicionamiento absoluto y la gran variedad de frameworks surgidos.

Así que ha llegado la hora de que Css ofrezca soluciones para lidiar con estos diseños tan comunes hoy día.

¿Puedo usarlo ya?

Sí se puede empezar a utilizar ya, pero sólo Chrome ha implementado la especificación lo suficiente como para jugar con el Css Grid Layout, pero hay que habilitarlo en su configuración ya que por ahora viene de serie en off.

IE hizo una implementación temprana (que data de IE10) también, pero la especificación ha evolucionado desde que fue agregado, así que no es totalmente compatible con él.

Firefox ha comenzado también su implementación, así que no debería retrasarse mucho el poder experimentar en él.

Finalmente también hay un polifyll, por lo que no tienes excusas para jugar con el Grid Layout de Css.

Nota de KsesoCss: en canIuse puedes consultar este aspecto.
Y en igalia.github.io cómo habilitarlo en los distintos navegadores.

Así pues, ¿qué es el Css Grid Layout?

En el fondo, un diseño de cuadrícula en CSS es un conjunto de líneas verticales y horizontales que definen las celdas en las que se puede colocar arbitrariamente el contenido .
Así que de alguna manera recuerda una table, a excepción de algunas diferencias clave que veremos más adelante.

celdas creadas por las líneas del Css Grid Layout
Bloques de una rejilla

La imagen anterior muestra los bloques construidos por una rejilla:

  • Líneas: en este caso hay 4 líneas verticales y 3 horizontales. Las líneas se numeran comenzando por 1. Las líneas verticales se muestran de izquierda a derecha, dependiendo de la dirección de la escritura direction.
    A las líneas, opcionalmente, se les puede asignar nombres, lo que facilita referenciarlas en el Css como veremos luego.
  • Tracks es símplemente el espacio entre dos líneas paralelas. Así, en el ejemplo de la imagen anterior, hay 3 tracks verticales y 2 horizontales.
    Las líneas son de utilidad para indicar dónde empieza y termina el contenido y los tracks en dónde se aloja.
  • Celdas: una celda es el espacio definido por las líneas horizontales y verticales. En la imagen previa sólo una celada ha sido resaltada, pero hay 6 en la rejilla.
  • Áreas: un área es una figura rectangular que puede extenderse sobre un número arbitrario de celdas. A las áreas, como a las líneas, pueden dárseles nombres. En la figura anterior de la rejilla, podemos por ejemplo definir las áreas A,B y C como ves a continuación:
áreas en una rejilla Css
Áreas con nombre en una rejilla Css

Ahora que conocemos estos sencillos conceptos vamos a fondo con lo que le da toda su potencia.

Un punto clave de la rejilla Css es que realmente logra la separación del contenido y su presentación.

De hecho, la rejilla está completamente definida en el CSS. Esto significa que, aparte del elemento HTML padre al que se le declara la rejilla, no hay necesidad de definir los elementos adicionales para las columnas, filas, celdas o áreas.

Si piensas en esto, es una característica realmente interesante. Un aspecto de esto es que el orden en el que el contenido se aparece en el HTML ya no importa. También significa que el marcado HTML será más liviano y más fácil de entender, y, por lo tanto, más fácil de mantener.

Pero lo más importante, esto le da una herramienta muy poderosa para separar el contenido de su disposición, liberándolos efectivamente, de tal manera que realizar un cambio en cualquiera de ellos ni afecta y rompe al otro.

Como diseñador, podrás experimentar fácilmente con nuevos diseños sin tener que cambiar nada más que CSS, ya que el nuevo diseño proporciona las líneas y áreas utilizas por el contenido.

Y como desarrollador, sólo tendrás que usar los números o nombres de las líneas y áreas para alojar el contenido en la rejilla.

Imagina el sencillo grid layout siguiente:

Sencillo grid layout Html
Sencillo Html grid layout

En este diseño, se han definido las zonas por su nombre, permitiendo que el contenido pueda ser alojado en ellas de forma sencilla haciendo referencia a estos nombres. Esto significa que no sólo podemos cambiar esta disposición relativa con facilidad en el futuro, siempre y cuando mantengamos las regiones nombradas (en este caso el nombre de las regiones actúan en cierta forma como el diseño de una API), si no que también se pueden usar las @medias queries para un cambio dinámica.

Recuerda, todo el layout se define en el CSS, así las @medias queries y el Css grid layout se complementan muy bien.

Por ejemplo, en pantallas pequeñas podremos cambiar la disposición anterior con una @media query a algo como ésto:

el diseño anterior en pantallas pequeñas
El mismo diseño en pantalla pequeña

Basta de teoría y vamos a ver cómo se construyen estos diseños sólo con el Css Grid Layout.

Creando rejillas con Css

Para definir una regilla sólo se necesita un elemento en el HTML: el contenedor de la cuadrícula (grid container). Este es el elemento en el que se creará el layout.

Cualquier elemento hijo del grid container es un grid item. Estos grid item son los que se ubicarán en la rejilla.

Configurar un elemento como grid container es tan sencillo de lograr como:

.container { display: grid; }

Nota de KsesoCss: sí. Exáctamente igual que en el flexbox.

Sin embargo, esto por sí sólo no es suficiente. Hemos de definir cómo se configura la rejilla: su número de columnas y filas y su tamaño.

Esto se puede hacer usando plantillas de rejillas como en el siguiente ejemplo:

.container { display: grid; grid-template-rows: 200px 100px; grid-template-columns: repeat(4, 100px); }

En este ejemplo estamos definiendo una rejilla que tiene 2 filas y 4 columnas. Observa que la función Css repeat() es utilizada aquí para evitar tener que repetir 4 veces el tamaño de los tracks (la separación de las líneas) de las columnas. Aquí es equivalente a 100px 100px 100px 100px

Al definir cada uno de los tracks así se asignan tamaños, por lo que la rejilla termina con una estructura y aspecto como el siguiente:

resultado de la regla anterior
Layout resultado de la regla Css anterior

Pero la rejilla también pueden ser implícitamente definidas así:

.container { display: grid; grid-template-rows: auto; grid-template-columns: repeat(4, 100px); }

En este caso, el navegador seguirá añadiendo tantas filas como sea necesario para que el contenido quepa.

Ahora vamos a añadir algo de contenido. Hasta ahora sólo teníamos 2 niveles de elementos, el contenedor y sus ítems, así que vamos a usar el siguiente Html:

<div class=”container”> <div class=”item1">item 1</div> <div class=”item2">item 2</div> <div class=”item3">item 3</div> <div class=”item4">item 4</div> <div class=”item5">item 5</div> </div>

Lo cual, sin ningún código CSS a mayores para colocar los ítems, nos lleva a la siguiente disposición:

Bloques resultantes del html y Css anterior
Esquema de bloques resultante del Html y Css previos

Como puedes observar, como no indicamos dónde se deben colocar los ítems en la rejilla es el navegador el que los ubica de forma automática colocando elemento por elemento hasta rellenar la primera fila, tras lo cual pasa el resto a la siguiente fila.

La especificación define un algorritmo para colocar automáticamente los ítems en la rejilla si no se les ha asignado una posición. Esto a veces puede ser útil si son muchos o su número es dinámico (y variable) y no quieres o puedes definir su ubicación para todos y cada uno de ellos.

Vamos a ver ahora cómo ubicar cada ítem en la rejilla.

.item1 { grid-row-start: 1; grid-row-end: 2; grid-column-start: 1; grid-column-end: 3; } .item2 { grid-row-start: 1; grid-row-end: 2; grid-column-start: 3; grid-column-end: 5; }

Con esto definimos la ubicación de los 2 primeros ítems, lo que significa que los restantes serán ubicados automáticamente por el navegador. Tal que así:

Esquemas de bloques resultante
Esquema de bloques resultante del Html y Css previos

El ejemplo anterior utiliza la colocación basada en la líneas: utiliza los índices numéricos de las líneas para colocar los elementos.
Los ítems 1 y 2 están definidos para ser colocados entre las líneas horizontales 1 y 2, y entre las líneas verticales 1 y 3 y 3 y 5 respectivamente.

¿Qué pasa ahora si seguimos añadiendo elementos, pero no hay definidas más celdas en la rejilla para recibirlos?

Css grid layout expandido
Gestión de ítems añadidos sin definir su Css

La estructura de la cuadrícula se mantiene añadiendo tantas filas y columnas como sean necesarias. Ten en cuenta que las medidas de los nuevos tracks o espacios dependerán del tamaño del contenido.

Todo esto está muy bien, pero además la propuesta del Css Grid Layout llega con otra utilidad que mencionada antes: las áreas.

En primer lugar hay que definir el contenedor de la cuadrícula grid container, sus espacios tracks y áreas:

.container { display: grid; grid-template-rows: 100px auto 100px; grid-template-columns: 100px auto; grid-template-areas: "header header" "sidebar content" "footer footer"; }

En este ejemplo hemos definido 3 filas, la superior e inferiore de 100px de alto, mientras que el del medio se adapta a su contenido. También hemos definido 2 columnas, la izquierdo de 100px de ancho, y la derecha que se adapta también a su contenido.

También hemos añadido la propiedad grid-template-areas. Puede parecer rara (por su valor) pero es realmente sencilla: es una representación de la rejilla asignándole nombres. Lo vemos.

Le hemos dicho que la rejilla tenga 3 filas y 2 columnas. Si la dibujamos con ascii-art sería algo así:

+---+---+ | . | . | +---+---+ | . | . | +---+---+ | . | . | +---+---+

Cada punto es una celda donde las áreas pueden ser definidos. Así que vamos a definir áreas para una disposición típica en una página web:

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

Queremos que el encabezado y el pie de página se extiendan para abarcar todo el ancho, por lo que los hemos repetido en las 2 columnas.
Ahora quitamos todos los elementos del ascii-art y entrecomillamos el contenido de cada fila:

"header header" "sidebar content" "footer footer"

que es exáctamente como se conforman las áreas de la rejilla de Css en el valor de la propiedad grid-template-areas. Quizás te ayude si piensas en ello como una representación en 2D de la rejilla Css y la que a cada área se le da un nombre para alinearlas.

También se pueden utilizar puntos . cuando una celda no es cubierta por ningún área. Aquí un ejemplo:

.container { display: grid; grid-template-rows: repeat(5, 100px); grid-template-columns: repeat(5, 100px); grid-template-areas: ". . . . ." ". . . . ." ". . a . ." ". . . . ." ". . . . ."; }

En este ejemplo hay 25 celdas y un área que es definida para ocupar sólo la celda central.

Ahora volvamos al ejemplo previo del header, sidebar, content, footer y añadamos un poco más de marcado:

<div class="container"> <div class="header">header</div> <div class="sidebar">sidebar</div> <div class="footer">footer</div> <div class="content"> <p>Lorem ipsum dolor sit amet...</p> </div> </div>

Ahora lo último que necesitamos hacer es colocar cada ítem de la rejilla (grid item) en su correspondiente área (convenientemente hemos usado nombres de áreas que coinciden con el valor del atributo class de cada div).

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

Cuyo resultado sería algo como lo siguiente:

Resultado Css Grid Layout
Resultado Css Grid Layout

Ahora si en cualquier momento quisiésemos alterar esta disposición, podremos adaptarla a otros tamaños de pantalla con las @media queries. Sólo tendremos que cambiar los valores relativos al grid-template-*. Quizás a algo así:

.container { display: grid; grid-template-rows: auto; grid-template-columns: 100%; grid-template-areas: "header" "sidebar" "content" "footer"; }

Lo que sin ningún otro cambio en el Css o el marcado Html produciría ésto:

distinta estructura en tamaños pequeños
Adaptación por Css Grid Layout en pantallas pequeñas

Podríamos reorganizar completamente el orden en que se muestran los ítems en la rejilla sin necesidad de cambiar nada en el marcado html (su aparición en él).

Nota de KsesoCss: Antes de continuar con el siguiente apartado del artículo original me tomo la libertad de mencionar una novedad del documento Css Grid Layout:

La unidad fr (fracción) o flexible length

Para manejar de forma eficiente el espacio generado por la rejilla Css, el documento "Css Grid Layout" define el valor fr como una unidad de longitud flexible y relativa, cuyo valor representa una fracción del espacio libre del grid item (el que quede vacío si sus ítems no lo cubren por completo).
Su valor está comprendido entre 0 y 1.
Su nombre fr viene de fraction (fracción).

Css Grid en el mundo real

Hasta ahora sólo hemos visto ejemplos simples de layouts, pero los sitios web que hacen uso de los sistemas de rejillas a menudo tienen estructuras mucho más complejas en su estructura. No es raro que estos sitios web estén basados en 12 columnas, cada uno de ellas separadas por "canales" (columnas estrechas utilizadas para espaciar o separar los ítems) a modo de márgenes.

Tomamos dribbble.com como ejemplo. Este sitio web hace uso de una cuadrícula para mostrar los diseños subidos por los usuarios. Aquí la parrilla es fácilmente reconocible porque cada diseño ocupa exactamente una celda (excluyendo el espaciado entre las filas y columnas):

Css grid layout de dribbble.com
Css grid layout de dribbble.com

El diseño de la cuadrícula de Dribbble también es responsive, por lo que si cambia el tamaño de la ventana gráfica, el tamaño y el número de columnas cambia poco a poco, como se muestra en la siguiente animación:

gif Adaptación RWD del Css grid layout de dribbble.com
Adaptación "RWD" del Css grid layout de dribbble.com

Usando las nuevas propiedades que vienen con el documento CSS Grid Layout podemos tratar de recrear un diseño de similar al de dribbble. Con un toque adicional, vamos a insertar un nuevo elemento conteniendo texto en la segunda fila, y que la ocupe por completo.

En primer lugar el marcado Html sería algo así:

<ul class="dribbbles"> <li class="dribbble">...</li> <li class="dribbble">...</li> ... <li class="dribbble">...</li> <li class="advert">Some text ....</li> </ul>

Donde el elemento con clase dribbbles representa el contenedor principal de todos los ítems, y cada dribbble a los distintos diseños mostrados (los ítems). El último elemento, con clase advert es la parte de contenido textual que queremos mostrar en la segunda fila.

Ahora, construyamos la rejulla para ello:

.dribbbles { display: grid; /* Permíteme presuponer que el diseño tiene una anchura fija por defecto */ width: 880px; grid-template-columns: repeat(4, 220px); grid-template-areas: ". . . ." "advert advert advert advert"; justify-items: center; } .advert { grid-area: advert; }

Hemos definido 4 columnas en nuestro layout. No hemos dicho nada sobre las filas, por lo que el navegador creará automáticamente tantas filas como sean necesarias.

Lo que también hicimos fue marcar una fila utilizando la propiedad grid-template-areas porque tenemos que colocar nuestro contenido de texto en la segunda fila. Así que lo que le hemos indicado es que queremos una primera fila con celdas vacías que van a ser rellenadas automáticamente con los items de grid, tal como aparezcan, y luego una segunda fila que define el área (para el elemento de texto class='advert') que se extiende por todas las 4 columnas.

Por último, la segunda regla declaramos la propiedad grid-area a para ubicar en el área con nombre advert el item de la rejilla con la clase advert.

El marcado Html anterior con este Css terminaría luciendo tal que así:

Layout tipo dribbble con Css Grid Layout
Layout tipo dribbble con Css Grid Layout

Bastante sencillo, ¿no? Por supuesto, esto requiere un poco más de código Css para hacer que los items luzcan tan bién, pero el código CSS para construir la estructura es así de corto y no necesita añadir más marcado.

Ahora ya podemos hacerlo responsive también. Digamos que queremos pasar a un diseño de 3 columnas para pantallas más pequeñas:

@media (max-width: 880px) and (min-width: 660px) { .dribbbles { width: 660px; grid-template-columns: repeat(3, 220px); grid-template-areas: ". . ." "advert advert advert"; } }

Y así sucesivamente, para todos los puntos de ruptura que necesitemos cubrir. Y así, sólo con añadir un par @medias queries, podríamos terminar con algo como esto:

Layout responsive tipo dribbble con Css Grid Layout
Layout "responsive" tipo dribbble con Css Grid Layout

Sitios como Dribbble aún no usan el Css Grid Layout, pero por ahí andan librerías Css de sobra conocidas que proveen sistemas de rejillas.

Un buen ejemplo de grilla Css es the Bootstrap CSS library, pero hay muchas más, como PureCSS, 960 Grid System, Responsive Grid System,Materialize entre otras.

Lamentablemente estos sistemas de rejillas tienen que afinar cuidadosamente los tamaños y flotados de los elementos, así como marcado (y elementos) a mayores para construir las filas y columnas y recurrir a los pseudoelementos para limpiar los flotados.

No es que todo ello sea demasiado complejo, después de todo los "trucos" en los que estas librerías se basan son sobradamente conocidos desde hace años. Pero son sólo eso, "trucos". Y ya es hora que contemos con una solución integrada en Css para deshacernos de ellos.

No me malinterpreten, estas librerías son impresionantes de todas formas. Y lo más importante, nos ayudaron a comprender que se necesitaba una nueva funcionalidad Css para definir las rejillas en la composición de las webs.

Y esto es precisamente lo que hace el nuevo documento Css Grid Layout.

Epílogo y referencias

Como vimos, el CSS Grid Layout es una buena herramienta para la configuración de los diseños que tienen como características la sencillez de creación, el mantenimiento, la separación de contenido y presentación y que se manejan bien con el responsive web design.

Pero en este artículo sólo hemos arañado la superficie de lo que es posible lograr con el Css Grid Layout. Las posibilidades de las distintas propiedades y su sintaxis permiten hacer un montón de cosas muy interesantes, y sólo espero que este artículo haga que desees profundizar en ellas por ti mismo.

A continuación algunos enlaces interesantes por si quieres saber un poco más:

Créditos y reconocimiento de autoría

Patrick Brosset

La totalidad del artículo, imágenes y demostraciones incluidas, es obra de Patrick Brosset (aka @patrickbrosset).
Publicado originalmente en inglés en medium.com bajo el título The future of layout with CSS: Grid Layouts
Patrick Brosset es miembro del equipo Firefox developer tools
En este último enlace puedes encontrar más información sobre él y sus trabajos.
Yo sólo me he limitado a trasladarlo al español, y, como soy consciente de mis limitaciones y carencias, con mis e(ho)rrores mis disculpas.
Traducción con conocimiento y consentimiento del autor.