DEV Community

Cargando imágenes responsive con CSS

Uno de los recursos más usados en la web son las imágenes, hay muchas estrategias para cargar imágenes de manera eficiente, en esta ocasión voy a mostrarles una alternativa que no he visto.

Imágenes responsivas con srcset

Una de las formas más fáciles de cargar imágenes responsive es el atributo srcset el cual nos permite agregar una imagen dependiendo del tipo de resolución.

<image
  width="360px"
  height="360px"
  src="https://images.wikidexcdn.net/mwuploads/wikidex/thumb/4/43/latest/20190406170624/Bulbasaur.png/400px-Bulbasaur.png"
  srcset="https://images.wikidexcdn.net/mwuploads/wikidex/thumb/4/43/latest/20190406170624/Bulbasaur.png/800px-Bulbasaur.png 2x"

/>
Enter fullscreen mode Exit fullscreen mode

Gracias wikidex :3

En este ejemplo el browser cargará automaticamente la imagen que mejor se adapte a las condiciones del browser actual, en el caso que nuestra pantalla tenga el device pixel de 2, se cargará el srcset y en caso contrario se cargará el src normal.

Como nota, también podríamos utilizar esta sintaxis y visualmente resultaría lo mismo


<image
  width="360px"
  height="360px"
  srcset="https://images.wikidexcdn.net/mwuploads/wikidex/thumb/4/43/latest/20190406170624/Bulbasaur.png/400px-Bulbasaur.png 360w https://images.wikidexcdn.net/mwuploads/wikidex/thumb/4/43/latest/20190406170624/Bulbasaur.png/800px-Bulbasaur.png 800w"
/>

Enter fullscreen mode Exit fullscreen mode

Hay 3 posibles detalles con esta estrategia:

  1. No tenemos un control explícito de que imagen se carga para ciertas condiciones mas allá de la resolución.
  2. La resolución esta definida no por el tamaño del elemento sino el de la pantalla
  3. La sintaxis puede ser un poco compleja de entender

En un caso de uso que tuve necesitaba cargar una imagen pero solo en resoluciones tablet hacia arriba (vamos a decir que 800px), en mobile no debía mostrarse y por ende tampoco descargarse.

Para este caso srcset no me resultaba ideal porque haga lo que haga siempre se descargará una imagen, también se puede utilizar JS para ver si el dispositivo es mobile y en ese caso no agregar el atributo srcset a la imagen.

Hay muchas alternativas pero no me convencia mucho el uso de JS para este tipo de escenarios, así que pensé en usar CSS y custom properties.

Imágenes responsive con custom properties

En mi caso la imagen era mas que nada un elemento decorativo que descriptivo no tenía problemas con la accesibilidad. Lo cual podría mitigar con aria attributes pero siempre es mejor usar lo nativo que tratar de ser muy listo.

La clave para decidir usar este approach es que cuando usamos una imagen como background en CSS y lo combinamos con display: none la imagen no se descarga (que trucazo).

Esta alternativa no es una propuesta para que se use siempre, a mi me funcionó para mi caso de uso

El HTML es el siguiente

<section>
  <div
    class="image image-responsive"
    style="
      --bg-image: url('https://images.wikidexcdn.net/mwuploads/wikidex/thumb/5/56/latest/20200307023245/Charmander.png/800px-Charmander.png');
    "
  >
  </div>
  <image
    class="image"
    srcset="https://images.wikidexcdn.net/mwuploads/wikidex/thumb/4/43/latest/20190406170624/Bulbasaur.png/400px-Bulbasaur.png 360w, https://images.wikidexcdn.net/mwuploads/wikidex/thumb/4/43/latest/20190406170624/Bulbasaur.png/800px-Bulbasaur.png 800w"
  />
</section>
Enter fullscreen mode Exit fullscreen mode

Y el CSS

section {
  display: flex;
}

.image {
  height: 300px;
  width: 300px;
  display: none;
}

.image-responsive {
  background-image: var(--bg-image, "");
  background-size: cover;
}

@media (width > 800px) {
  .image {
    display: block;
  }
}
Enter fullscreen mode Exit fullscreen mode

En el srcset cargué 2 imágenes, aunque solo nos interesa la segunda la primera es mas que nada para mostrar la sintaxis de srcset

Recomiendo mirar el código y después ir al pen que cree, si estas en una resolución menor a 800px no verás nada pero en caso contrario verás a un charmander y a un bulbasaur.

Abre las devtools, pon el tab de network, filtra los request para solo mostrar los de imagen, haces un resize de pantalla a 360px y recarga. Si hicieste esto y revisas en las imágenes que se descargaron podrás ver que la imagen de bulbasaur se descarga pero no la de charmander.

Aunque en cierto aspecto la legibilidad de este approach no es muy buena ya que agregar custom properties directamente en el elemento y no a traves de una clase agrega mucho texto y es muy delicado en la parte del setup, ya que srcset es la solución ideal para el manejo de imágenes responsive. Pero también nos permite tener mayor claridad de que imagen se va a cargar ya que podrías tener varias custom properties para cargarse en escenarios como landscape o dark sin necesidad de usar JS.

Otro punto a favor o en contra (dependiendo de como lo veas) es que si haces un resize de pantalla se cargaran otras imágenes que hayas definido, dependiendo de la resolución ya que css es reactivo. Puede que quieras eso o no, con srcset solo se carga la primera imagen seleccionada de acuerdo al criterio definido así que no importa si se hace mas grande la pantalla o mas chica, solo se usará la que se descargó en un inicio.

Top comments (0)