En el diseño responsive las imágenes tienen algunos inconvenientes: carga de archivos innecesariamente pesados para pantallas pequeñas y necesidad de redimensionar las imágenes con la posible distorsión y pérdida de calidad. Hay múltiples soluciones para este problema pero ninguna parece ser, al menos en el momento de escribir este post, aceptada como la solución definitiva.

En este post, como el título indica, me voy a centrar en las imágenes de fondo. Estas imágenes se utilizan, yo diría que el 100% de las veces, con motivos exclusivamente de diseño visual y por tanto no necesitan de un marcado semántico ni estar incluidas en el documento. Así que no hay razón alguna para cargar estas imágenes a través de elementos HTML <img> o <picture>. En otras palabras, podemos evitar las limitaciones de estos elementos HTML y aprovechar toda la libertad que nos ofrece CSS.

Sinceramente, desde todo el cariño, si tienes que utilizar obligatoriamente un elemento <img> o <picture> para cargar una imagen cuyo único propósito es el diseño, creo que deberías replantearte el enfoque del problema. Si crees que estoy equivocado me encantará discutir el tema.

background y media queries

Si vamos a utilizar CSS para las imágenes de fondo en un diseño adaptativo, la solución viene casi por sí sola: definir la propiedad background para cada tamaño de pantalla combinándola con media queries.

Siguiendo un enfoque mobile-first, definimos el set de imágenes desde la que se utilizará en las pantallas más pequeñas hasta la que se utilizará en las pantallas más grandes utilizando el media query con la propiedad min-width. Por ejemplo, supongamos que queremos una imagen de fondo para el <body>:

/* Imagen utilizada por defecto, la que se utlizará en pantallas pequeñas */
body {
    background: url("background.png");
}

/* Imagen utilizada en pantallas de anchura 480 px y superior */
@media (min-width: 480px) {
    body {
        background: url("background-480w.png");
    }
}

/* Imagen utilizada en pantallas de anchura 768 px y superior */
@media (min-width: 768px) {
    body {
        background: url("background-768w.png");
    }
}

/* Imagen utilizada en pantallas de anchura 1200 px y superior */
@media (min-width: 1200px) {
    body {
        background: url("background-1200w.png");
    }
}

Es importante recordar que con esta técnica sólo se realiza una solicitud HTTP ya que sólo se carga la imagen definida en la regla que cumpla los requisitos y no las demás (en la mayoría de navegadores principales). De ahí que sea una buena solución para establecer imágenes de fondo en un diseño responsive. Además, tenemos toda la libertad para modificar el tamaño y posición de la imagen de fondo. Por ejemplo:

/* Imagen utilizada por defecto, la que se utlizará en pantallas pequeñas
 * Puestas todas las propiedades por separado por motivos ilustrativos
 */
body {
    background-color: transparent;
    background-image: url("background.png");
    background-repeat: no-repeat;
    background-position: center top;
    background-attachment: fixed;
    backgroudn-size: contain;
}

/* Ahora podemos cambiar solo la propiedad background-image */
@media (min-width: 480px) {
    body {
        background-image: url("background-480w.png");
    }
}
@media (min-width: 768px) {
    body {
        background-image: url("background-768w.png");
    }
}
@media (min-width: 1200px) {
    body {
        background-image: url("background-1200w.png");
    }
}

El formato SVG como background

El formato SVG “admite en su interior” diferentes <image> y media queries, seria algo similar a lo descrito en el método anterior pero sin ninguna ventaja y sí algunos inconvenientes, pues en este caso se descargarían todas las imágenes definidas en el archivo SVG.

Sin embargo, cuándo el archivo SVG contiene una imagen vectorial, la cosa se pone mucho mejor y hace que este formato sea una solución mejor que la anterior. Una imagen vectorial, a diferencia de las imágenes bitmap, no contiene píxeles sino que sus colores, líneas y formas están representadas matemáticamente. Esto hace posible que se puedan escalar, tanto aumentar como disminuir, sin que haya la más mínima pérdida de calidad.

El inconveniente es que no todas las imágenes se pueden representar en imágenes vectoriales, pero si la imagen que vas a utilizar puede ser vectorizada, esta ténica para poner imágenes de fondo en un diseño adaptativo tiene importantes ventajas: un sólo archivo, una sola solicitud HTTP y, en la mayoría de los casos, una sóla regla CSS. Por ejemplo:

body {
    background: url("background.svg");
}

En algunos casos, al utilizar imágenes SVG (y en general cualquier imagen) como background hay que ponerle atención a la propiedad background-size y al tamaño del elemento contenedor. Por ejemplo, tenemos un <div class="logo"> dónde vamos a poner un logotipo como imagen de fondo. El espacio para el logotipo es de 150×100 y de 300×200 en patallas de más de 768 px de ancho. Una posible solución totalmente responsive sería:

div.logo {
    display: block;
    width: 150px;
    height: 100px;
    background: url("logo.svg") no-repeat;
    background-size: contain;
}
@media (min-width: 768px) {
    div.logo {
        width: 300px;
        height: 200px;
    }
}

Nota: background-size no es soportado en IE8 y versiones anteriores.

Ejemplo

Fuentes como background

El uso de web fonts para almacenar imágenes es más que conocido en el caso de iconos. Estas fuentes no so más que imágenes vectoriales almacenadas en un archivo tipográfico, así que si tienes la imagen en vectorial, nada te impide convertirla a una fuente. La aplicación de IcoMoon te permite hacerlo fácilmente desde un archivo SVG (y gratis).

Como fuente, la imagen es completamente escalable sin pérdida de calidad, al igual que las imágenes SVG, pero además tiene la ventaja de que se le pueden aplicar todas las propiedades CSS que se pueden aplicar a texto (color, line-height, text-align, text-decoration, font-shadow, y un largo etcétera). La única limitación es que el carácter de una fuente admite un sólo color plano.

Lo que nos interesa es que una web font se puede poner de fondo, así que nos serviría perfectamente para nuestro propósito. En este caso, el tamaño se controlaría con la propiedad font-size en lugar de width, height y background-size y en lugar de background se utilizaría el pseudo elemento :before y la regla content. Esto es lo mismo que hace en realidad cualquier font icon.

Por ejemplo, si la imagen que vamos a utilizar como fondo tiene asignado el carácter e600 en la fuente, podríamos hacer lo siguiente para obtener el mismo resultado que en el ejemplo del logotipo con imagen SVG:

/* Definimos la regla @font-face */
@font-face {
    font-family: "my-font";
    src: url(//misitio.com/assets/fonts/my-font.woff) format('woff');
    font-weight: normal;
    font-style: normal;
}
/* Asignamos nuestra fuente al elemento contenedor */
div.logo {
    display: block;
    width: 150px;
    height: 100px;
    font-family: "my-font";
}
/* Insertamos el caracter e600 de nuestra fuente y definimos el tamaño */
div.logo:before {
    content: "\e600";
    font-size: 100px;
    text-align: center;
    line-height: 100px;
}
/*Hacerlo más grande en pantallas de anchura igual o superior a 768px*/
@media (min-width: 768px) {
    div.logo {
        width: 300px;
        height: 200px;
    }
    div.logo:before {
        font-size: 200px;
        line-height: 200px;
    }
}

Bueno, en el ejemplo anterior no se vería muy bien el efecto al no haber contenido sobre el icono utilizado. En el siguiente pen se puede ver claramente (fork de este pen).

Me quedé sin más sugerencias. En mi opinión, la técnica a elegir para imágenes background en un diseño responsive sería en este orden:

  1. Si la imagen puede vectorizarse, es plana y de un sólo color: web font. Es escalable, por lo que permite tener un solo archivo, y se le pueden aplicar más propiedades CSS que a las imágenes.
  2. Si la imagen puede vectorizarse pero no es plana o no es de un sólo color: imagen vectorial SVG. Es escalable.
  3. Si la imagen no puede vectorizarse: background + media queries. Los formatos de imágenes no vectoriales no son escalables, por lo que hay que tener una versión de la misma imagen por cada tamaño que necesitemos.

¿Alguna sugerencia? Soy todo oídos.

Ah!!! Y si quieres una buena lectura sobre criterios para elegir métodos de imágenes responsive, este artículo de CSS Tricks está bastante bien.

  • Deborah Cisternas

    Hola Juan… de casualidad me encontré con tu post. Te hago una consulta muy, muy básica: Si coloco una imagen (foto en formato PNG o JPG) en, por ejemplo, 300 x 450 dpi en un sitio adpatativo, ¿se puede hacer que dicha imagen se pueda aumentar al doble en un teléfono celular? Lo preciso para que el internauta pueda ver mejor los detalles de la misma en su celular, aunque tenga que recorrerla de arriba hacia abajo y/o de izquierda a derecha y viceversa…

  • jose

    Hola! estoy en etapa aprendiz, gracias por compartir excelentes conocimientos, y consulto si puedo aplicar esto en imagenes contenidas en un div con una clase, gracias

    • Hola Jose. Si por “contenidas” te refieres a imágenes insertadas (elementos <img>, <picture>), lo que se discute en este post no te vale. Pero si te refieres a un <div> al que quieres poner una imagen de fondo a través de CSS, de eso trata el tutorial y en algunos de los ejemplos propuestos se utiliza un <div>. Repásalos.