Skip to content

Diseño web adaptativo

En este documento abordaremos el tema del diseño web adaptativo o responsive, aunque en breve veremos que estos dos conceptos no son exactamente iguales. Básicamente, la temática a abordar es cómo diseñar una web para que se vea adecuadamente en diferentes tipos de dispositivos o resoluciones, tales como smartphones, tablets o monitores de alta resolución.

1. Introducción al diseño adaptativo

Como acabamos de comentar, abordaremos la problemática de cómo diseñar una web para distintos tipos de dispositivos. Esta afirmación en sí plantea dos preguntas:

  • ¿Qué tipos principales de dispositivos podemos o debemos considerar?
  • ¿Qué estrategias hay para abordar el diseño web para esos tipos de dispositivos?

1.1. Tipos de resoluciones

Tratemos de responder a la primera pregunta: ¿qué tipos principales de dispositivos podemos o debemos considerar?. Realmente no es esa la pregunta adecuada, sino más bien a cuántos tipos de resoluciones diferentes podemos o debemos adaptar nuestra web. Y, para responder a esta pregunta, podemos hacer un análisis rápido de los distintos tipos de pantalla en los que habitualmente podemos consultar una página web:

  • Por un lado, tenemos smartphones de baja resolución o resolución extra-pequeña (normalmente abreviada xs, extra small). La resolución máxima típica en esta categoría no llega a unos 576px de ancho.
  • El siguiente escalón estaría formado por dispositivos pequeños (normalmente smartphones también) de mayor resolución. Conformarían una resolución pequeña (a menudo abreviada como sm de small), con valores máximos de hasta unos 768px de anchura.
  • A continuación están las pantallas de pequeño tamaño, como las de las tablets, que formarían una resolución media (normalmente abreviada como md), con valores máximos de hasta unos 992px.
  • Después vendrían pantallas más grandes (abreviadas lg), como los monitores de gama media, con resoluciones de hasta unos 1200px.
  • Le siguen las pantallas aún más grandes (abreviadas xl), con resoluciones de hasta unos 1400px.
  • Finalmente, podríamos hablar de pantallas todavía más grandes (abreviadas xxl), para resoluciones mayores que la anterior.

1.2. Estrategias de diseño. Responsive vs adaptativo

Vayamos ahora con la segunda pregunta formulada anteriormente: a la hora de abordar el diseño de una web para dar respuesta a todos los tipos de resoluciones posibles (o un grupo de ellos), tenemos dos estrategias:

  • La estrategia responsive consiste en definir un único diseño que automáticamente se va adaptando a las distintas resoluciones que indiquemos, y re-posicionando sus elementos conforme a esas resoluciones. Para abordar esta estrategia podemos hacer uso de elementos como flexbox, que veremos a continuación, y también de frameworks específicos de diseño web, como Bootstrap.
  • La estrategia adaptativa consiste en definir un diseño para cada una de las posibles resoluciones que queremos tratar, de forma que se activa o carga uno u otro en función de la resolución. Esta estrategia se aborda mediante el uso de media queries, que también trataremos a continuación.

1.3. Gestionando el viewport

Una de las etiquetas meta que comentamos en las primeras sesiones de este curso es la etiqueta viewport. Esta etiqueta permite a los diseñadores web controlar el área visible de una web. En general, la etiqueta que se recomienda utilizar tiene este aspecto:

<meta name="viewport" content="width=device-width, initial-scale=1.0">

El parámetro width=device-width hace que la anchura de la página se iguale a la anchura de la pantalla del dispositivo. Por otra parte, el parámetro initial-scale=1.0 establece el nivel de zoom inicial en 1, es decir, en el zoom del 100%, cuando la página se carga por primera vez.

2. Diseño adaptativo. Uso de media queries

Las media queries (en español, consulta sobre medios) son una técnica proporcionada por CSS3 que permite adaptar la visualización del contenido de una página a las características del dispositivo en que se va a mostrar. Estas características incluyen, sobre todo, la resolución de la pantalla, pero también podemos hablar de otras, como el tipo de medio. Así, por ejemplo, podemos definir un estilo diferente para una web que se vaya a imprimir en papel y eliminar el color de fondo, entre otras cosas.

2.1. Estructura general de una media query

Las media queries se definen en el propio documento CSS, a través de la expresión @media seguida de las condiciones que debe cumplir el dispositivo para aplicar los estilos incluidos en ella. En concreto, su sintaxis general es:

@media not|only tipo_medio and (expresiones)
{
    estilos CSS
}

donde:

  • tipo_medio alude al tipo de medio donde se va a mostrar el contenido. Típicamente es screen (pantalla), pero puede valer también print (impreso en papel), speech (hablado) u all.
  • Las expresiones consisten en una serie de condiciones que debe cumplir el dispositivo. Algunos de los parámetros más habituales que se pueden especificar aquí son:
    • Anchura mínima o máxima, que suele ser lo más habitual. Se indican con min-width / max-width y el valor suele especificarse en píxeles (por ejemplo, min-width: 700px). También podemos especificar altura mínima/máxima, o un rango de anchura/altura (por ejemplo, 500px < width < 800px).
    • Resolución del dispositivo (resolution), habitualmente expresada en dpi. Podemos especificar un rango o bien establecer una resolución mínima o máxima (min-resolution, max-resolution).
    • Orientación del dispositivo (orientation), que puede ser portrait (vertical) o landscape (horizontal)
    • Estilo de tema (prefers-color-scheme), útil para aplicar estilos distintos a temas claros (light) u oscuros (dark)

Por ejemplo, esta media query se aplicaría únicamente a pantallas con una resolución mínima de 768px:

@media only screen and(min-width: 768px)
{
    ...
}

También podemos enlazar condiciones con and o con comas (equivalente a un or):

/* Estilos para pantallas entre 320 y 480px de ancho y resolución de 150dpi */
@media only screen and (320px <= width <= 480px) and (resolution = 150dpi)
{
    ...
}

/* Estilos para pantallas con anchura máxima de 600px u orientación vertical */
@media (max-width: 600px), (orientation: portrait) 
{
    ...
}

Para el uso habitual que se hace de las media queries puede bastar con especificar una anchura mínima o máxima, por lo que podemos dejarlas con este formato:

@media (min-width: 768px)
{
    ...
}

2.2. Estrategia de uso de las media queries

A la hora de aplicar media queries a nuestra web para definir diferentes disposiciones y diseños de elementos acordes a distintas resoluciones de pantalla, una estrategia general es:

  1. Fuera de las media queries (por ejemplo, al inicio del documento CSS) definimos los estilos generales que no van a cambiar entre resoluciones (colores de fondo, tipos de letra, etc) y también la disposición de los elementos para la resolución más baja (o más alta) que queramos tratar.
  2. Definimos una media query por cada resolución superior (o inferior) que queramos contemplar, y dentro, redefinimos únicamente los estilos que queramos adaptar a esa resolución. Por ejemplo, la anchura o tamaño de ciertas cajas, etc.

Por ejemplo, supongamos el siguiente contenido HTML:

<!DOCTYPE html>
<html lang="es">
<head>
    <meta charset="UTF-8">
    <title>Ejemplo media queries</title>
    <link rel="stylesheet" href="estilos.css">
</head>
<body>
    <section id="contenedor">
        <section id="caja1">Caja 1</section>
        <section id="caja2">Caja 2</section>
    </section>
</body>
</html>

Vamos a definir dos tipos de resoluciones: para pantallas de hasta 768px de ancho, mostraremos una caja debajo de la otra. En cambio, para pantallas de mayor anchura, las mostraremos en paralelo, usando para ello un grid de dos columnas. Nuestro CSS quedaría así:

  1. Primero definimos los estilos generales y la disposición de las cajas para baja resolución:
body
{
    font-family: Arial;
    margin: 10px 5%;
}

#caja1
{
    background-color:lightcoral;
    padding: 10px;
    margin-bottom: 10px;
    border: 1px solid black;
}

#caja2
{
    background-color:lightskyblue;
    padding: 10px;
    margin-bottom: 10px;
    border: 1px solid black;
}
  1. Después, definimos la media query para resoluciones mayores, y definimos la disposición en rejilla de las dos cajas en este caso:
@media(min-width: 768px)
{
    body
    {
        margin: 100px 20%;
    }

    #contenedor
    {
        display: grid;
        grid-template-columns: 1fr 1fr;
        grid-template-rows: auto;
        gap: 10px;
    }
}

Y obtendríamos un resultado como este (baja resolución / alta resolución):

Notar que también podemos aplicar CSS nesting si queremos y ubicar las media queries dentro de los elementos sobre los que se aplican. Por ejemplo:

#contenedor
{
    display: block;
    margin: 10px 10%;

    @media(min-width: 768px)
    {
        &
        {
            display: grid;
            grid-template-columns: 1fr 1fr;
            grid-template-rows: auto;
            gap: 10px;
        }
    }
}

2.3. Ficheros CSS y diseño adaptativo

Podemos centralizar todo el diseño adaptativo de nuestra web en un solo CSS, o definir un fichero CSS para cada configuración de pantalla. En este último caso, podemos emplear la etiqueta link de HTML para especificar en qué condiciones cargar cada CSS:

<link rel="stylesheet" href="movil.css" media="(max-width: 640px)">
<link rel="stylesheet" href="tablet.css" media="(min-width: 640px) and (max-width: 1280px)">
<link rel="stylesheet" href="escritorio.css" media="(min-width: 1280px)">

Ejercicio 1

Descarga este ejemplo y define un documento CSS donde, ayudándote de media queries, definamos tres posibles disposiciones:

  • Para resoluciones bajas (hasta 768px), mostraremos las cajas una debajo de otra

  • Para resoluciones intermedias (hasta 992px), mostraremos la caja 1 arriba, la caja 4 abajo, y las dos intermedias en paralelo. Además, cambiaremos el color de las cajas 1 y 4 a gris (ver imagen resultado)

  • Para resoluciones mayores, mostraremos las 4 cajas en paralelo con sus colores originales

2.4. Las container queries

Un cambio importante que se ha dado en versiones recientes de CSS es la incorporación de container queries, a través de la regla @container. Esto va a permitir que los estilos que apliquemos a los elementos ya no sólo dependan de la pantalla sobre las que los estemos visualizando, sino también del tamaño dado al elemento que los contiene.

Para poder trabajar con estos elementos, primero debemos configurar el elemento contenedor con un par de propiedades:

  • container-type: especificamos que este contenedor va a ser consultable para ajustar las características de lo que tiene. Los posibles valores son inline-size (si nos interesa sólo la anchura) o size (para anchura y altura).
  • container-name: no es obligatorio, pero sí es útil. Se le asigna un nombre a este contenedor para luego usarlo en las queries

Por ejemplo, así configuramos el elemento #contenedor para que sea consultable en anchura, y le damos un nombre:

#contenedor
{
    container-type: inline-size;
    container-name: mi-contenedor;
}

A partir de aquí, los elementos que estén dentro de este contenedor pueden admitir configuraciones dependiendo del tamaño (anchura) del contenedor padre. Por ejemplo, si tenemos una sección #contenido dentro de este contenedor, podemos hacer algo así:

@container mi-contenedor (min-width: 800px) 
{
    #contenido 
    {
        ...
    }
}

Ejercicio 2

En el siguiente código HTML hay un elemento de clase evento que se muestra en dos contenedores diferentes. En el CSS se ha definido un grid de 2 columnas, y debes añadir el código CSS necesario para que, si la anchura del contenedor es inferior a 300px, sólo se muestre el título principal (con un tipo de letra más pequeño) y el subtítulo, rodeado todo por un borde negro redondeado. Esto hará que en el contenedor de la izquierda se vea reducido, y en el de la derecha ampliado.

<!DOCTYPE html>
<html lang="es">
<head>
    <meta charset="UTF--8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Ejemplo de Container Queries</title>
    <style>
        body
        {
            font-family: system-ui;
            margin: 10px 5%;
        }
        #contenedor
        {
            display: grid;
            grid-template-columns: 25% 75%;
            grid-template-rows: auto;
            gap: 50px;
        }
        .evento
        {
            margin: 10px;
            padding: 10px;
        }            
    </style>
</head>
<body>
    <header>
        <h1>Próximos Eventos</h1>
    </header>

    <section id="contenedor">

        <aside id="miniaturas">
            <section class="evento">
                <h2>Concierto de Jazz Nocturno</h2>
                <p class="subtitulo">25 Octubre 2025, Gran Teatro</p>
                <div class="contenido">
                    <p>Una noche mágica con El Reno Renardo es un grupo musical español de heavy metal humorístico o freak metal, nacido de un proyecto en línea en solitario de Jevo Jevardo​. Tras dos años de bastante éxito en Internet, se decidió crear un concierto, para lo cual se reclutó al resto de miembros y se formó la banda en sí misma.</p>
                </div>
            </section>
            <section class="evento">
                <h2>Cuentos de Alberto Celdrán</h2>
                <p class="subtitulo">12 Noviembre 2025, Explanada</p>
                <div class="contenido">
                    <p>El gran cuentacuentos Alberto Celdrán nos deleitará en la tarde noche del 12 de noviembre con una serie de cuentos fantásticos basados en la historia de África. Apto para grandes y pequeños, el autor interpretará diversos cuentos tradicionales africanos que cuentan la historia y creencias de esa tierra.</p>
                </div>
            </section>
        </aside>

        <main id="principal">
            <section class="evento">
                <h2>Concierto de Jazz Nocturno</h2>
                <p class="subtitulo">25 Octubre 2025, Gran Teatro</p>
                <div class="contenido">
                    <p>Una noche mágica con El Reno Renardo es un grupo musical español de heavy metal humorístico o freak metal, nacido de un proyecto en línea en solitario de Jevo Jevardo​. Tras dos años de bastante éxito en Internet, se decidió crear un concierto, para lo cual se reclutó al resto de miembros y se formó la banda en sí misma.</p>
                </div>
            </section>
            <section class="evento">
                <h2>Cuentos de Alberto Celdrán</h2>
                <p class="subtitulo">12 Noviembre 2025, Explanada</p>
                <div class="contenido">
                    <p>El gran cuentacuentos Alberto Celdrán nos deleitará en la tarde noche del 12 de noviembre con una serie de cuentos fantásticos basados en la historia de África. Apto para grandes y pequeños, el autor interpretará diversos cuentos tradicionales africanos que cuentan la historia y creencias de esa tierra.</p>
                </div>
            </section>
        </main>

    </div>
</body>
</html>    

Este debería ser el aspecto final aproximado:

3. Diseño responsive. Uso de flexbox

Flexbox (flexible boxes) es un mecanismo de diseño web responsive facilitado por CSS3, que permite especificar una serie de propiedades en las cajas para que se adapten automáticamente al tamaño de pantalla existente, dependiendo de si van a tener suficiente espacio para mostrarse de un modo u otro.

Del mismo modo que ocurre con el grid de CSS, es necesario que las cajas involucradas en el proceso responsive estén contenidas en otra, de forma que podemos especificar las propiedades generales de flexbox en la caja contenedora, y luego definir, adicionalmente, cómo queremos disponer las cajas en ese contenedor.

Como veremos a continuación, definiremos cómo distribuir los elementos en una dimensión (horizontal o verticalmente), no es posible definir rejillas bidimensionales como se hace con grid.

3.1. Configurando la caja contenedora

Entre las propiedades que podemos definir en la caja contenedora, podemos destacar las siguientes:

  • display: en este caso, la propiedad display deberá tener el valor de flex para habilitar el contenedor como un contenedor de elementos flexibles. Alternativamente, también se le puede dar el valor inline-flex si queremos que los elementos de dentro se comporten como elementos en línea (no en bloque).
  • flex-direction: indica cómo se van a disponer las cajas dentro del contenedor. El valor por defecto es row, que hace que se dispongan de izquierda a derecha, pero también podemos utilizar row-reverse (horizontal pero invertido), column (de arriba a abajo) y column-reverse (vertical pero invertido). Como decíamos antes, con Flexbox vamos a poder disponer los elementos en una dirección (bien horizontal, bien vertical) de forma flexible.
  • justify-content: indica cómo se va a rellenar el espacio entre cajas a lo largo del eje principal (horizontal o vertical). Puede tomar los valores flex-start (valor por defecto, se agrupan las cajas al inicio del espacio disponible), flex-end (al final), center (centradas en medio del espacio disponible), space-between (justificadas con espacio entre ellas), space-around (justificadas con espacio también a los lados)...
  • flex-wrap: indica cómo vamos a adaptar las cajas en caso de que no quepan todas en una misma fila (o columna). Su valor por defecto es nowrap, lo que indica que no hay ningún ajuste: las cajas se disponen según lo indicado en las propiedades anteriores, y si no caben se siguen disponiendo en esa dirección. Pero si lo establecemos a wrap, entonces se redistribuirán si no hay espacio suficiente. Es el valor más habitual si queremos establecer un diseño responsive. También existe la opción wrap-reverse.
  • align-items: indica la alineación de los elementos a lo largo del eje cruzado o secundario. Posibles valores son stretch (estira los elementos para que ocupen todo el alto/ancho del contenedor), flex-start (al inicio del eje cruzado), flex-end (al final del eje cruzado) o center.
  • flex-flow: es un atajo para poner de una vez, separados por espacios, los valores de flex-direction y flex-wrap. Por ejemplo: flex-flow: row wrap;.
  • row-gap y column-gap permiten establecer la separación entre filas (para eje principal vertical) o entre columnas (para eje principal horizontal). Alternativamente podemos usar gap para especificar ambas separaciones (un solo valor para las dos, o uno para X y otro para Y).

Existen algunas webs como esta donde podemos probar el comportamiento de estas y otras propiedades, y ver cómo funciona cada una en realidad.

3.2. Configurando las cajas internas

Para cada caja contenida en el elemento contenedor, podemos configurar sus propiedades flexbox para indicar dónde se va a ubicar y cuánto espacio va a ocupar. Algunas de estas propiedades son:

  • order: indica el orden de la caja dentro de la secuencia de cajas contenidas. Si no indicamos nada, cada caja se coloca a continuación de la anterior, siguiendo la disposición indicada en la caja contenedora. Pero podemos alterar ese orden natural reubicando las cajas. Se trata simplemente de un número; cuanto mayor sea, la caja se colocará más hacia el final de la secuencia.
  • flex-grow: capacidad del elemento para crecer y ocupar el espacio disponible en el eje principal. Funciona de forma proporcional, como las unidades fr de las rejillas (grid).
  • flex-shrink: capacidad del elemento para encogerse si no hay espacio para todos. Similar al anterior
  • flex-basis: tamaño inicial del elemento antes de distribuir el espacio sobrante. Por defecto es auto, pero lo podemos poner en píxeles o porcentaje, por ejemplo.
  • flex: es un atajo que combina las tres propiedades anteriores. indica el tamaño de la caja respecto al resto. Son tamaños relativos, igual que ocurre con las unidades fr en la rejilla grid CSS.

Respecto a las unidades de algunas de estas propiedades, veamos un ejemplo: si todas las cajas tienen un tamaño flex de 1, todas ocuparán lo mismo. Si a alguna le asignamos un tamaño de 2, ocupará el doble que el resto. Alternativamente, también podemos utilizar esta propiedad para dar un tamaño fijo en píxeles (por ejemplo, flex:200px) o en porcentaje (flex: 40%). Esta última opción es útil si queremos controlar mejor cuántas columnas queremos que haya en cada fila.

Además, podemos emplear otras propiedades CSS habituales, como min-width. Esto indicará una anchura mínima en los elementos y, si esta anchura no se cumple y tenemos habilitada la opción flex-wrap: wrap en el contenedor, entonces hará que vaya a la siguiente fila/columna disponible para mostrarse.

Echemos un vistazo a este ejemplo:

<!DOCTYPE html>
<html lang="es">
<head>
    <meta charset="UTF-8">
    <title>Ejemplo flexbox</title>
    <link rel="stylesheet" href="estilos.css">
</head>
<body>
    <section id="contenedor">
        <section id="caja1">Caja 1</section>
        <section id="caja2">Caja 2</section>
        <section id="caja3">Caja 3</section>
    </section>
</body>
</html>

Imaginemos que queremos poner las tres cajas en horizontal, con la caja 2 ocupando el doble de espacio, y que todas tengan una anchura mínima de 250px. Si eso no puede cumplirse, queremos que las cajas se redistribuyan para cumplir con esa anchura mínima (normalmente una debajo de otra).

En primer lugar, definimos las características del elemento contenedor:

#contenedor
{
    display: flex;
    flex-direction: row;
    justify-content: space-between;
    flex-wrap: wrap;
    gap: 10px;
}

Después, establecemos las propiedades de las cajas contenidas. Además de sus características particulares (color de fondo, padding, etc), indicamos sus propiedades flexbox: anchura (propiedad flex) y anchura mínima.

#caja1, #caja3
{
    background-color:lightcoral;
    padding: 10px;
    flex: 1;
    min-width: 250px;
}

#caja2
{    
    background-color:lightskyblue;
    padding: 10px;
    flex: 2;
    min-width: 500px;
}

Si vamos variando el tamaño de la ventana del navegador, podemos comprobar cómo las propias cajas se van ajustando a distintos tamaños y posiciones para cumplir con lo establecido. Aquí vemos la evolución desde pantallas grandes a pequeñas:

Notar que, si eliminamos la propiedad flex-wrap: wrap del elemento contenedor, las cajas ya no se redistribuyen. Se quedan ocupando su espacio original, y si encogemos demasiado la pantalla nos tocará hacer scroll para verlas.

Notar también que, utilizando flexbox, podemos reajustar las cajas automáticamente en cuanto el tamaño de la pantalla "choque" con los requisitos de cada caja, pero no podemos controlar del todo dónde va a parar cada caja. En el ejemplo anterior, llega un punto en que la caja 3 baja a la segunda fila, quedando la caja 1 y la 2 en primera fila... pero quizá preferiríamos otra distribución para esa situación intermedia.

Puedes leer más información sobre Flexbox en otras webs interesantes, como por ejemplo esta.

Ejercicio 3

Descarga este ejemplo que ya hemos utilizado en un ejercicio previo. Ahora vamos a configurarlo mediante flexbox para que:

  • Las dos cajas centrales ocupen el doble de tamaño que las laterales. Las laterales van a tener un color de fondo gris y las centrales amarillo-naranja.
  • Las cajas laterales tengan una anchura mínima de 200px, y las centrales de 300px. Cuando este tamaño no sea posible, se redistribuirán

Aquí tienes un ejemplo de cómo puede quedar, a algunas de las resoluciones posibles:

4. Uso avanzado de la rejilla (grid)

En documentos anteriores ya hemos hablado del uso de la rejilla o grid desde CSS3 para poder posicionar nuestros elementos en la web de forma cómoda. Entonces simplemente definíamos en qué fila(s) o columna(s) queríamos ubicar cada elemento. Sin embargo, la rejilla tiene otros usos algo más avanzados o complementarios, que vamos a comentar aquí.

4.1. Configuración de la rejilla por áreas

Podemos definir áreas en el grid usando la propiedad grid-template-areas en el elemento contenedor. Esto nos permite asignar un nombre a cada área, y posicionar luego los elementos en un área concreta, indicando su nombre.

Por ejemplo, imaginemos que definimos estas áreas en nuestro contenedor:

#contenedor
{
    display: grid;
    grid-template-areas: "arriba arriba", "izquierda derecha", "abajo abajo";
 }

Hemos definido una malla de 3 filas y 2 columnas en cada fila. Si hiciéramos algo como esto:

#elemento1 { grid-area: arriba; }
#elemento2 { grid-area: izquierda; }
#elemento3 { grid-area: derecha; }
#elemento4 { grid-area: abajo; }

Entonces el elemento1 ocuparía toda la fila superior, y el elemento4 toda la fila inferior. Los elementos 2 y 3 se repartirían la zona central a izquierda y derecha, respectivamente.

Notar que los elementos ocupan automáticamente toda el área que se le ha asignado con ese nombre, lo que permite hacer expansiones tanto en horizontal como en vertical:

#contenedor
{
    display: grid;
    grid-template-areas: "izquierda derecha", "izquierda derecha", "abajo1 abajo2";
 }

En este caso, un item colocado en el área izquierda ocuparía la primera columna de las dos primeras filas.

4.2. Alineación del contenido

Para alinear el contenido de la rejilla podemos hacer uso de estas propiedades CSS:

  • justify-content: define la alineación horizontal de la rejilla entera dentro de la página. Sus posibles valores son start, end, center, space-between (espacio entre columnas, sin espacio en los bordes), space-around (espacio equitativo alrededor de cada columna) o space-evenly (espaciado uniforme entre y alrededor de columnas). Similar al comportamiento en Flexbox.
  • align-content: define la alineación vertical de la rejilla dentro de la página. Sus valores son los mismos que para la propiedad anterior.
  • justify-items: define la alineación horizontal de los elementos dentro de cada casilla de la rejilla. Sus posibles valores son start, end, center y stretch (valor por defecto, el contenido se estira para ocupar toda la celda).
  • align-items: define la alineación vertical de los elementos dentro de cada casilla.

Estas propiedades se aplican sobre el contenedor:

#contenedor 
{
  display: grid;
  width: 500px;
  justify-content: space-around;
  justify-items: center;
  ...
}

4.3. Grids y diseño adaptativo

El uso de grids combina muy bien con el diseño adaptativo que hemos visto antes. Por ejemplo, podemos definir distintas distribuciones de grid areas en distintas media queries para distribuir los elementos de nuestra web de una u otra forma dependiendo del tamaño de la pantalla.

5. Conclusiones. Flexbox vs grid vs media queries

En general, flexbox es una buena opción para una distribución flexible unidimensional (es decir, colocar componentes en una misma fila o columna y que se auto-distribuyan dependiendo del tamaño disponible). Pero para disposiciones bidimensionales (tablas), flexbox se queda corto por sí mismo, si queremos controlar la distribución concreta de los elementos. Una alternativa a esto podría ser utilizar grid y media-queries para diferentes posibles tamaños.

Con lo visto hasta ahora, podemos optar por un diseño adaptativo (media queries + grid) si queremos controlar mejor la disposición bidimensional de los elementos de la web, o por un diseño responsive (flexbox) si sólo queremos controlar la disposición unidimensional (fila a fila, o columna a columna). El inconveniente de lo primero es que nos "obliga" a plantear distintos diseños complementarios para elegir automáticamente cuál de ellos cargar. Una alternativa a esto es utilizar algún framework de diseño web, como Bootstrap, que simplifica bastante esta tarea.

Pero, por encima de todo, hay que tener en cuenta que todas estas opciones no son enemigas entre sí, sino que se pueden complementar. Es muy habitual utilizar media queries y grid para el diseño general de la página y luego flexbox para organizar los elementos en un componente determinado.