Skip to content
This page has been auto-translated and may contain errors.View in English

Imágenes y multimedia ​

docs.scrimba.com

El texto carga con buena parte de una página web, pero no con toda. Las fotos, los diagramas, las ilustraciones, los clips de video y el sonido también son contenido, y HTML tiene elementos para cada uno de ellos. Este capítulo trata sobre el marcado que pone medios en una página: cómo apuntar a un archivo de imagen, cómo describirlo para las personas que no pueden verlo, y cómo servir el archivo correcto a la pantalla correcta sin desperdiciar los datos de nadie.

El elemento de imagen ​

Pones una imagen en una página con el elemento de imagen, que se escribe <img>. No tiene contenido ni etiqueta de cierre. En su lugar, le dices dos cosas mediante atributos: qué archivo mostrar y de qué se trata la imagen.

html
<img src="golden-retriever.jpg" alt="A golden retriever sitting in tall grass">

src es la fuente: la ruta o dirección web del archivo de imagen. alt es el texto alternativo: una descripción breve de la imagen en palabras. Si la imagen no carga, o si alguien está escuchando la página con un lector de pantalla en lugar de mirarla, el texto de alt es lo que recibe esa persona. Así que escríbelo como si le estuvieras describiendo la imagen a un amigo por teléfono.

El elemento <img> trae un archivo externo a la página. Es un elemento vacío, así que no tiene etiqueta de cierre; todo lo que necesita vive en sus atributos. Dos son indispensables:

html
<img src="/images/team-photo.jpg" alt="The five members of the design team at their desks">

src es la ruta del archivo, relativa a la página, o una URL absoluta. alt es el texto alternativo, las palabras que reemplazan a la imagen cuando no se muestra o no se puede ver.

Poner bien el alt es la parte que la gente se salta y no debería. Describe el contenido y el propósito de la imagen, no los detalles del archivo. "Gráfico de barras que muestra que las ventas se duplicaron entre 2023 y 2024" le dice al lector lo que dice el gráfico; "chart.png" no le dice nada. Mantenlo en una oración, y no empieces con "Imagen de", el navegador ya anuncia que es una imagen.

<img> es un elemento vacío que carga un recurso externo y lo ubica en línea con el texto por defecto. Dos atributos hacen el trabajo real: src (la URL del recurso) y alt (el texto alternativo). El resto de esta sección trata sobre alt, porque ahí es donde realmente se juegan la accesibilidad y la corrección de una imagen.

El atributo alt no es un pie de foto ni una descripción del archivo. Es un reemplazo: el texto que un navegador muestra en lugar de la imagen cuando esta no está disponible, y el texto que un lector de pantalla (software que lee una página en voz alta para personas que no pueden verla) pronuncia en lugar de la imagen. La prueba es la equivalencia funcional. Si quitaras la imagen y pusieras tu texto de alt en su lugar, ¿la oración seguiría teniendo sentido y transmitiría la misma información? Un buen alt pasa esa prueba; "photo1" no.

De ahí se desprenden dos reglas. Primero, describe el propósito antes que los píxeles: un ícono de lupa dentro de un botón de búsqueda lleva alt="Buscar", no alt="lupa", porque su función en la página es la acción, no el dibujo. Segundo, las imágenes decorativas llevan un alt vacío. Cuando una imagen no aporta información —un adorno de fondo o un divisor—, escribe alt="" sin nada entre las comillas. Eso no es lo mismo que omitir alt. Un alt vacío le dice a la tecnología de asistencia "sáltate esto, no tiene significado", mientras que la ausencia de alt hace que un lector de pantalla termine leyendo en voz alta el nombre del archivo, lo cual es peor que el silencio.

html
<!-- Con significado: describe lo que comunica -->
<img src="revenue-2024.png" alt="Revenue rose from 1.2 to 2.4 million across 2024">

<!-- Decorativa: alt vacío, así la tecnología de asistencia la omite -->
<img src="corner-flourish.svg" alt="">
JunoEl elemento de imagen Una imagen necesita dos cosas: src, que es el archivo a mostrar, y alt, que describe la imagen en palabras. Escribe el alt como si le estuvieras contando a alguien por teléfono lo que hay en la foto. Es la parte que más se salta la gente, y es la parte que más importa.
JunoEl elemento de imagen<img> es un elemento vacío: sin etiqueta de cierre, todo va en los atributos. Describe lo que dice la imagen, no el archivo, y nunca empieces con Imagen de, el navegador ya sabe que es una imagen. El alt de un gráfico debería decirle a alguien el número que ese gráfico está mostrando.
JunoEl elemento de imagen Un buen alt es un reemplazo, no un pie de foto: ponlo en la oración y el significado debería sobrevivir. Describe la función, no el dibujo, así que un ícono de búsqueda debería decir Buscar. Y alt="" para las imágenes decorativas es una decisión real, le indica a un lector de pantalla que se la salte, mientras que la falta de alt hace que lea el nombre del archivo en voz alta.

Imágenes responsivas ​

Una foto que se ve nítida en una laptop puede ser mucho más pesada de lo que necesita un teléfono. Enviar ese archivo a tamaño completo a una pantalla pequeña desperdicia los datos de quien visita la página y hace que cargue más lento. HTML te permite ofrecerle al navegador varias versiones de la misma imagen y dejar que él elija la que corresponde.

No necesitas esto para cada imagen mientras estás empezando. Un solo <img> con un archivo razonable está bien. Pero ayuda saber que la idea existe: la misma foto puede venir en varios tamaños, y el navegador elige.

html
<img src="beach-800.jpg" alt="Waves rolling onto a quiet beach at sunset">

Las imágenes responsivas dejan que el navegador elija un archivo según la pantalla. En lugar de fijar una sola fuente, listas varias con srcset y describes cuánto espacio ocupará la imagen con sizes. El navegador hace los cálculos y descarga la que mejor le conviene.

html
<img
  src="beach-800.jpg"
  srcset="beach-400.jpg 400w, beach-800.jpg 800w, beach-1600.jpg 1600w"
  sizes="(max-width: 600px) 100vw, 50vw"
  alt="Waves rolling onto a quiet beach at sunset">

En srcset, cada entrada empareja un archivo con su ancho real en píxeles (400w significa que el archivo tiene 400 píxeles de ancho). En sizes, le dices al navegador cuánto espacio va a ocupar la imagen: aquí llena todo el ancho de la ventana (100vw) en pantallas de hasta 600 píxeles, y la mitad del ancho (50vw) en el resto de los casos. El src se mantiene como respaldo para navegadores antiguos. Nota que el alt se escribe una sola vez y aplica a cada fuente, porque todas son la misma imagen.

Cuando necesites algo más que un cambio de tamaño, recurre a <picture>. Envuelve varios elementos <source> y un <img>, y el navegador usa el primer <source> que coincida. Esto resuelve la dirección de arte, es decir, servir una imagen recortada de forma distinta según el ancho, y también los formatos de archivo modernos:

html
<picture>
  <source srcset="hero.avif" type="image/avif">
  <source srcset="hero.webp" type="image/webp">
  <img src="hero.jpg" alt="Two cyclists climbing a mountain road at dawn">
</picture>

El navegador lee de arriba hacia abajo, elige el primer formato que entiende, y recurre al <img> simple si ninguno coincide. El <img> interno es obligatorio; es el que en realidad se renderiza y donde vive el alt.

Las imágenes responsivas resuelven un problema de selección de resolución: la misma imagen, con distintas dimensiones en píxeles para distintas pantallas, elegida por el navegador antes de descargarla para que nadie pague por píxeles que no puede ver. Hay dos herramientas, y responden preguntas distintas.

srcset junto con sizes responde "¿qué resolución?". Le das al navegador un conjunto de archivos candidatos, cada uno etiquetado con su ancho intrínseco en píxeles mediante el descriptor w, y un valor de sizes que le indica cuánto espacio ocupará la imagen en distintos puntos de quiebre. Un punto de quiebre es un umbral de ancho de pantalla en el que cambia el diseño. El navegador combina tu indicación de sizes con la densidad de píxeles del dispositivo para elegir el archivo más pequeño que aún se vea nítido.

html
<img
  src="product-800.jpg"
  srcset="product-400.jpg 400w, product-800.jpg 800w, product-1200.jpg 1200w"
  sizes="(max-width: 700px) 100vw, 350px"
  alt="Leather backpack shown from the front">

El elemento <picture> responde una pregunta distinta: "¿qué fuente por completo?". Es para los casos en los que el archivo en sí debe cambiar, y no solo su escala. Hay dos razones comunes. La dirección de arte, donde un banner ancho se recorta a un retrato vertical en pantallas angostas para que el sujeto siga visible, necesita archivos de imagen distintos, no un solo archivo reducido. Y la negociación de formato, donde ofreces un formato moderno con un respaldo, necesita que el navegador elija según lo que pueda decodificar.

html
<picture>
  <source media="(max-width: 600px)" srcset="hero-portrait.avif" type="image/avif">
  <source media="(max-width: 600px)" srcset="hero-portrait.jpg">
  <source srcset="hero-wide.avif" type="image/avif">
  <img src="hero-wide.jpg" alt="Chef plating a dish in a busy kitchen">
</picture>

El orden importa: el navegador toma el primer <source> cuyo media y type cumpla, así que pon primero tus opciones más preferidas y más restrictivas. El <img> final es obligatorio y es el elemento que la página realmente renderiza; srcset y sizes en las fuentes lo alimentan, pero alt, width, height y el comportamiento de carga van todos en ese <img> interno.

JunoImágenes responsivas La misma foto puede venir en varios tamaños, y el navegador puede elegir el que se ajusta a la pantalla, así un teléfono no descarga un archivo pensado para laptop. No necesitas esto desde el primer día; un <img> simple está bien. La opción está ahí para cuando una página empieza a sentirse pesada en el celular.
JunoImágenes responsivas Usa srcset y sizes cuando quieras que el navegador elija un tamaño, y <picture> cuando quieras cambiar el archivo por completo, para un recorte distinto o un formato moderno. El <img> dentro de <picture> es obligatorio y ahí es donde vive el alt. Escribe el alt una sola vez; cada fuente es la misma imagen.
JunoImágenes responsivas Son dos tareas distintas: srcset junto con sizes elige una resolución, <picture> elige una fuente completa para dirección de arte o negociación de formato. Las fuentes se leen de arriba hacia abajo, gana la primera coincidencia, así que ordénalas de la más restrictiva a la menos. Todo lo que se renderiza sigue dependiendo del <img> interno, así que ahí van el alt y el tamaño.

Video y audio ​

HTML puede reproducir video y sonido sin necesidad de complementos. Para un clip, usas el elemento <video>; para el sonido, <audio>. Agrega el atributo controls y el navegador te da un botón de reproducción, una línea de tiempo y un control de volumen sin esfuerzo adicional.

html
<video src="tutorial.mp4" controls></video>

<audio src="podcast-episode.mp3" controls></audio>

A diferencia de una imagen, estos tienen etiqueta de cierre, porque puedes poner texto de respaldo o configuraciones adicionales entre la etiqueta de apertura y la de cierre. Lo más importante de recordar al principio: incluye siempre controls, o quien visite la página no tendrá forma de darle a reproducir.

Los elementos <video> y <audio> incrustan un reproductor de medios nativo en la página. El atributo controls muestra la interfaz integrada del navegador para reproducir, pausar, avanzar y controlar el volumen; sin él, no hay controles de ningún tipo.

html
<video src="product-demo.mp4" controls width="640" poster="demo-cover.jpg"></video>

Algunos atributos se ganan su lugar. poster fija una imagen fija que se muestra antes de que el video reproduzca, así el reproductor no es una caja negra. width reserva el tamaño del reproductor. También puedes agregar autoplay, loop y muted, aunque la mayoría de los navegadores solo permiten autoplay cuando el video también es muted, así que esos dos van juntos.

Para ofrecer más de un formato de archivo, quita el src y en su lugar lista elementos <source> dentro. El navegador reproduce el primero que puede:

html
<video controls width="640" poster="demo-cover.jpg">
  <source src="product-demo.webm" type="video/webm">
  <source src="product-demo.mp4" type="video/mp4">
  Your browser cannot play this video.
</video>

El texto después de las fuentes es contenido de respaldo, que solo se muestra si el navegador no puede reproducir ninguna de ellas. <audio> funciona igual, con el mismo patrón de controls y <source>, menos los atributos visuales como poster y width.

<video> y <audio> incrustan el motor nativo de medios del navegador —decodificación, almacenamiento en búfer y una interfaz de reproducción integrada— sin necesidad de un complemento externo. Ambos aceptan controls (para mostrar la interfaz nativa), y ambos admiten varios elementos hijos <source> para que puedas ofrecer varios códecs (los formatos de compresión con los que se codifica un archivo de video o audio) y dejar que el navegador elija el primero que pueda decodificar.

html
<video controls width="640" height="360" poster="demo-cover.jpg" preload="metadata">
  <source src="demo.webm" type="video/webm">
  <source src="demo.mp4" type="video/mp4">
  <track kind="captions" src="demo-captions.en.vtt" srclang="en" label="English" default>
  Your browser cannot play this video.
</video>

Aquí dominan dos preocupaciones de producción. La primera es la accesibilidad, es decir, hacer que el contenido multimedia sea usable por personas que no pueden oírlo o verlo. Para eso está <track>: adjunta un archivo de texto sincronizado, normalmente en formato WebVTT (un formato de subtítulos en texto plano, con archivos terminados en .vtt), al contenido multimedia. kind="captions" ofrece una versión en texto del habla y de los sonidos importantes para espectadores sordos o en un entorno sin sonido, que es la situación de la mayoría de la gente que navega en público. kind="subtitles" traduce el diálogo a otro idioma. El atributo default activa una pista sin que el usuario tenga que buscarla. Un video sin subtítulos deja fuera a una parte real de tu audiencia, y los subtítulos también ayudan a los motores de búsqueda, que no pueden ver un video pero sí pueden leer una transcripción.

La segunda preocupación es el ancho de banda. preload controla con cuánta anticipación el navegador descarga el contenido multimedia antes de reproducirlo: preload="none" no descarga nada hasta que el usuario le da a reproducir, preload="metadata" solo obtiene la duración y las dimensiones, y preload="auto" puede descargar el archivo completo. Usa metadata o none por defecto para cualquier contenido que quede fuera de la vista inicial, porque un video que carga automáticamente es una de las cosas más pesadas que una página puede hacer sin que nadie se dé cuenta. Y se mantiene la misma advertencia sobre autoplay: los navegadores bloquean la reproducción automática con sonido, así que un video con reproducción automática debe estar en muted, lo cual es otra razón por la que importan los subtítulos.

JunoVideo y audio<video> reproduce un clip y <audio> reproduce sonido, sin necesidad de complementos. Agrega controls o no habrá botón de reproducción y quien visite la página se quedará sin poder hacer nada. Ambos tienen etiqueta de cierre, porque puedes meter configuraciones y texto de respaldo dentro de ellos, a diferencia de una imagen.
JunoVideo y audio Agrega siempre controls, define un poster para que el reproductor no sea un rectángulo negro, y lista elementos <source> para ofrecer más de un formato. autoplay solo funciona si el video está en muted, así que esos dos van juntos. El audio sigue el mismo patrón, sin los atributos visuales.
JunoVideo y audio Agrega un <track> con subtítulos; la mayoría de la gente mira con el sonido apagado, y los motores de búsqueda leen el texto que no pueden ver. Mantén preload en metadata o none para todo lo que quede fuera de la vista inicial; un video que carga automáticamente es una de las formas más silenciosas de hacer pesada una página. Y la reproducción automática con sonido está bloqueada, así que reproducción automática significa silenciado, otra razón más para subtitular.

Tamaño, carga diferida y rendimiento ​

Cuando una imagen carga, puede empujar el resto de la página. Estás leyendo un párrafo, una foto termina de cargar arriba de él, y de repente el texto salta hacia abajo. Ese salto es molesto, y puedes evitarlo: dile al navegador de antemano el tamaño de la imagen con width y height.

html
<img src="team-lunch.jpg" alt="The team sharing lunch on the office balcony"
     width="800" height="600">

Con esos números, el navegador reserva el espacio correcto antes de que la imagen llegue, así que nada salta cuando aparece. Le das las dimensiones reales en píxeles del archivo, y el CSS igual puede cambiarle el tamaño en pantalla.

Las imágenes afectan dos cosas que notas como usuario: cuánto se mueve la página mientras carga, y cuántos datos consume. HTML te da atributos para ambas cosas.

Definir width y height evita el salto de diseño (layout shift), es decir, que el contenido se mueva de lugar mientras las imágenes van cargando. Cuando declaras las dimensiones, el navegador reserva ese espacio de inmediato en lugar de colapsar la imagen a nada y luego expandirla cuando llega el archivo.

html
<img src="article-header.jpg" alt="Overhead view of a busy newsroom"
     width="1200" height="675" loading="lazy">

El atributo loading="lazy" le dice al navegador que no descargue la imagen hasta que el lector esté por hacerla visible con el scroll. Para imágenes ubicadas muy abajo en una página larga, eso ahorra datos y acelera la primera visualización. Una regla: no apliques carga diferida a la imagen que la persona ve primero, en la parte superior de la página. Esa quieres que cargue lo más rápido posible, así que déjale sin loading (o pon loading="eager").

Los medios suelen ser la parte más pesada de una página, así que los atributos que rigen su carga son controles de rendimiento. Ninguno es decorativo. Tres son importantes.

Primero, el cambio acumulativo de diseño (cumulative layout shift), una medida de cuánto se mueve el contenido visible mientras carga la página. La causa habitual es una imagen sin tamaño declarado: el navegador le da una altura de cero, ubica todo lo que va debajo, y luego reacomoda toda la columna una vez que llega el archivo y se conoce su altura real. Esto se evita dándole al navegador la proporción de antemano. Fija width y height con las dimensiones reales en píxeles del archivo, y el navegador calcula la proporción y reserva el espacio correcto incluso mientras el CSS cambia el tamaño de visualización:

html
<img src="feature.jpg" alt="Solar panels across a green field"
     width="1600" height="900" loading="lazy" decoding="async">

Puedes expresar la misma idea en CSS con la propiedad aspect-ratio; lo importante es que la proporción se pueda conocer antes de que los píxeles se descarguen.

Segundo, loading="lazy" retrasa la descarga de las imágenes que están fuera de la pantalla hasta que el lector se acerca a ellas, reduciendo la carga inicial en páginas largas. La excepción crítica es tu elemento LCP (Largest Contentful Paint, la imagen o bloque más grande visible sin hacer scroll, y una métrica que los navegadores y el posicionamiento en buscadores toman en cuenta). Aplicarle carga diferida a esa imagen retrasa justo lo que esa métrica mide, así que el elemento principal ubicado en la parte visible inicial debería cargar de inmediato.

Tercero, decoding="async" le permite al navegador decodificar la imagen fuera del hilo principal, así que convertir bytes comprimidos en píxeles no bloquea el resto del renderizado. Es una ganancia pequeña y segura para las imágenes que no son lo primero que se ve en pantalla.

El formato es la otra palanca. WebP y AVIF son formatos de imagen modernos que comprimen mucho más que JPEG o PNG con la misma calidad visual; AVIF suele ganar en tamaño de archivo, WebP en compatibilidad con navegadores y velocidad de codificación. La contrapartida es la compatibilidad y las herramientas, que es exactamente lo que <picture> con fuentes de type está diseñado para manejar: ofrece primero AVIF, luego WebP, y por último un respaldo en JPEG o PNG, así cada navegador obtiene el mejor archivo que en realidad puede decodificar.

JunoTamaño, carga diferida y rendimiento Dale a cada imagen un width y un height y la página deja de moverse mientras las fotos cargan. Usa el tamaño real en píxeles del archivo; el CSS igual puede achicarlo en pantalla. Este solo hábito arregla el problema de carga más molesto que existe.
JunoTamaño, carga diferida y rendimientowidth y height reservan el espacio para que nada se mueva mientras las imágenes cargan, y loading="lazy" retrasa la descarga de las imágenes hasta que están por aparecer con el scroll. La única imagen a la que no debes aplicarle carga diferida es la primera de la página; esa debe cargar de inmediato.
JunoTamaño, carga diferida y rendimiento Declara width y height (o define aspect-ratio) para que el navegador reserve el espacio y el diseño deje de saltar; la proporción solo necesita conocerse antes de que lleguen los píxeles. Aplica carga diferida a todo excepto al elemento principal de la vista inicial, porque aplicársela a tu imagen visible más grande ralentiza justo la métrica que la mide. Y sirve AVIF o WebP a través de <picture> con un respaldo en JPEG para que cada navegador reciba el archivo más pequeño que pueda decodificar.