<video>
Imágenes y multimedia
Incrusta un reproductor de video en la página, con controles nativos del navegador, soporte para múltiples formatos mediante hijos <source>, y subtítulos accesibles con <track>.
<video> incrusta un reproductor de video directamente en el documento HTML, sin plugins ni JavaScript externo. Desde HTML5, el navegador provee la interfaz de reproducción nativa (play/pausa, barra de progreso, volumen, pantalla completa) cuando se activa el atributo controls. El resultado es un reproductor que se integra visualmente con el sitio y funciona en cualquier plataforma moderna.
A diferencia de <img>, <video> tiene etiqueta de apertura y cierre y puede contener hijos. Eso habilita dos capacidades centrales: los elementos <source> (para ofrecer el mismo video en múltiples formatos y que el navegador elija el que soporta) y los elementos <track> (para subtítulos, transcripciones y descripciones de audio, que hacen el video accesible). La diferencia con <img> también es de modelo de contenido: un <video> sin controls es válido en HTML pero invisible para el usuario; siempre se necesita alguna forma de iniciarlo.
<video> es un elemento de contenido incrustado y su display por defecto es en línea, pero casi siempre se usa con CSS para convertirlo en bloque o para controlarlo dentro de un layout. El navegador reserva espacio según width/height declarados o las dimensiones intrínsecas del video. No hay layout shift porque el elemento existe en el DOM desde el principio, aunque el archivo tarde en llegar.
Cómo funciona
El navegador descarga el archivo de video (o el primer <source> soportado) en paralelo con el resto de la página. Cuánto descarga depende del atributo preload: por defecto solo baja los metadatos (duración, dimensiones) y no el video completo, para ahorrar datos.
Cuando el usuario hace clic en play (o cuando autoplay está activo), el navegador empieza a decodificar y mostrar los fotogramas. El área de video existe en el DOM desde el inicio; si hay poster, lo muestra hasta que empieza la reproducción.
Si el elemento tiene hijos <source>, el navegador los evalúa en orden y usa el primero cuyo type soporte. Si ningún <source> funciona o el elemento no tiene controls ni JavaScript para iniciarlo, el video no se ve ni se reproduce.
Modelo de contenido
<video> es contenido incrustado y de flujo (flow content). Puede contener:
- Cero o más elementos
<source>(como primeros hijos, antes de cualquier otro contenido). - Cero o más elementos
<track>(después de los<source>). - Contenido de respaldo (fallback) que solo se muestra si el navegador no soporta
<video>(hoy irrelevante en la práctica, pero válido).
Display por defecto: en línea (inline), aunque casi siempre se usa como bloque.
Sintaxis
<!-- Patrón A: un solo formato, src en el elemento -->
<video src="intro.mp4" controls width="640" height="360"></video>
<!-- Patrón B: múltiples formatos con <source> hijos (recomendado) -->
<video controls poster="portada.jpg" width="640" height="360">
<source src="intro.webm" type="video/webm">
<source src="intro.mp4" type="video/mp4">
</video>
Los dos patrones son mutuamente excluyentes: si usás <source> hijos, no pongas src en el <video>. Si tenés src en el <video>, los <source> se ignoran.
Atributos
src
La ruta o URL del archivo de video. Usalo solo cuando tenés un único formato disponible. Si necesitás soporte para múltiples formatos, usá <source> hijos y omitís este atributo (ver <source> más abajo).
controls
Atributo booleano. Sin él, no hay interfaz de usuario: el video existe en el DOM pero el usuario no puede reproducirlo, pausarlo ni ajustar el volumen. En el 99% de los casos de contenido editorial, siempre se incluye.
La apariencia de los controles varía entre navegadores (Chrome, Firefox, Safari tienen distintos estilos), pero la funcionalidad es la misma. Para personalizar la apariencia, es necesario construir controles propios con JavaScript.
<video src="intro.mp4" controls></video>
poster
URL de la imagen que se muestra antes de que el video empiece a reproducirse (la “portada” o thumbnail). Si se omite, el navegador muestra el primer fotograma del video — o un área negra hasta que empiece la carga.
<video src="intro.mp4" controls poster="portada.jpg"></video>
Buena práctica: siempre incluir poster para dar contexto visual inmediato al usuario antes de que interactúe.
width / height
Dimensiones del reproductor en píxeles, sin unidad (igual que en <img>). Permiten al navegador reservar el espacio correcto en el layout antes de que el video cargue. El tamaño visual final se controla con CSS, pero declarar las dimensiones en HTML evita el salto de layout.
<video src="intro.mp4" controls width="640" height="360"></video>
autoplay
Atributo booleano. Hace que el video intente reproducirse automáticamente al cargar la página.
Gotcha crítico: autoplay solo funciona con muted. Los navegadores modernos bloquean el autoplay con sonido por política de usuario (evitar audio inesperado). La única excepción aceptada es la combinación autoplay muted: el video arranca silenciado y el usuario puede activar el sonido después.
<!-- ✅ funciona en todos los navegadores modernos -->
<video src="intro.mp4" autoplay muted loop></video>
<!-- ❌ bloqueado en la mayoría de los navegadores -->
<video src="intro.mp4" autoplay controls></video>
Usá autoplay muted solo para videos de fondo o decorativos. Para contenido editorial, dejá que el usuario elija reproducir.
muted
Atributo booleano. El video se reproduce sin sonido. Necesario para que autoplay funcione. También útil como estado inicial en reproductores donde el usuario puede activar el sonido después.
loop
Atributo booleano. Al terminar el video, lo reinicia automáticamente. Útil para videos de fondo cortos o demos de UI. Evitalo en contenido con narración o historia.
preload
Indica al navegador cuánto contenido precargar antes de que el usuario interactúe.
none— no precargar nada; esperar hasta que el usuario haga play. Ideal para páginas con muchos videos o cuando el ancho de banda es limitado.metadata(valor por defecto en la mayoría de los navegadores) — solo descargar los metadatos (duración, dimensiones, primeras miniaturas). Buen balance entre usabilidad y rendimiento.auto— descargar el video completo en cuanto sea posible. Consume datos aunque el usuario nunca lo reproduzca.
<video src="intro.mp4" controls preload="metadata"></video>
Es una pista al navegador, no una orden. Puede ignorarlo según el contexto (modo ahorro de datos, red lenta, etc.).
Hijos <source> — múltiples formatos
<source> es un void element que especifica una fuente alternativa del video. El navegador evalúa cada <source> en orden y usa el primero que puede reproducir.
<video controls poster="portada.jpg" width="640" height="360">
<source src="intro.webm" type="video/webm">
<source src="intro.mp4" type="video/mp4">
</video>
Atributos de <source>:
src— ruta o URL del archivo de video.type— MIME type del formato:video/webm,video/mp4,video/ogg. Permite al navegador descartar formatos no soportados sin intentar cargarlos (ahorra una petición de red).
Orden de preferencia: poné primero el formato más moderno y eficiente (WebM con VP9/AV1), luego el de mayor compatibilidad (MP4/H.264). Los navegadores modernos soportan WebM y MP4; los más viejos a veces solo MP4.
Hijos <track> — subtítulos y accesibilidad
<track> provee subtítulos, transcripciones, descripciones de audio u otros metadatos sincronizados con el video. Usa el formato WebVTT (.vtt).
<video controls src="intro.mp4">
<track kind="subtitles" src="subtitulos-es.vtt" srclang="es" label="Español" default>
<track kind="subtitles" src="subtitulos-en.vtt" srclang="en" label="Inglés">
</video>
Atributos de <track>:
src— ruta al archivo.vtt.kind— tipo de track:subtitles(traducción del diálogo),captions(diálogo + efectos de sonido para usuarios sordos),descriptions(descripción de la acción visual para usuarios ciegos),chapters(puntos de navegación),metadata(datos para JavaScript).srclang— idioma del track (código BCP47:es,en,fr). Requerido cuandokind="subtitles".label— nombre legible que aparece en el menú de subtítulos del reproductor.default— booleano; activa este track por defecto (solo uno puede serlo).
Accesibilidad
- Siempre incluí
<track kind="captions">para contenido con diálogo. Los subtítulos benefician a usuarios sordos, a quien está en un entorno ruidoso, y a quien ve el video en un idioma que no es el suyo. - Nunca uses
autoplaycon sonido. Además de estar bloqueado por los navegadores, sorprende y puede desorientar a usuarios con tecnologías asistivas. - Si el video es el único medio para transmitir información importante, ofrecer una transcripción de texto es una buena práctica (aunque no reemplaza los
<track>). - El rol implícito de
<video>esapplicationcuando tienecontrols; los lectores de pantalla anuncian el reproductor y permiten interactuar con los controles.
Cuándo usar qué
| Necesidad | Solución |
|---|---|
| Video de contenido editorial con controles | <video controls> |
| Video de fondo decorativo (loop, sin sonido) | <video autoplay muted loop> (sin controls) |
| Imagen estática (no animada) | <img> |
| GIF animado | Reemplazarlo con <video autoplay muted loop> — más liviano |
| Múltiples formatos del mismo video | <source> hijos dentro del <video> |
| Video con subtítulos o descripciones | <track> hijos |
Notas, gotchas e interacción
autoplayrequieremutedo el usuario habrá interactuado antes con la página. Sinmuted, el autoplay falla silenciosamente en Chrome, Firefox y Safari modernos.srcen<video>y<source>hijos son mutuamente excluyentes. Si ponés ambos, los<source>se ignoran.preload="auto"puede ser caro en móvil. Si la página tiene varios videos, usápreload="none"opreload="metadata".- Sin
controlsy sin JavaScript, el video no se puede usar. El elemento es válido HTML, pero el usuario no puede interactuar con él. - Cicatriz de este sitio (A.0.5): los archivos de video no cargan en el sandbox/preview (no hay servidor de archivos). Los controles se muestran, pero no hay reproducción. Validá la estructura HTML con los checks; el efecto lo observás con un archivo real.
<video>dentro de<figure>es un patrón válido cuando el video va acompañado de un pie de figura.
Vigente / legacy
<video> es HTML5; no tiene equivalente en HTML4. Antes de HTML5 se usaba el plugin Adobe Flash (<object>/<embed>) para incrustar video — eso es completamente legacy: Flash dejó de recibir soporte en 2020 y ningún navegador moderno lo soporta. Hoy <video> es la única forma estándar de incrustar video.
El atributo autoplay sin muted era aceptado por navegadores hasta alrededor de 2017; hoy está bloqueado por política de usuario.
Aprendelo en el recorrido
Esta entrada complementa la lección <audio> y <video>: medios incrustados del módulo Imágenes y medios, donde se practica <video> con controls, poster y <source> hijos.