Diseño web con HTML y CSS

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:

1.1. Tipos de resoluciones

Tratemos de responder a la primera pregunta: ¿qué tipos principales de dispositivos podemos o debemos considerar?. Realmente no es ésa 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:

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:

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:

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)
{
    ...
}

Para el uso que vamos a hacer aquí de las media queries nos 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):

Ejercicio 1:

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

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.

3.1. Configurando la caja contenedora

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

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:

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;
}

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;
    margin: 10px;    
    flex: 1;
    min-width: 250px;
}

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

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 2:

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

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

4. Conclusiones. Flexbox 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.