Imágenes y multimedia
La etiqueta <img>
La etiqueta <img> inserta una imagen en el documento. Es un elemento vacío: no tiene etiqueta de cierre, y su contenido lo definen los atributos.
<img src="/images/cabecera.jpg" alt="Vista del puerto al amanecer" width="800" height="450">
Los atributos esenciales son cuatro.
src indica la ubicación de la imagen. Puede ser una ruta relativa al sitio (/images/foto.jpg), relativa al documento (../images/foto.jpg) o una URL absoluta. En general, las rutas relativas al sitio son las más robustas: funcionan correctamente aunque el HTML se sirva desde rutas virtuales o con enrutamiento dinámico. Las rutas relativas al documento pueden dar problemas si el archivo se mueve o si el servidor reescribe URLs. Las rutas absolutas son apropiadas cuando la imagen está alojada en otro dominio.
alt proporciona una descripción textual de la imagen. Lo veremos en detalle en la sección siguiente.
width y height indican las dimensiones en píxeles. No son obligatorios, pero su presencia tiene una consecuencia práctica importante: el navegador puede reservar el espacio correspondiente antes de que la imagen se descargue, evitando el desplazamiento repentino del contenido durante la carga. Ese fenómeno afecta negativamente tanto a la experiencia del usuario como al posicionamiento en buscadores. Incluye siempre width y height.
El atributo alt
El atributo alt es obligatorio en toda etiqueta <img>. Su función es proporcionar una alternativa textual para quienes no pueden ver la imagen: usuarios de lectores de pantalla, buscadores, o situaciones en que la imagen no carga.
Para imágenes con contenido informativo, describe lo que muestra la imagen de forma concisa y relevante en contexto. «Foto de producto» no ayuda a nadie; «Zapatilla Nike Air Max en color blanco, vista lateral» sí.
Para imágenes decorativas que no aportan información adicional al texto que las rodea, el alt debe estar vacío: alt="". Esto le indica al lector de pantalla que ignore la imagen en lugar de anunciar el nombre del archivo. No omitas el atributo: si falta, algunos lectores de pantalla leen el nombre del archivo, que raramente es descriptivo.
El atributo role="presentation" (o su sinónimo role="none") hace explícito que un elemento no tiene significado semántico. Algunos desarrolladores lo añaden junto a alt="" en imágenes decorativas para dejar la intención más clara al leer el código. Según la especificación, alt="" solo es suficiente; role="presentation" es redundante pero inofensivo:
<img src="separador.png" alt="" role="presentation" width="800" height="4">
Para imágenes que actúan como botón o enlace, describe la acción o el destino, no la imagen en sí.
<!-- Imagen informativa -->
<img src="grafico-ventas.png" alt="Gráfico de barras: ventas trimestrales 2024, crecimiento del 12% en Q4" width="600" height="400">
<!-- Imagen decorativa -->
<img src="separador.png" alt="" width="800" height="4">
<!-- Imagen como enlace -->
<a href="/"><img src="logo.svg" alt="Inicio - Mi empresa" width="120" height="40"></a>
Formatos de imagen
La elección del formato afecta al peso del archivo, la calidad visual y las capacidades de la imagen.
JPG es el formato habitual para fotografías e imágenes con muchos tonos y gradientes. Usa compresión con pérdida: reduce el tamaño del archivo sacrificando algo de calidad. Para web, entre el 70% y el 85% de calidad suele ser el equilibrio adecuado.
PNG usa compresión sin pérdida y soporta transparencia. Es la opción correcta para logotipos, capturas de pantalla e imágenes con bordes nítidos o texto. Los archivos son más pesados que JPG para fotografías, pero más ligeros para gráficos con pocas variaciones de color.
SVG es un formato vectorial: la imagen se define mediante coordenadas matemáticas, no píxeles, por lo que escala sin perder calidad a cualquier tamaño. Es la opción ideal para iconos, ilustraciones y logotipos. Los archivos SVG son texto XML, por lo que pueden editarse e incluso animarse con CSS.
WebP ofrece mejor compresión que JPG y PNG para ambos tipos de imagen, con soporte para transparencia. Tiene soporte universal en navegadores modernos y es la primera opción a considerar en proyectos nuevos.
AVIF va un paso más allá en compresión y calidad que WebP, con soporte para HDR y colores de alta profundidad. El soporte en navegadores es bueno desde 2023, aunque en algunos entornos conviene ofrecer un formato alternativo como respaldo.
GIF soporta animaciones simples, pero su paleta de 256 colores lo hace inadecuado para fotografías. Para animaciones en la web moderna existen alternativas mejores: vídeos cortos en MP4 o WebM ocupan mucho menos espacio con la misma calidad visual.
El elemento <picture> permite ofrecer varios formatos y dejar que el navegador use el primero que soporta, con <img> como fallback universal:
<picture>
<source srcset="foto.avif" type="image/avif">
<source srcset="foto.webp" type="image/webp">
<img src="foto.jpg" alt="Descripción de la foto" width="800" height="600">
</picture>
Imágenes como elemento en línea
<img> es un elemento en línea: se integra en el flujo del texto sin provocar saltos de línea, igual que <strong> o <span>. Puede aparecer dentro de un párrafo, aunque en la práctica es poco habitual salvo para iconos pequeños:
<p>El logotipo <img src="logo.svg" alt="Logo" width="24" height="24"> está registrado.</p>
Para que una imagen se comporte como bloque (ocupe su propia línea y admita márgenes verticales), basta con CSS:
img {
display: block;
}
CSS para imágenes
La regla más básica para imágenes responsivas es evitar que superen el ancho de su contenedor:
img {
max-width: 100%;
height: auto; /* mantiene la proporción */
}
Cuando necesitas que una imagen ocupe exactamente un área determinada sin deformarse, object-fit es la propiedad adecuada:
img {
width: 300px;
height: 200px;
object-fit: cover; /* recorta lo que sobra, sin deformar */
}
Los valores más útiles de object-fit son cover (rellena el área recortando si hace falta), contain (la imagen queda completa dentro del área, con espacio vacío si las proporciones no coinciden) y fill (estira la imagen para rellenar el área, puede deformar).
object-position controla qué parte de la imagen queda visible cuando se recorta, con la misma sintaxis que background-position:
img {
width: 300px;
height: 200px;
object-fit: cover;
object-position: center top; /* mantiene visible la parte superior */
}
Para mantener una proporción específica independientemente del tamaño del contenedor, aspect-ratio evita tener que calcular alturas manualmente:
img {
width: 100%;
aspect-ratio: 16 / 9;
object-fit: cover;
}
Figuras y pies de foto
Cuando una imagen va acompañada de un pie de foto o una leyenda, HTML5 ofrece los elementos semánticos correctos para ello:
<figure>
<img src="plano-ciudad.jpg" alt="Plano del centro histórico de Sevilla" width="800" height="600">
<figcaption>Centro histórico de Sevilla, con el recorrido turístico señalado en rojo.</figcaption>
</figure>
<figure> no tiene que contener necesariamente una imagen: puede envolver un bloque de código, un gráfico, una cita o cualquier contenido que sea una unidad autocontenida referenciada desde el texto principal. <figcaption> es el pie de esa unidad y puede ir antes o después del contenido.
El navegador no aplica ningún estilo especial por defecto más allá de un margen lateral, así que el aspecto visual depende completamente de CSS.
Imágenes responsivas
En una época en que una misma página se ve en móviles de 4 pulgadas y monitores de 27, servir siempre la misma imagen es un desperdicio. srcset permite ofrecer varias versiones y dejar que el navegador elija la más adecuada:
<img
src="foto-800.jpg"
srcset="foto-400.jpg 400w, foto-800.jpg 800w, foto-1600.jpg 1600w"
sizes="(max-width: 600px) 100vw, 800px"
alt="Descripción de la foto"
width="800"
height="600">
srcset lista las versiones disponibles con su anchura real en píxeles (el sufijo w). sizes le dice al navegador cuánto espacio ocupará la imagen en pantalla según el tamaño de la ventana, para que pueda elegir la versión óptima antes de descargarla. En el ejemplo: en pantallas de hasta 600px de ancho, la imagen ocupa el 100% del viewport; en el resto, 800px.
loading="lazy" difiere la carga de la imagen hasta que el usuario se aproxima a ella en el scroll. Es especialmente útil en páginas largas con muchas imágenes. Para las imágenes visibles sin hacer scroll, no incluyas el atributo o usa loading="eager":
<!-- Imagen fuera del viewport inicial -->
<img src="galeria-3.jpg" alt="..." width="600" height="400" loading="lazy">
<!-- Imagen principal visible al cargar: no diferir -->
<img src="hero.jpg" alt="..." width="1200" height="600">
Multimedia propia
Cuando tienes archivos de vídeo o audio propios alojados en tu servidor, las etiquetas <video> y <audio> son la opción correcta, sin depender de servicios externos.
<video width="640" height="360" controls poster="miniatura.jpg">
<source src="video.webm" type="video/webm">
<source src="video.mp4" type="video/mp4">
Tu navegador no soporta el elemento de vídeo.
</video>
controls muestra los controles del reproductor. poster define la imagen que aparece antes de que empiece la reproducción. <source> permite ofrecer el mismo vídeo en varios formatos: el navegador usa el primero que soporta. WebM con codec VP9 ofrece mejor compresión que MP4, pero MP4 tiene soporte más amplio, así que lo habitual es ofrecer los dos.
Otros atributos útiles: loop (repite el vídeo), muted (sin sonido inicial), autoplay (requiere también muted para funcionar en la mayoría de navegadores modernos).
<audio controls>
<source src="podcast.ogg" type="audio/ogg">
<source src="podcast.mp3" type="audio/mpeg">
Tu navegador no soporta el elemento de audio.
</audio>
<audio> funciona igual que <video> pero sin dimensiones visuales. Los formatos más comunes son MP3 (soporte universal) y OGG/Vorbis (mejor compresión, algo menos universal).
Contenido incrustado: <iframe>
<iframe> (inline frame) muestra contenido de otra fuente dentro de tu página: vídeos de YouTube, mapas de Google Maps, widgets externos. A diferencia de los antiguos frames, que dividían la ventana entera, un <iframe> es un elemento como cualquier otro que puedes colocar donde necesites.
<iframe
src="https://www.youtube.com/embed/ID_DEL_VIDEO"
width="560"
height="315"
title="Título descriptivo del vídeo"
allowfullscreen
loading="lazy">
</iframe>
El atributo title es obligatorio desde el punto de vista de la accesibilidad: los lectores de pantalla lo usan para describir el contenido del iframe. allow controla qué funciones del navegador puede usar el contenido incrustado. sandbox restringe lo que puede hacer el iframe por seguridad, y es recomendable cuando el origen no es de total confianza.
Para hacer un iframe responsivo manteniendo las proporciones de vídeo, envuélvelo en un contenedor con aspect-ratio:
.video-container {
width: 100%;
aspect-ratio: 16 / 9;
}
.video-container iframe {
width: 100%;
height: 100%;
border: none;
}
<div class="video-container">
<iframe src="https://www.youtube.com/embed/ID" title="..." allowfullscreen></iframe>
</div>
Nota: Algunas páginas bloquean que las incruste un iframe ajeno. Si el iframe aparece en blanco o con un error, es probable que el sitio destino lo esté impidiendo mediante la cabecera HTTP X-Frame-Options.
Material histórico
Antes de CSS, los atributos HTML controlaban directamente la presentación de las imágenes. Todos están obsoletos en HTML5.
align en <img> definía la alineación y si el texto fluía alrededor. hspace y vspace añadían espacio horizontal y vertical. border añadía un borde. Todo eso se hace hoy con CSS:
<!-- Obsoleto, no usar -->
<img src="foto.jpg" align="right" hspace="10" vspace="5" border="2">
<!-- Correcto -->
<img src="foto.jpg" style="float: right; margin: 5px 0 5px 10px; border: 2px solid #ccc;" alt="...">
Los frames (<frameset>, <frame>, <noframes>) dividían la ventana del navegador en secciones independientes, cada una con su propio documento HTML. El mecanismo tenía problemas serios: las URLs no reflejaban el estado de la página, era difícil marcar en favoritos o compartir una vista concreta, y la accesibilidad era mala. HTML5 los eliminó. <iframe> es el único elemento de este grupo que sobrevivió, con un uso completamente distinto.
Tu proyecto
Crea una carpeta imagenes/ dentro de tu carpeta de proyecto. Coloca ahí una foto tuya o una imagen que represente tu trabajo. Añádela a proyecto.html con su alt y hazla responsiva:
<img src="imagenes/foto-perfil.jpg"
alt="Laura Suárez, arquitecta"
width="400" height="400"
style="max-width: 100%; height: auto;">
Si tienes más imágenes (proyectos, trabajos), añade dos o tres más. No te preocupes por el layout todavía: por ahora aparecerán una debajo de la otra. Las colocaremos en cuadrícula cuando lleguemos a CSS Grid.
Recapitulación
<img>requiere siempresrcyalt. Incluyewidthyheightpara evitar saltos de contenido durante la carga.- Un buen
altdescribe la función de la imagen en contexto. Las imágenes decorativas llevanalt="".role="presentation"se puede añadir para hacer explícita la intención, aunque es redundante conalt="". - Para fotografías usa WebP (o JPG como fallback). Para gráficos con transparencia, PNG. Para iconos e ilustraciones, SVG.
<picture>con<source>permite ofrecer varios formatos. max-width: 100%; height: autohace las imágenes responsivas.object-fitcontrola el recorte cuando la imagen tiene dimensiones fijas.aspect-ratiomantiene proporciones sin calcular alturas.<figure>y<figcaption>son los elementos semánticos para imágenes con pie de foto.srcsetysizessirven versiones distintas de la misma imagen según el dispositivo.loading="lazy"difiere la carga de imágenes fuera del viewport.<video>y<audio>con<source>permiten multimedia propia sin depender de servicios externos.<iframe>incrusta contenido externo. Usa siempretitlepara accesibilidad yloading="lazy"para contenido pesado.- Los atributos
align,hspace,vspaceyborderen<img>, y los elementos<frameset>y<frame>, son obsoletos.
En la próxima lección: las tres formas de incluir CSS, Google Fonts, y la cascada. A partir de aquí el proyecto empieza a tener aspecto.