Responsive images sin JavaScript ni PHP



A día de hoy, responsive design arroja 77 millones de resultados aproximadamente de Google, pero a pesar de las virtudes y la relativa facilidad con la que crear un diseño adaptativo, hay un bestia negra que plantea un problema: las imágenes. Pensando en ello hemos hecho un pequeño experimento.

El problema reside en que si bien el tamaño en píxeles de las imágenes se puede modificar para que se ajuste a la maquetación, una imagen de 100 kilobytes sigue pesando lo mismo independientemente de las dimensiones a las que se reduzca, lo que es un problema para los dispositivos móviles. Por eso, la intención de la comunidad de imágenes adaptables de W3C es definir un elemento picture en el que especificar imágenes de diferentes tamaños, y que su descarga dependa de unas condiciones expresadas con Media Queries, en una sintaxis como ésta:


<picture alt="">
  <source media="(min-width: 45em)" srcset="large-1.jpg 1x, large-2.jpg 2x">
  <source media="(min-width: 18em)" srcset="med-1.jpg 1x, med-2.jpg 2x">
</picture>
 

Pero mientras se termina de definir la propuesta, como siempre la comunidad de desarrolladores ha intentado solventar el problema. Así, ya existen soluciones basadas en JavaScript —de las que la que más nos convence es la del Filament Group— y en PHP —la mejor Adaptatives Images de Matt Wilcox—. Pero por colaborar en el esfuerzo, queríamos ofrecer un nuevo enfoque al problema: una opción que no necesite ninguna de las tecnologías que acabamos de mencionar.

Nuestra prueba de concepto

Isaac Clarke a diversos tamaños en la demo

Nuestra solución se basa exclusivamente en CSS. En el marcado de la página incluimos una imagen que es un GIF transparente de 1?1 píxeles, y a esa imagen le asignamos los diversos tamaños que queremos para los tramos de ancho de pantalla que hemos definido en el ejemplo —menos de 760 píxeles, 760 a 960, 960 a 1240 y más de 1240—, cada uno en su propia hoja de estilos, servidas por medio de queries:


<link href="1240.css" rel="stylesheet" type="text/css" media="screen and (min-width: 1240px)" />
<link href="960.css" rel="stylesheet" type="text/css" media="screen and (min-width: 960px) and (max-width: 1240px)" /> 
<link href="760.css" rel="stylesheet" type="text/css" media="screen and (min-width: 760px) and (max-width: 960px)" /> 
<link href="400.css" rel="stylesheet" type="text/css" media="screen and (max-width: 760px)" />
 

Por otra parte, hemos preparado cuatro imágenes:

Por último, para incluir la imagen que corresponde, simplemente en las respectivas hojas de estilo la incluimos como imagen de fondo de nuestro GIF transparente:


/* En 1240.css: */

#isaac-clarke img{width:1200px;height:570px;background:url(ds2_1200x570.jpg);} 

/* En 960.css: */

#isaac-clarke img{width:920px;height:450px;background:url(ds2_920x450.jpg);} 

/* En 760.css: */

#isaac-clarke img{width:720px;height:390px;background:url(ds2_720x390.jpg);  

/* En 700.css: */

#isaac-clarke img{width:360px;height:230px;background:url(ds2_360x230.jpg);}
 

Así, dependiendo de la hoja de estilo que carga el dispositivo, se sirve la imagen apropiada.

Cuestiones pendientes

Por supuesto, la solución no es perfecta. ¿Qué ocurre si el agente de usuario no cuenta con soporte de media queries? Al usuario no se le serviría ninguna imagen. De todas formas, se trata de una prueba de concepto, así lo que seguiremos desarrollando la idea e intentaremos darle una solución.



Artículos relacionados

Efectos javascript

Un acordeón fallido con CSS3 Creamos una interfaz de acordeón con un híbrido de transiciones de CSS3 y JavaScript. Carrusel con desplazamiento horizontal, en menos de 2… en lo menos que hemos podido Programamos un carrusel de contenidos con desplazamiento horizontal, flexible y casi en menos de 2Kb. ScrollTo,

Menús desplegables animados con CSS3

Los menús desplegables son una interfaz de navegación muy común. Hasta ahora con CSS podíamos hacer que los vínculos de las subsecciones aparecieran sin necesidad de JavaScript, pero si queríamos hacer que el efecto de dicha aparición fuera progresivo, no nos quedaba más opción que prog