CSS Grid Layout: la revolución que esperas y que ya ha comenzado 30.8.15
Traducción al español del artículo original [ING] de Patrick Brosset "The future of layout with CSS: Grid Layouts" en el que explica y explora las novedades y posibilidades que trae el nuevo documento del consorcio W3c que desarrolla la construcción de rejillas con puro Css.
Al final del artículo tienes toda la información y enlaces sobre el autor y su artículo.
CSS Grid Layout: la revolución que esperas y que ya ha comenzado
Yo suelo dividir el corpus de Css, de forma informal o coloquial, en tres grandes grupos:
- Estructural: Los documentos (y las propiedades desarrolladas en ellos) dedicados a la composición de la página (su estructura o layout).
- 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.
- 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:
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.
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 lostracks
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:
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:
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:
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:
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:
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í:
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?
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:
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:
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).
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
frviene 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):
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:
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í:
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:
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:
- La especificación www.w3.org/TR/css-grid-1/
- Algunos ejemplos por Rachel Andrew: http://gridbyexample.com/
- Más ejemplos en http://igalia.github.io/css-grid-layout/index.html
- Bug a seguir en la implementación en Firefox: https://bugzilla.mozilla.org/show_bug.cgi?id=616605
- Cómo usarlo en IE: https://msdn.microsoft.com/en-us/library/hh673533%28v=vs.85%29.aspx
- Si hay una charla que necesitas conocer, podría ser ésta de Rachel Andrew:
- Y la charla de Manuel Rego también es muy útil:
Créditos y reconocimiento de autoría
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.
se ve impresionante
ResponderEliminarVaya, yo llevo unos años con un tema parecido en http://soy-nudista.org me parece una evolución lógica.
ResponderEliminarEsta página es la mejor definitivamente
ResponderEliminar