Sintaxis prescriptivas

El elemento <picture> no renderiza nada por sí solo, sino que actúa como un motor de decisiones para un elemento <img> interno. diciéndole qué representar. <picture> sigue un precedente ya establecido por los elementos <audio> y <video>: un elemento wrapper que contiene elementos <source> individuales.

<picture>
   <source …>
   <source …>
    <img …>
</picture …>

Ese <img> interno también te proporciona un patrón de resguardo confiable para navegadores más antiguos sin compatibilidad con imágenes responsivas: Si el navegador del usuario no reconoce el elemento <picture>, se ignorará. Luego, también se descartan los elementos <source>. ya que el navegador no los reconocerá o no tendrá un contexto significativo para ellos sin un elemento superior <video> o <audio>. Sin embargo, cualquier navegador reconocerá el elemento <img> interno y la fuente especificada en su src se renderizará como se espera.

"Dirección de arte" imágenes con <picture>

Realizar cambios en el contenido o la relación de aspecto de una imagen en función de su tamaño en la página se suele denominar “dirigida a material gráfico”. con imágenes responsivas. srcset y sizes están diseñados para funcionar de manera invisible y sin problemas, como intercambio de fuentes a medida que lo indica el navegador del usuario. Sin embargo, hay ocasiones en las que es conveniente alterar las fuentes de los puntos de interrupción para destacar mejor el contenido, de la misma manera en que adaptas los diseños de página. Por ejemplo, una imagen de encabezado de ancho completo con un enfoque central pequeño puede funcionar bien en una ventana de visualización grande:

Una imagen del ancho del encabezado de una flor de lavanda rodeada de hojas y tallos, visitada por una abeja.

Sin embargo, cuando se reduzca la escala verticalmente para ajustarse a viewports pequeños, es posible que se pierda el enfoque central de la imagen:

Imagen del ancho del encabezado de una flor de color violeta, reducida. La abeja apenas se puede ver.

El asunto de estas fuentes de imágenes es el mismo, pero para enfocarnos mejor en él de forma visual, debes proporciones de la fuente de la imagen para cambiar entre los puntos de interrupción. Por ejemplo, un zoom más ajustado en el centro de la imagen y algunos de los detalles en los bordes recortados:

Un recorte acercado de la flor de lavanda.

Ese tipo de “recortar” se puede lograr a través de CSS, pero haría que un usuario solicite todos los datos que conforman esa imagen. aunque quizás nunca terminen viéndolo.

Cada elemento source tiene atributos que definen las condiciones para seleccionar ese source: media, que acepta un consulta de medios, y type, que acepta un tipo de medio (anteriormente conocido como "tipo de MIME"). La primera <source> en la fuente para que coincida con el contexto de navegación actual del usuario, y el contenido del atributo srcset en ese source se utilizarán para determinar los candidatos adecuados en cada contexto. En este ejemplo, se muestra el primer source con un atributo media. que coincida con el tamaño del viewport del usuario será el seleccionado:

<picture>
  <source media="(min-width: 1200px)" srcset="wide-crop.jpg">
  <img src="close-crop.jpg" alt="…">
</picture>

Siempre debes especificar el img interno en último lugar en el orden, si ninguno de los elementos source coincide con su media o type. la imagen se comportará como una fuente. Si utiliza min-width consultas de medios, le recomendamos que tenga el mayor a las fuentes primero, como se ve en el código anterior. Cuando uses consultas de medios max-width, debes colocar primero la fuente más pequeña.

<picture>
   <source media="(max-width: 400px)" srcset="mid-bp.jpg">
   <source media="(max-width: 800px)" srcset="high-bp.jpg">
   <img src="highest-bp.jpg" alt="…">
</picture>

Cuando se elige una fuente según los criterios que especificaste, se pasa el atributo srcset en source al <img> como si se definiera en <img>, lo que significa que puedes usar sizes para optimizar la imagen dirigida al arte fuentes de datos.

<picture>
   <source media="(min-width: 800px)" srcset="high-bp-1600.jpg 1600w, high-bp-1000.jpg 1000w">
   <source srcset="lower-bp-1200.jpg 1200w, lower-bp-800.jpg 800w">
   <img src="fallback.jpg" alt="…" sizes="calc(100vw - 2em)">
</picture>

Por supuesto, una imagen con proporciones que pueden variar según el elemento <source> seleccionado genera un problema de rendimiento: <img> solo admite un único atributo width y height, pero omitir esos atributos puede generar una experiencia del usuario mucho peor. Para dar cuenta de esto, es una estrategia relativamente reciente, pero bien compatible, además del código HTML esta especificación permite el uso de los atributos height y width en elementos <source>. También trabajan para reducir los cambios de diseño como lo hacen en <img>, con el espacio apropiado reservado en tu diseño para cualquier elemento <source> que se seleccione.

<picture>
   <source
      media="(min-width: 800px)"
      srcset="high-bp-1600.jpg 1600w, high-bp-1000.jpg 1000w"
      width="1600"
      height="800">
   <img src="fallback.jpg"
      srcset="lower-bp-1200.jpg 1200w, lower-bp-800.jpg 800w"
      sizes="calc(100vw - 2em)"
      width="1200"
      height="750"
      alt="…">
</picture>

Es importante tener en cuenta que la dirección artística no solo sirve para tomar decisiones basadas en el tamaño del viewport, y debería usarse, ya que la mayoría de esos casos se pueden manejar de manera más eficiente con srcset/sizes. Por ejemplo, seleccionar mejor una fuente de imagen adecuado para el esquema de colores dictado por la preferencia del usuario:

<picture>
   <source media="(prefers-color-scheme: dark)" srcset="hero-dark.jpg">
   <img srcset="hero-light.jpg">
</picture>

El atributo type

El atributo type te permite usar el motor de decisión de solicitud única del elemento <picture> para publicar solo formatos de imagen. a los navegadores compatibles.

Como aprendiste en Formatos de imagen y compresión, una codificación que el navegador no pueda analizar ni siquiera se reconocerá como datos de imágenes.

Antes de la introducción del elemento <picture>, se requieren las soluciones de frontend más viables para la publicación de nuevos formatos de imagen que el navegador solicite e intente analizar un archivo de imagen antes de determinar si debe descartarlo y cargar un resguardo. R Un ejemplo común fue una secuencia de comandos similar a estas líneas:

   <img src="image.webp"
    data-fallback="image.jpg"
    onerror="this.src=this.getAttribute('data-fallback'); this.onerror=null;"
    alt="...">

Con este patrón, se seguiría realizando una solicitud de image.webp en todos los navegadores, lo que significa que se desperdiciaría una transferencia de navegadores. sin compatibilidad con WebP. Los navegadores que no podían analizar la codificación WebP arrojarían un evento onerror e intercambiarían el valor data-fallback en src. Era una solución desperdiciada, pero, de nuevo, los enfoques como este eran la única opción. disponibles en el frontend. Recuerda que el navegador comienza a realizar solicitudes de imágenes antes de que cualquier secuencia de comandos personalizada tenga un la oportunidad de ejecutarse, o incluso de ser analizada, por lo que no podíamos anticipar este proceso.

El elemento <picture> está diseñado de forma explícita para evitar esas solicitudes redundantes. Aunque todavía no hay forma de que un navegador para reconocer un formato que no admite sin solicitarlo, el atributo type advierte al navegador sobre la fuente. codificación por adelantado, de modo que pueda decidir si debe realizar o no una solicitud.

En el atributo type, proporcionas el tipo de medio (anteriormente, tipo de MIME). de la fuente de la imagen especificada en el atributo srcset de cada <source>. De este modo, el navegador tiene toda la información que debe determinar inmediatamente si la imagen candidata que proporciona ese source se puede decodificar sin hacer ninguna solicitudes: si no se reconoce el tipo de medio, se ignoran <source> y todos sus candidatos, y el navegador avanza.

<picture>
 <source type="image/webp" srcset="pic.webp">
 <img src="pic.jpg" alt="...">
</picture>

Aquí, cualquier navegador compatible con la codificación WebP reconocerá el tipo de medio image/webp especificado en el atributo type. del elemento <source>, selecciona ese <source> y, como solo proporcionamos un único candidato en srcset, indica al elemento <img> para solicitar, transferir y renderizar pic.webp. Cualquier navegador sin compatibilidad con WebP ignorará las source. sin instrucciones que expresen lo contrario, <img> renderizará el contenido de src como lo ha hecho desde 1992. No necesitas especificar un segundo elemento <source> con type="image/jpeg" aquí, por supuesto. Puedes suponer que es compatible con JPEG.

Independientemente del contexto de navegación del usuario, todo esto se logra con una transferencia de archivos única y sin desperdicio de ancho de banda en fuentes de imágenes que no se pueden renderizar. Además, es una herramienta innovadora: a medida que surjan formatos de archivo más nuevos y eficaces con tipos de medios propios y podremos aprovecharlos gracias a picture, sin JavaScript ni servidor las dependencias y toda la velocidad de <img>.

El futuro de las imágenes responsivas

Todos los patrones de marcado que se analizan aquí fueron un trabajo pesado en términos de estandarización: cambiar la funcionalidad de algo tan establecido y central para la Web como <img> no fue sencillo, y el conjunto de problemas que esos cambios apuntaban a resolver resolver fueron extensas, por así decirlo. Si ahora piensas que hay mucho por mejorar con estos de lenguaje de marcado, tienes toda la razón. Desde el principio, estos estándares se diseñaron como base para el futuro tecnologías para desarrollar.

Todas estas soluciones han dependido necesariamente del lenguaje de marcado, de modo que se incluyan en la carga útil inicial del servidor. y llegar a tiempo para que el navegador solicite fuentes de imágenes, una limitación que condujo al atributo sizes claramente difícil de manejar.

Sin embargo, desde que estas funciones se introdujeron en la plataforma web, se introdujo un método nativo para diferir las solicitudes de imágenes. Los elementos <img> con el atributo loading="lazy" no se solicitan hasta que se conoce el diseño de la página, para diferir. solicitudes de imágenes fuera del viewport inicial del usuario hasta más adelante en el proceso de renderización de la página, lo que podría evitar innecesarias. Como el navegador entiende completamente el diseño de la página en el momento en que se realizan estas solicitudes, una Se propuso el atributo sizes="auto" como complemento de la especificación HTML para evitar la carga de los atributos sizes escritos de forma manual en estos casos.

También se incorporarán elementos <picture> en el horizonte para que concuerden con algunos cambios excepcionalmente emocionantes. a la forma en que diseñamos los diseños de página. Si bien la información del viewport es una base sólida para decisiones de diseño de alto nivel, nos impide adoptar un enfoque de desarrollo a nivel de todos los componentes, es decir, un componente que se pueda incorporar cualquier parte de un diseño de página, con estilos que respondan al espacio que ocupa el componente. Esta preocupación generó hasta la creación de consultas de contenedores: un método de diseño de elementos en función del tamaño del contenedor superior, en lugar del viewport solo.

Aunque la sintaxis de consulta del contenedor recién se estabilizó, y la compatibilidad con los navegadores es muy limitada, al momento de la redacción; la incorporación de tecnologías de navegador que lo permitan proporcionará al elemento <picture> una significa hacer lo mismo: un posible atributo container que permite criterios de selección de <source> basados en el espacio que ocupa el elemento <img> del elemento <picture>, en lugar de basarse en el tamaño del viewport.

Si eso suena poco claro, bueno, hay una buena razón: estas discusiones sobre estándares web son continuas, pero están lejos de ser resueltos, todavía no las puedes usar.

Si bien el lenguaje de marcado de imágenes responsivas promete que con el tiempo será más fácil trabajar con él, como con cualquier tecnología web, hay una variedad de servicios, tecnologías y frameworks para ayudar a aliviar la carga de escribir a mano este lenguaje de marcado. En el próximo módulo, veremos cómo integrar todo lo que aprendimos sobre formatos de imagen, imágenes responsivas y compresión en un flujo de trabajo de desarrollo moderno.