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

Imágenes y medios

docs.scrimba.com

El texto lleva gran parte de una página web, pero no toda. Fotos, diagramas, ilustraciones, clips de video y sonido también son contenido, y HTML tiene elementos para cada uno. 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 datos de nadie.

El elemento image

Pones una foto en una página con el elemento image, escrito como <img>. No tiene contenido ni etiqueta de cierre. En su lugar, le dices dos cosas a través de atributos: qué archivo mostrar y de qué se trata la imagen.

html
<img src="golden-retriever.jpg" alt="Un golden retriever sentado en pasto alto">

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

El elemento <img> extrae un archivo externo en 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 estructurales:

html
<img src="/images/team-photo.jpg" alt="Los cinco miembros del equipo de diseño en sus escritorios">

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.

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

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

El atributo alt no es un título ni una descripción del archivo. Es un reemplazo: el texto que un navegador renderiza en el lugar de la imagen cuando la imagen está ausente, 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 foto. La prueba es la equivalencia funcional. Si sacaste la imagen e insertaste tu texto alt en el flujo, ¿seguiría teniendo sentido la oración y llevaría la misma información? Un buen alt pasa esa prueba; "photo1" no.

Dos reglas se derivan de esto. Primero, describe el propósito, no los píxeles: un icono de lupa dentro de un botón de búsqueda tiene alt="Buscar", no alt="lupa", porque su trabajo en la página es la acción, no el dibujo. Segundo, las imágenes decorativas toman un alt vacío. Cuando una imagen no agrega información, un adorno de fondo o un divisor, escribe alt="" sin nada entre las comillas. Eso no es lo mismo que dejar alt fuera. Un alt vacío le dice a la tecnología de asistencia "sáltalo, no lleva significado", mientras que un alt faltante hace que un lector de pantalla retroceda a leer el nombre del archivo en voz alta, lo cual es peor que el silencio.

html
<!-- Significativo: describe qué comunica -->
<img src="revenue-2024.png" alt="Los ingresos subieron de 1.2 a 2.4 millones durante 2024">

<!-- Decorativo: alt vacío, así que la tecnología de asistencia lo salta -->
<img src="corner-flourish.svg" alt="">
JunoEl elemento image Una imagen necesita dos cosas: src, que es el archivo a mostrar, y alt, que describe la foto en palabras. Escribe el alt como si le estuvieras diciendo a alguien por teléfono qué hay en la foto. Es la parte que se salta más, y es la parte que importa más.
JunoEl elemento image<img> es un elemento vacío: sin etiqueta de cierre, todo en los atributos. Describe qué dice la imagen, no el archivo, y nunca comiences 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 el gráfico está haciendo.
JunoEl elemento image Un buen alt es un reemplazo, no un título: insértalo en la oración y el significado debería sobrevivir. Describe el trabajo, no el dibujo, así que un icono de búsqueda lee Buscar. Y alt="" para imágenes decorativas es una verdadera opción, le dice a un lector de pantalla que salte, donde un alt faltante 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 grande de lo que un teléfono necesita. Enviar ese archivo de tamaño completo a una pantalla pequeña desperdicia los datos del visitante y ralentiza la página. HTML te permite ofrecer al navegador algunas versiones de la misma foto y dejar que elija la que se ajuste.

No necesitas esto para cada imagen mientras estés comenzando. Un solo <img> con un archivo sensato 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="Olas rodando en una playa tranquila al atardecer">

Las imágenes responsivas permiten que el navegador elija un archivo según la pantalla. En lugar de codificar una sola fuente, listas varias con srcset y describes cuánto ancho tendrá la imagen para mostrar con sizes. El navegador hace las matemáticas y descarga la mejor coincidencia.

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="Olas rodando en una playa tranquila al atardecer">

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

Cuando necesitas 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 maneja dirección de arte, sirviendo una imagen cortada diferentemente a diferentes anchos, y 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="Dos ciclistas subiendo un camino de montaña al amanecer">
</picture>

El navegador lee de arriba a abajo, elige el primer formato que entiende, y regresa al <img> simple si ninguno coincide. El <img> dentro es obligatorio; es lo que realmente se renderiza y donde vive alt.

Las imágenes responsivas resuelven un problema de cambio de resolución: la misma imagen, diferentes dimensiones de píxeles para diferentes pantallas, elegidas por el navegador antes de la descarga para que nadie pague por píxeles que no pueden ver. Hay dos herramientas, y responden preguntas diferentes.

srcset con sizes responde "¿cuál es la resolución?". Le das al navegador un conjunto de archivos candidatos, cada uno etiquetado con su ancho intrínseco en píxeles usando el descriptor w, y un valor sizes diciéndole cuán ancho será la imagen en varios puntos de ruptura. Un punto de ruptura es un umbral de ancho de pantalla en el que el diseño cambia. El navegador combina tu pista 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="Mochila de cuero mostrada de frente">

El elemento <picture> responde una pregunta diferente: "¿cuál es la fuente completa?". Es para casos donde el archivo en sí debería cambiar, no solo su escala. Dos razones comunes. Dirección de arte, donde un banner ancho se recorta a retrato vertical en pantallas estrechas para que el sujeto siga siendo visible, necesita diferentes archivos de imagen, no un archivo escalado. Y negociación de formato, donde ofreces un formato moderno con un respaldo, necesita que el navegador elija por lo que puede 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 preparando un plato en una cocina ocupada">
</picture>

El orden importa: el navegador toma el primer <source> cuyo media y type satisface, así que pon tus opciones más preferidas y más restringidas primero. 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 pertenecen a ese <img> interno.

JunoImágenes responsivas La misma foto puede venir en algunos tamaños, y el navegador puede elegir la que se ajuste a la pantalla para que un teléfono no descargue un archivo del tamaño de una laptop. No necesitas esto el primer día; un <img> simple está bien. La opción existe para cuando una página comienza a sentirse pesada en móvil.
JunoImágenes responsivas Usa srcset y sizes cuando quieras que el navegador elija un tamaño, y <picture> cuando quieras cambiar el archivo en sí, para un recorte diferente o un formato moderno. El <img> dentro de <picture> es obligatorio y es donde vive alt. Escribe el alt una vez; cada fuente es la misma foto.
JunoImágenes responsivas Dos trabajos diferentes: srcset más 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 a abajo, la primera coincidencia gana, así que ordena lo más restringido primero. Todo lo que se renderiza aún cuelga del <img> interno, así que ahí es donde van alt y el tamaño.

Video y audio

HTML puede reproducir video y sonido sin ningún complemento. Para un clip, usas el elemento <video>; para 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 de forma gratuita.

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

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

A diferencia de una imagen, estos tienen una etiqueta de cierre, porque puedes poner texto de respaldo o configuraciones adicionales entre las etiquetas de apertura y cierre. Lo más importante para recordar al comenzar: siempre incluye controls, o el visitante no tiene forma de presionar reproducción.

Los elementos <video> y <audio> incrustan un reproductor de medios nativo en la página. El atributo controls muestra la interfaz de reproducción, pausa, búsqueda y volumen integrada del navegador; sin él, no hay controles en absoluto.

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

Algunos atributos merecen su lugar. poster establece una imagen estática mostrada antes de que se reproduzca el video, para que el reproductor no sea 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, elimina src y enumera elementos <source> adentro. 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">
  Tu navegador no puede reproducir este video.
</video>

El texto después de las fuentes es contenido de respaldo, mostrado solo si el navegador no puede reproducir ninguno de ellos. <audio> funciona de la misma manera, con el mismo patrón de controls y <source>, menos los atributos visuales como poster y width.

<video> y <audio> incrustan la canalización de medios nativa del navegador, decodificación, almacenamiento en búfer y una UI de reproductor incorporada, sin un complemento de terceros. Ambos toman controls (muestran la UI nativa), y ambos aceptan múltiples hijos <source> para que puedas ofrecer varios códecs (los formatos de compresión en los que está codificado 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>
  Tu navegador no puede reproducir este video.
</video>

Dos preocupaciones de producción dominan aquí. La primera es accesibilidad, hacer que los medios sean usables por personas que no pueden oír o ver. Para eso es <track>: adjunta un archivo de texto sincronizado, generalmente en formato WebVTT (un formato de subtítulos de texto plano, archivos que terminan en .vtt), a los medios. kind="captions" proporciona una versión de texto del habla y sonido importante para espectadores que son sordos o en una configuración silenciosa, lo cual es la mayoría de las personas navegando 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. Video sin subtítulos excluye 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 pueden leer una transcripción.

La segunda preocupación es el ancho de banda. preload controla cuán ansiosamente el navegador obtiene los medios antes de la reproducción: preload="none" descarga nada hasta que el usuario presiona reproducción, preload="metadata" agarra solo la duración y dimensiones, y preload="auto" puede extraer el archivo completo. Predeterminadamente a metadata o none para cualquier cosa por debajo del pliegue, porque un video que se carga automáticamente es una de las cosas más pesadas que una página puede hacer silenciosamente. Y la misma advertencia de autoplay se mantiene: los navegadores bloquean audio activado en autoplay, por lo que un video que se reproduce automáticamente debe ser muted, que es otra razón por la que los subtítulos importan.

JunoVideo y audio<video> reproduce un clip y <audio> reproduce sonido, sin complementos necesarios. Agrega controls o no hay botón de reproducción y el visitante está atrapado. Ambos tienen etiquetas de cierre, porque puedes meter configuraciones y texto de respaldo adentro, a diferencia de una imagen.
JunoVideo y audio Siempre agrega controls, establece un poster para que el reproductor no sea un rectángulo negro, y enumera elementos <source> para ofrecer más de un formato. autoplay solo se ejecuta si el video es muted, así que esos dos van juntos. Audio es el mismo patrón sin los atributos visuales.
JunoVideo y audio Agrega una <track> con subtítulos; la mayoría de las personas miran silenciado, y los motores de búsqueda leen el texto que no pueden ver. Mantén preload en metadata o none para cualquier cosa por debajo del pliegue, un video que se carga automáticamente es una de las formas más silenciosas de hacer que una página sea pesada. Y el audio activado en autoplay está bloqueado, así que autoplay significa silenciado, que es una razón más para subtitular.

Tamaño, carga diferida y rendimiento

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

html
<img src="team-lunch.jpg" alt="El equipo compartiendo almuerzo en el balcón de la oficina"
     width="800" height="600">

Con esos números, el navegador reserva la cantidad correcta de espacio antes de que llegue la imagen, así que nada salta cuando lo hace. Das las dimensiones reales de píxeles del archivo, y CSS aún puede cambiar su tamaño en pantalla.

Las imágenes afectan dos cosas que sientes como usuario: cuánto se desplaza la página mientras se carga, y cuántos datos extrae. HTML te da atributos para ambos.

Establecer width y height previene el cambio de diseño, contenido saltando alrededor mientras se cargan las imágenes. Cuando declaras las dimensiones, el navegador reserva ese espacio inmediatamente en lugar de contraer la imagen a nada y luego expandirla una vez que llega el archivo.

html
<img src="article-header.jpg" alt="Vista aérea de una sala de redacción ocupada"
     width="1200" height="675" loading="lazy">

El atributo loading="lazy" le dice al navegador que no descargue la imagen hasta que el lector esté a punto de desplazarla a la vista. Para imágenes lejos en una página larga, eso guarda datos y acelera la primera pintura. Una regla: no hagas carga diferida de la imagen que el visitante ve primero, en la parte superior de la página. Esa quieres que se cargue lo más rápido posible, así que déjalo sin loading (o establece 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, no decoración. Tres importan.

Primero, cambio de diseño acumulativo, una medida de cuánto contenido visible salta alrededor mientras se carga la página. La causa habitual es una imagen sin tamaño declarado: el navegador le da altura cero, diseña todo debajo de ella, luego refluye la columna completa una vez que llega el archivo y se conoce su altura real. Lo evitas dándole al navegador la proporción de aspecto con anticipación. Establece width y height a las dimensiones reales de píxeles del archivo, y el navegador calcula la proporción y reserva la caja correcta aunque CSS redimensione la pantalla:

html
<img src="feature.jpg" alt="Paneles solares a través de un campo verde"
     width="1600" height="900" loading="lazy" decoding="async">

Puedes expresar la misma intención en CSS con la propiedad aspect-ratio; el punto es que la proporción debe ser conocible antes de que se descarguen los píxeles.

Segundo, loading="lazy" difiere la descarga de imágenes fuera de pantalla hasta que el lector se acerca a ellas, cortando 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 desplazarse, y una métrica que los navegadores y la clasificación de búsqueda observan). Hacer carga diferida de esa imagen demora lo mismo que mide la métrica, así que el héroe por encima del pliegue debería cargarse con entusiasmo.

Tercero, decoding="async" permite que el navegador decodifique la imagen fuera del hilo principal, para que convertir bytes comprimidos en píxeles no bloquee otra renderización. Es una pequeña ganancia segura para imágenes que no son lo primero en pantalla.

El formato es la otra palanca. WebP y AVIF son formatos de imagen modernos que se comprimen mucho más pequeños que JPEG o PNG con la misma calidad visual; AVIF típicamente gana en tamaño de archivo, WebP en soporte de navegador y velocidad de codificación. El compromiso es compatibilidad y herramientas, que es exactamente lo que <picture> con fuentes type está construida para manejar: ofrece AVIF primero, WebP siguiente, y un respaldo JPEG o PNG último, y cada navegador obtiene el mejor archivo que realmente puede decodificar.

JunoTamaño, carga diferida y rendimiento Dale a cada imagen un width y height y la página deja de saltar alrededor mientras se cargan las fotos. Usa el tamaño real de píxel del archivo; CSS aún puede encogerlo en pantalla. Este único hábito arregla el glitch de carga más molesto que existe.
JunoTamaño, carga diferida y rendimientowidth y height reservan espacio para que nada se desplace mientras se cargan las imágenes, y loading="lazy" posterga la descarga de imágenes hasta que están a punto de desplazarse a la vista. La imagen a la que no hacer carga diferida es la primera en la página; esa debería cargarse de inmediato.
JunoTamaño, carga diferida y rendimiento Declara width y height (o establece aspect-ratio) para que el navegador reserve la caja y el diseño deje de saltar; la proporción solo tiene que ser conocida antes de que aterricen los píxeles. Haz carga diferida de todo excepto el héroe por encima del pliegue, ya que hacer carga diferida de tu imagen visible más grande ralentiza la métrica que la observa. Y sirve AVIF o WebP a través de <picture> con un respaldo JPEG para que cada navegador obtenga el archivo más pequeño que pueda decodificar.