MDN’s new design is in Beta! A sneak peek: https://blog.mozilla.org/opendesign/mdns-new-design-beta/

Conceptos básicos del posicionamiento con rejillas

Esta traducción está incompleta. Por favor, ayuda a traducir este artículo del inglés.

CSS Grid Layout presenta un sistema de rejilla bidimensional para CSS. Las rejillas se pueden utilizar para posicionar un área mayor de la página o pequeños elementos de interfaz de usuario. Este artículo presenta CSS Grid Layout y la nueva terminología que forma parte de la especificación CSS Grid Layout Nivel 1. Las características mostradas en este resumen se explicarán con mayor detalle en el resto de esta guía.

¿Qué es una rejilla?

Una rejilla es un conjunto de líneas horizontales y verticales que se intersectan - un conjunto que define columnas y el otro filas. En los elementos de la rejilla se pueden colocar respetando estas líneas, columnas y filas. El diseño de rejilla CSS tiene las siguientes características:

Tamaños de vía (track) fijos y flexibles

Usted puede crear una rejilla con tamaños de track fijos, utilizando píxeles, por ejemplo. También puede crear una rejilla utilizando tamaños flexibles con porcentajes o con la nueva unidad fr diseñada para este propósito.

Posicionamiento de elementos

Puede colocar elementos en una ubicación precisa en la rejilla utilizando números de línea, nombres o seleccionando un área de la rejilla. Grid también contiene un algoritmo para controlar la colocación de elementos que no tienen una posición explícita en la rejilla.

Creación de tracks adicionales para alojar contenido

Usted puede definir una rejilla explícita con grid layout, pero la especificación también trata con contenido agregado fuera de una rejilla declarada, agregando filas y columnas adicionales según sea necesario. Se incluyen características como la adición de "tantas columnas como caben en un contenedor".

Control de alineación

Grid contiene características de alineación para poder controlar cómo se alinean los elementos una vez colocados en un área de rejilla y cómo está alineada toda la rejilla.

Control de contenido superpuesto

Se puede colocar más de un elemento en una celda de rejilla o las áreas pueden solaparse parcialmente entre sí. Esta estratificación puede luego ser controlada con z-index.

Grid es una poderosa especificación y cuando se combina con otras partes de CSS como flexbox, puede ayudarle a crear diseños que antes eran imposibles de construir en CSS. Todo comienza creando una rejilla en su contenedor de rejilla.

El Contenedor de Grid

Creamos un contenedor de rejilla al declarar display: grid o display: inline-grid en un elemento. Tan pronto como hagamos esto todos los hijos directos de ese elemento se convertirán en elementos de la rejilla.

En este ejemplo tengo un div contenedor con una clase wrapper, dentro hay cinco elementos hijos.

<div class="wrapper">
   <div>One</div>
   <div>Two</div>
   <div>Three</div>
   <div>Four</div>
   <div>Five</div>
</div>

Hago de .wrapper un contenedor de rejilla.

.wrapper {
  display: grid;
}

<button class="open-in-host">Open in codepen </button><button class="open-in-host">Open in jsfiddle </button>

<button class="open-in-host">Abrir en codepen </button><button class="open-in-host">Abrir en jsfiddle </button>

Todos los descendientes directos son ahora elementos de la rejilla. En un navegador web usted no verá ninguna diferencia en cómo se mostraron los elementos antes de convertirlos en una rejilla ya que grid ha creado una rejilla de una sola columna para los elementos. En este punto usted puede encontrar útil trabajar en Firefox Developer Edition, el cual  tiene el Grid Inspector disponible como parte de las Herramientas de Desarrollador. Si ve este ejemplo en Firefox e inspecciona la rejilla, verá un icono pequeño junto al valor grid. Haga clic sobre este y la rejilla de este elemento se superpondrá en la ventana del navegador.

Using the Grid Highlighter in DevTools to view a grid

Mientras usted aprende y luego trabaja con CSS Grid Layout esta herramienta le dará una mejor idea de lo que está sucediendo con sus rejillas visualmente.

Si queremos empezar a hacer esto más parecido a una rejilla necesitamos agregar tracks (vías) de columna.

Vías de Grid

Definimos filas y columnas en nuestra rejilla con las propiedades grid-template-columns y grid-template-rows. Éstas definen las vías de la rejilla. Una vía de rejilla es el espacio entre dos líneas dentro de la rejilla. En la imagen inferior se puede ver una vía resaltada - la primera vía de fila en nuestra rejilla.

Puedo incrementar nuestro ejemplo anterior al agregar la propiedad grid-template-columns, luego definiendo el tamaño de las vías de columna.

He creado ahora una rejilla con tres vías de columna de 200 píxeles. Los elementos hijo se posicionarán en esta rejilla uno en cada una de las celdas de la rejilla.

<div class="wrapper">
   <div>One</div>
   <div>Two</div>
   <div>Three</div>
   <div>Four</div>
   <div>Five</div>
</div>
.wrapper {
  display: grid;
  grid-template-columns: 200px 200px 200px;
}

<button class="open-in-host">Abrir en codepen </button><button class="open-in-host">Abrir en jsfiddle </button>

La Unidad fr

Las vías se pueden definir usando cualquier unidad de longitud. Grid también presenta una unidad de longitud adicional para ayudarnos a crear vías de rejilla flexibles. La nueva unidad fr representa una fracción del espacio disponible en el contenedor de la rejilla. La siguiente definición de rejilla crearía tres vías con el mismo ancho que se expanden y se encogen de acuerdo el espacio disponible.

<div class="wrapper">
   <div>One</div>
   <div>Two</div>
   <div>Three</div>
   <div>Four</div>
   <div>Five</div>
</div>
.wrapper {
  display: grid;
  grid-template-columns: 1fr 1fr 1fr;
}

<button class="open-in-host">Abrir en codepen </button><button class="open-in-host">Abrir en jsfiddle </button>

En este próximo ejemplo creamos una definición con una vía de 2fr y luego dos vías de 1fr. El espacio disponible se divide en cuatro. Dos partes corresponden a la primera vía y una parte a las dos siguientes.

.wrapper {
  display: grid;
  grid-template-columns: 2fr 1fr 1fr;
}

En este ejemplo final mezclamos las vías de tamaño absoluto con unidades de fracción. La primera vía tiene 500 píxeles, por lo que este ancho fijo se sustrae del espacio disponible.El espacio restante se divide en tres y se asigna en proporción a las dos vías flexibles.

.wrapper {
  display: grid;
  grid-template-columns: 500px 1fr 2fr;
}

Listando vías con la notación repeat()

Rejillas grandes con muchas vías pueden utilizar la notación repeat() con le fin de repetir todas o una sección de la lista de vías. Por ejemplo la definición de rejilla:

.wrapper {
  display: grid;
  grid-template-columns: 1fr 1fr 1fr;
}

También puede ser escrita así:

.wrapper {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
}

La notación de repetición se puede utilizar para una parte del listado de vías. En este siguiente ejemplo he creado una rejilla con una vía inicial de 20 píxeles luego una sección repetitiva de 6 vías de 1fr y luego una vía final de 20 píxeles.

.wrapper {
  display: grid;
  grid-template-columns: 20px repeat(6, 1fr) 20px;
}

La notación de repetición toma una lista de vías, por lo tanto, puede utilizarla para crear un patrón de repetición de vías. En este próximo ejemplo, mi rejilla consistirá de 10 vías, una vía 1fr seguida por una vía 2fr, repetida cinco veces.

.wrapper {
  display: grid;
  grid-template-columns: repeat(5, 1fr 2fr);
}

La rejilla implícita y explícita

Al crear nuestra rejilla de ejemplo definimos nuestras vías de columna con la propiedad grid-template-columns, pero dejamos que grid cree filas según sea necesario para el contenido. Estas filas se crean en la rejilla implícita. La rejilla explícita consiste en las filas y columnas que se definen con grid-template-columns y grid-template-rows. Si coloca algo fuera de esa rejilla definida, o debido a la cantidad de contenido, se necesitarán más vías de rejilla, entonces la rejilla crea filas y columnas en la rejilla implícita. Estas vías varía su tamaño automátivamente de forma predeterminada, así que ajustarán su tamaño basadas en el contenido dentro de ellas.

También puede definir un tamaño para el conjunto de vías creadas en la rejilla implícita con las propiedades grid-auto-rows y grid-auto-columns.

En el siguiente ejemplo usamos grid-auto-rows para asegurar que las vías creadas en la rejilla implícita tengan 200 píxeles de alto.

<div class="wrapper">
   <div>One</div>
   <div>Two</div>
   <div>Three</div>
   <div>Four</div>
   <div>Five</div>
</div>
.wrapper {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  grid-auto-rows: 200px;
}

<button class="open-in-host">Abrir en codepen </button><button class="open-in-host">Abrir en jsfiddle </button>

Tamaño de vía y minmax()

Al configurar una rejilla explícita o definir el tamaño de las filas o columnas creadas automáticamente, es posible que desee dar a las vías un tamaño mínimo, pero asegúrese de que se expandan para adaptarse a cualquier contenido que se pueda agregar. Por ejemplo, tal vez quiera que mis filas nunca se colapsen a menos de 100 píxeles, pero si mi contenido se extiende a 300 píxeles de altura, me gustaría que la fila se expandiera a esa altura.

Grid tiene una solución para esto con la función minmax(). En el ejemplo siguiente estoy usando minmax() en el valor de grid-auto-rows. Las filas creadas automáticamente tendrán como mínimo de 100 píxeles de alto y un máximo de auto. El uso de auto significa que el tamaño mirará el tamaño del contenido y se estirará para dar espacio al elemento más alto en una celda en esta fila.

.wrapper {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  grid-auto-rows: minmax(100px, auto);
}
<div class="wrapper">
   <div>One</div>
   <div>Two
   <p>I have some more content in.</p>

<p>This makes me taller than 100 pixels.</p>
</div>
   <div>Three</div>
   <div>Four</div>
   <div>Five</div>
</div>

<button class="open-in-host">Abrir en codepen </button><button class="open-in-host">Abrir en jsfiddle </button>

Líneas de RejillaEdit

Debe tenerse en cuenta que cuando definimos una rejilla definimos las vías de la rejilla, no las líneas. Grid luego nos da las líneas numeradas a utilizar al posicionar elementos. En nuestra rejilla de tres columnas y dos filas, tenemos cuatro líneas de columna.

Diagram showing numbered grid lines.

Las líneas están numeradas según el modo de escritura del documento. En un idioma de izquierda a derecha, la línea 1 está al lado izquierdo de la rejilla. En un idioma de derecha a izquierda, está en el lado derecho de la rejilla. Las líneas también se pueden nombrar, ya veremos cómo hacer esto en una guía posterior de esta serie.

Posicionando elementos contra líneas

Estaremos explorando la colocación basada en líneas en detalle en un artículo posterior, el siguiente ejemplo demuestra cómo hacer esto de una manera sencilla. Cuando colocamos un elemento dirigimos la línea - en lugar de la vía.

En el siguiente ejemplo, estoy posicionando los dos primeros elementos en la rejilla de tres vías de columna,  usando las propiedades grid-column-start, grid-column-end, grid-row-start y grid-row-end. Trabajando de izquierda a derecha, el primer elemento se coloca contra la línea de columna 1, y se extiende a la línea de columna 4, que en nuestro caso es la línea de la derecha en la rejilla. Comienza en la línea de fila 1 y termina en la línea de fila 3, por lo tanto, se extiende sobre dos vías de fila.

El segundo elemento comienza en la línea de columna de rejilla 1 y se extiende una vía. Este es el valor por defecto, por lo que no necesito especificar la línea final. También se extiende dos vías de fila de la línea de fila 3 a la línea de fila 5. Los otros elementos se colocarán a sí mismos en espacios vacíos en la rejilla.

<div class="wrapper">
   <div class="box1">One</div>
   <div class="box2">Two</div>
   <div class="box3">Three</div>
   <div class="box4">Four</div>
   <div class="box5">Five</div>
</div>
.wrapper { 
    display: grid; 
    grid-template-columns: repeat(3, 1fr); 
    grid-auto-rows: 100px; 
} 
.box1 { 
    grid-column-start: 1; 
    grid-column-end: 4; 
    grid-row-start: 1; 
    grid-row-end: 3; 
} 
.box2 { 
    grid-column-start: 1; 
    grid-row-start: 3; 
    grid-row-end: 5; 
}

<button class="open-in-host">Abrir en codepen </button><button class="open-in-host">Abrir en jsfiddle </button>

No olvide que puede utilizar Grid Inspector en las Herramientas de Desarrollador de Firefox para ver cómo se posicionan los elementos en las líneas de la rejilla.

Celdas de Rejilla

Una celda de rejilla es la unidad más pequeña en una rejilla, conceptualmente es como una celda de tabla. Como vimos en nuestros ejemplos anteriores, una vez que se define una rejilla en un padre, los elementos hijo se posicionarán a sí mismos de una vez en cada celda de la rejilla definida. En la imagen de abajo he resaltado la primera celda de la rejilla.

The first cell of the grid highlighted

Áreas de rejilla

Los elementos pueden extenderse a través de una o más celdas tanto por fila como por columna, lo que crea un área de rejilla. Las áreas de la rejilla tienen que ser rectangulares - no es posible crear un área en forma de L, por ejemplo. El área de rejilla resaltada abarca dos vías de fila y dos de columna.

A grid area

Canaletas

Las canaletas o callejones entre las celdas de la rejilla se pueden crear usando las propiedades grid-column-gap y grid-row-gap, o la propiedad abreviada grid-gap. En el siguiente ejemplo estoy creando una brecha de 10 píxeles entre columnas y una brecha de 1em entre filas.

.wrapper {
   display: grid;
   grid-template-columns: repeat(3, 1fr);
   grid-column-gap: 10px;
   grid-row-gap: 1em;
}
<div class="wrapper">
   <div>One</div>
   <div>Two</div>
   <div>Three</div>
   <div>Four</div>
   <div>Five</div>
</div>

<button class="open-in-host">Abrir en codepen </button><button class="open-in-host">Abrir en jsfiddle </button>

Cualquier espacio utilizado por las brechas se tendrá en cuenta antes de que el espacio sea asignado a las vías fr de longitud flexible y las canaletas intervienen con propósitos de dimensionamiento como una vía de rejilla regular, sin embargo, no se puede colocar nada en una brecha. En términos de posicionamiento basado en líneas, la brecha actúa como una línea gruesa.

Anidamiento de rejillas

Un elemento de rejilla puede convertirse en un contenedor de rejilla. En el ejemplo siguiente tengo la rejilla de tres columnas creada anteriormente, con nuestros dos elementos posicionados. En este caso, el primer elemento tiene algunos subelementos. Ya que estos elementos no son descendientes directos de la rejilla, no participan en la disposición de la rejilla y por lo tanto se muestran en el flujo normal del documento.

<div class="wrapper">
   <div class="box box1">
       <div class="nested">a</div>
       <div class="nested">b</div>
        <div class="nested">c</div>
    </div>
    <div class="box box2">Two</div>
    <div class="box box3">Three</div>
    <div class="box box4">Four</div>
    <div class="box box5">Five</div>
</div>

Nested grid in flow

Si establezco box1 a display: grid puedo darle una definición de vía y también se convertirá en una rejilla, los elementos entonces se posicionan en esta nueva rejilla.

.box1 {
   grid-column-start: 1;
   grid-column-end: 4;
   grid-row-start: 1;
   grid-row-end: 3;
   display: grid;
   grid-template-columns: repeat(3, 1fr);
}

<button class="open-in-host">Abrir en codepen </button><button class="open-in-host">Abrir en jsfiddle </button>

En este caso, la rejilla anidada no tiene ninguna relación con el padre. Como usted puede ver en el ejemplo, no ha heredado la grid-gap del elemento padre y las líneas de la rejilla anidada no se alinean con las líneas de la rejilla padre.

Subgrid

En la especificación de grid de nivel 1 hay una característica llamada subgrid que nos permitiría crear rejillas anidadas que usan la definición de la vía de la rejilla padre.

Las Subgrids aún no están implementadas en ningún navegador y la especificación está sujeta a cambio.

En la especificación actual, editaríamos el ejemplo de rejilla anidada arriba para usar display: subgrid en lugar de display: grid, y luego eliminar la definición de vía. La rejilla anidada utilizará las vías de la rejilla principal para posicionar los elementos.

Cabe señalar que la rejilla está anidada en ambas dimensiones — filas y columnas. No hay concepto de la rejilla implícita trabajando con subgrids. Esto significa que debe asegurarse de que la rejilla padre tenga suficientes vías de fila y columna para todos los subelementos.

.box1 {
   grid-column-start: 1;
   grid-column-end: 4;
   grid-row-start: 1;
   grid-row-end: 3;
   display: subgrid;
}

Estratificando elementos con z-index

Los elementos de rejilla pueden ocupar la misma celda. Si volvemos a nuestro ejemplo con elementos posicionados por número de línea, podemos cambiar esto para hacer que dos elementos se superpongan.

<div class="wrapper">
   <div class="box box1">One</div>
   <div class="box box2">Two</div>
   <div class="box box3">Three</div>
   <div class="box box4">Four</div>
   <div class="box box5">Five</div>
</div>
.wrapper {
   display: grid;
   grid-template-columns: repeat(3, 1fr);
   grid-auto-rows: 100px;
}
.box1 {
   grid-column-start: 1;
   grid-column-end: 4;
   grid-row-start: 1;
   grid-row-end: 3;
}
.box2 {
   grid-column-start: 1;
   grid-row-start: 2;
   grid-row-end: 4;
}

<button class="open-in-host">Abrir en codepen </button><button class="open-in-host">Abrir en jsfiddle </button>

El elemento box2 ahora se superpone a box1, se muestra en la parte superior ya que aparece después en el orden de origen.

Controlando el orden

Podemos controlar el orden en el que los artículos se apilan utilizando la propiedad z-index - al igual que con los elementos posicionados. Si le damos a box2 un z-index más bajo que box1, se mostrará debajo de box1 en la pila.

.wrapper {
   display: grid;
   grid-template-columns: repeat(3, 1fr);
   grid-auto-rows: 100px;
}
.box1 {
   grid-column-start: 1;
   grid-column-end: 4;
   grid-row-start: 1;
   grid-row-end: 3;
   z-index: 2;
}
.box2 {
   grid-column-start: 1;
   grid-row-start: 2;
   grid-row-end: 4;
   z-index: 1;
}

<button class="open-in-host">Abrir en codepen </button><button class="open-in-host">Abrir en jsfiddle </button>

Siguientes Pasos

En este artículo hemos tenido una mirada muy rápida a través de la Especificación de Grid Layout. Juegue un poco con los ejemplos de código, y luego pase a la siguiente parte de esta guía donde realmente nos vamos a adentrar en detalle dentro de CSS Grid Layout.

Etiquetas y colaboradores del documento

 Colaboradores en esta página: jorgemontoyab
 Última actualización por: jorgemontoyab,