Shadow DOM es una función del navegador que permite a los sitios web definir elementos HTML autocontenidos . Estos elementos, denominados árboles de sombra, permiten a los desarrolladores web agrupar código HTML y estilos CSS relacionados de forma que el código y el estilo no afecten a otros elementos circundantes. Esto resuelve un problema recurrente al que se enfrentan los desarrolladores web: la interferencia no deseada entre componentes, donde las reglas CSS escritas para una parte de la página pueden afectar accidentalmente a otras partes del sitio web.
La función Shadow DOM se originó como parte de la iniciativa Web Components de Google, junto con otras propuestas como Custom Elements y el elemento de plantilla HTML en 2013. Tras las críticas de Apple y Mozilla a la primera versión de la propuesta Shadow DOM, denominada diseño "v0", se publicó una nueva propuesta llamada diseño "v1", que posteriormente fue adoptada por todos los principales navegadores web.
Historia
Shadow DOM tiene sus orígenes en discusiones entre 2010 y 2011 entre ingenieros de Google y otros colaboradores en las listas de correo públicas del W3C , donde se exploraron por primera vez ideas para la encapsulación del DOM. [ 1 ] Una especificación inicial "v0", publicada como un borrador de trabajo del W3C en 2013, introdujo características que incluían múltiples árboles de sombra por elemento anfitrión y un <content>elemento para la proyección de contenido. [ 2 ] Google lanzó v0 en Chrome junto con Custom Elements v0 e HTML Imports , pero otros proveedores de navegadores no lo hicieron. [ 3 ]
El equipo WebKit de Apple planteó preocupaciones sobre la complejidad de v0 y propuso una API más simple basada en ranuras. [ 3 ] [ 1 ] El equipo Firefox de Mozilla se alineó con el equipo WebKit al oponerse a muchos detalles de implementación de la API v0. [ 3 ] [ 4 ] Los desacuerdos entre los proveedores de navegadores sobre la forma y la implementación de la API llevaron a una reunión "cara a cara" del Grupo de Trabajo de Aplicaciones Web del W3C en Mountain View en abril de 2015. [ 4 ] [ 3 ] [ 1 ] La discusión posterior a la reunión resultó en que los proveedores de navegadores acordaran un diseño "v1" que eliminó múltiples shadow roots por host, reemplazó <content>con <slot>, y cambió hacia una API más declarativa. [ 1 ] En 2018, el W3C publicó una Nota del Grupo de Trabajo que indicaba que la nueva versión de la API Shadow DOM se incorporaría a varias especificaciones web en lugar de publicarse a través de Borradores de Trabajo. [ 5 ] El estándar DOM de WHATWG ahora define árboles de sombra, raíces de sombra y despacho de eventos a través de límites de sombra como parte del estándar vivo. [ 6 ]
Chrome lanzó Shadow DOM v1 en la versión 53 (2016), [ 7 ] Safari lo hizo más tarde ese mismo año, [ 8 ] y Firefox agregó soporte en 2018. [ 9 ] Microsoft Edge obtuvo soporte en la versión 79, en la que hizo la transición al motor Chromium . [ 10 ] [ 11 ] Chrome dejó de dar soporte y eliminó Shadow DOM v0, Custom Elements v0 e HTML Imports en 2019. [ 12 ] Una nueva adición a las especificaciones, Shadow DOM declarativo, se ha lanzado en navegadores basados en Chromium y Safari a partir de 2024.. [ 13 ] [ 14 ]
Descripción general
Shadow DOM es una de las tres tecnologías principales del conjunto de Web Components , junto con Custom Elements y el elemento de plantilla HTML . [ 15 ] [ 16 ] Juntos permiten la creación de componentes reutilizables y encapsulados que combinan marcado , estilo y comportamiento de forma nativa en la web. Los árboles Shadow permiten que dichos componentes rendericen la estructura interna sin exponerla como parte del DOM principal de la página. [ 6 ] [ 17 ] Los navegadores han utilizado internamente mecanismos similares a Shadow durante mucho tiempo para implementar elementos integrados complejos . Elementos como y renderizan sus controles a través de árboles Shadow internos mientras presentan una interfaz simple en el DOM claro. Shadow DOM extiende la misma capacidad a los elementos definidos por el desarrollador. [ 18 ]<video>...</video><details>...</details>
El Shadow DOM consta de múltiples árboles de sombra que son árboles DOM HTML cuya raíz se llama raíz de sombra , adjunta a un elemento llamado elemento anfitrión en el árbol DOM normal de la página de un sitio web. La raíz de sombra en sí no forma parte del DOM del documento regular , existe como un árbol separado accesible solo a través de la shadowRootpropiedad del elemento anfitrión (en modo abierto) o no accesible en absoluto (en modo cerrado). [ 19 ] Los borradores v0 anteriores permitían múltiples árboles de sombra por anfitrión, pero v1 eliminó esto en favor de una composición basada en ranuras más simple que solo permite un árbol de sombra por anfitrión. [ 20 ] Los elementos fuera del Shadow DOM se llaman Light DOM. [ 21 ]
Una raíz de sombra se crea llamando attachShadow()a un elemento, pasando un objeto de opciones con una modepropiedad. Una llamada de la forma element.attachShadow({mode: 'open'})devuelve una referencia a la nueva raíz de sombra, después de la cual se pueden agregar nodos hijos, atributos y estilos utilizando las API DOM estándar . [ 22 ] [ 23 ] En la práctica, los autores suelen llamar attachShadow()dentro de un constructor de elemento personalizado o rellenar el árbol de sombra clonando el contenido de un elemento. [ 24 ] [ 25 ] El contenido del elemento es inerte hasta que se instancia. El elemento de plantilla expone una propiedad que se puede insertar directamente en el árbol de sombra. [ 25 ]<template>...</template><template>contentDocumentFragment
Características
Encapsulación
Los estilos definidos dentro de un árbol de sombra tienen alcance en ese árbol y no se propagan hacia afuera; los selectores del documento externo no coinciden con elementos dentro del árbol de sombra. [ 26 ] Dos puntos de integración CSS permiten un estilo controlado a través del límite: la :hostpseudoclase estiliza el elemento anfitrión desde dentro de su propio árbol de sombra, [ 26 ] mientras que el ::slotted()pseudoelemento apunta a elementos DOM dentro de ranuras. [ 27 ] La modeopción pasada attachShadow()determina si la raíz de sombra está abierta o cerrada. En modo abierto, la propiedad del anfitrión shadowRootdevuelve la raíz de sombra, lo que permite que los scripts externos recorran el árbol. [ 28 ] [ 19 ] En modo cerrado shadowRoot, devuelve null[ 19 ] [ 29 ] desalentando el recorrido. [ 22 ]
Proyección de contenido
Shadow DOM define elementos que sirven como marcador de posición dentro de un árbol de sombra en el que se colocan los hijos del DOM claro del host. Esto se llama proyección de contenido. [ 26 ] En la especificación v1, esto se hace típicamente a través de elementos. Las ranuras pueden no tener nombre (la ranura predeterminada) o tener nombre a través de un atributo; los hijos del DOM claro apuntan a una ranura específica estableciendo un atributo coincidente. [ 28 ] Los hijos no asignados pasan a la ranura predeterminada. Este mecanismo reemplazó el elemento de v0, que usaba selectores CSS para determinar qué nodos del DOM claro aparecían en un punto de inserción dado. [ 26 ] El cambio a fue parte del rediseño de v1 acordado entre los proveedores de navegadores para simplificar la especificación y admitir mejor la subclase de componentes. [ 1 ]<slot>...</slot>nameslot<content>...</content><slot>...</slot>
Shadow DOM declarativo
El Shadow DOM declarativo permite definir raíces de sombra directamente en el marcado HTML sin JavaScript . Un elemento con un atributo colocado dentro de un elemento anfitrión hace que el navegador adjunte una raíz de sombra durante el análisis HTML , moviendo los hijos de la plantilla al árbol de sombra y eliminando la plantilla del DOM. [ 14 ] Esta característica está dirigida principalmente a la representación del lado del servidor de componentes web y entornos donde JavaScript puede no estar disponible o restringido. Al construir árboles de sombra durante el análisis en lugar de en tiempo de ejecución, puede reducir el cambio de diseño y mejorar métricas como Largest Contentful Paint . [ 13 ] [ 30 ]<template>...</template>shadowrootmode
Casos de uso
Los navegadores han utilizado durante mucho tiempo árboles de sombra internos para implementar elementos de interfaz de usuario integrados, como controles de formulario y reproductores multimedia , ocultando los detalles de implementación del DOM de la página. El Shadow DOM estandarizado extiende esta capacidad a componentes definidos por el autor, lo que permite elementos personalizados que exponen una API simple mientras mantienen el marcado y los estilos internos encapsulados. [ 18 ] Los desarrolladores pueden usar Shadow DOM al crear sistemas de diseño , widgets de interfaz de usuario reutilizables y componentes integrables que deben coexistir con páginas host arbitrarias sin colisiones de CSS . [ 26 ] El Shadow DOM declarativo extiende estos patrones a entornos renderizados en el servidor , lo que permite que los componentes lleguen completamente estructurados desde el servidor sin depender de JavaScript del lado del cliente. [ 30 ]
El alcance de estilo de Shadow DOM permite a los autores reutilizar nombres de clase comunes dentro de diferentes componentes sin riesgo de conflictos con hojas de estilo globales , y reduce la dependencia de selectores anidados profundamente . [ 31 ] Los componentes pueden gestionar su propio DOM y CSS de forma independiente, lo que puede mejorar la mantenibilidad al disminuir las colisiones de nombres y el comportamiento en cascada inesperado en aplicaciones grandes compuestas por muchos widgets. [ 31 ] [ 32 ] Esto ha llevado a que los frameworks de JavaScript adopten Shadow DOM como límite de componente. Frameworks como Polymer y su sucesor Lit están construidos directamente sobre Shadow DOM y sus polyfills , utilizan los términos DOM local para el árbol de sombra de un componente y DOM ligero para describir los elementos gestionados por el framework. [ 33 ] [ 34 ] Otros frameworks como Angular , Vue y Svelte admiten el uso de la API de Shadow DOM para encapsular estilos dentro de sus componentes. [ 35 ] [ 36 ] [ 37 ]
Limitaciones
Shadow DOM v0 recibió críticas por su complejidad y por aspectos de su modelo de encapsulación que dificultaban la creación de subclases , lo que contribuyó a su limitada adopción fuera de Chrome y motivó el rediseño de la versión 1. [ 1 ] [ 3 ] [ 4 ]
La API v1 introduce una complejidad adicional para las herramientas y la depuración , particularmente en aplicaciones que combinan Web Components con marcos existentes o que dependen de CSS global. La encapsulación puede dificultar la inspección de la semántica y la prueba del árbol de accesibilidad compuesto , lo que requiere una atención deliberada a los roles WAI-ARIA y la navegación del teclado a través de los límites de sombra. [ 21 ] La participación en el formulario tampoco es automática: las entradas dentro de un árbol de sombra no envían sus valores con un formulario DOM ligero contenedor de forma predeterminada, y los estados de validación del formulario no se propagan a través del límite de sombra. [ 25 ] [ 18 ]
Shadow DOM es una herramienta para la composición y encapsulación del DOM, no un límite de seguridad . La shadowRootpropiedad del elemento anfitrión en modo abierto, junto con varias otras API del DOM, puede exponer el contenido del árbol de sombra a los scripts de la página. [ 38 ] [ 39 ]
Referencias
- 1 2 3 4 5 6 Miksovsky, Jan (2019-04-08). "Una historia del elemento ranura HTML - Component Kitchen" . component.kitchen . Recuperado el 2026-07-08 .
- ↑ "Shadow DOM" . www.w3.org . Consultado el 8 de julio de 2026 .
- 1 2 3 4 5 "El estado de los componentes web – Mozilla Hacks - el blog para desarrolladores web" . Mozilla Hacks – el blog para desarrolladores web . Consultado el 8 de julio de 2026 .
- 1 2 3 "Webapps/WebComponentsApril2015Meeting - W3C Wiki" . www.w3.org . Consultado el 08-07-2026 .
- ↑ "Shadow DOM se está incorporando al repositorio principal" . www.w3.org . Consultado el 8 de julio de 2026 .
- 1 2 "Árboles de sombra" . WHATWG DOM Nivel de vida . WHATWG . Consultado el 23 de junio de 2026 .
- ↑ "Chrome 53 Beta: Shadow DOM" . Blog de Chromium . Google . Consultado el 23 de junio de 2026 .
- ↑ "Shadow DOM v1 - Componentes web autónomos | Artículos" . web.dev . Consultado el 8 de julio de 2026 .
- ↑ "Notas de la versión beta de Firefox 63.0" . Firefox . Consultado el 8 de julio de 2026 .
- ↑ "ShadowRoot - API web | MDN" . developer.mozilla.org . Consultado el 8 de julio de 2026 .
- ↑ "Microsoft Edge 79 utilizará el motor de navegador Chromium" . InfoQ . Consultado el 8 de julio de 2026 .
- ↑ "Intención de descontinuar y eliminar: Shadow DOM v0" . blink-dev . Google . Consultado el 23 de junio de 2026 .
- 1 2 "Declarative Shadow DOM" . WebKit . Consultado el 23 de junio de 2026 .
- 1 2 "Declarative Shadow DOM" . web.dev . Google . Consultado el 23 de junio de 2026 .
- ↑ "Componentes web - API web | MDN" . Documentación web de MDN . 22/02/2026 . Consultado el 08/07/2026 .
- ↑ "Introducción a los componentes web" . CSS-Tricks . 18 de marzo de 2019. Consultado el 8 de julio de 2026 .
- ↑ "Componentes web vs. Componentes de framework: ¿Cuál es la diferencia?" . Smashing Magazine . 17 de marzo de 2025 . Consultado el 23 de junio de 2026 .
- 1 2 3 Beswick, Russell (28-07-2025). "Componentes web: trabajando con Shadow DOM" . Smashing Magazine . Recuperado el 23-06-2026 .
- 1 2 3 Frisbie, Matt (2 de octubre de 2019). JavaScript profesional para desarrolladores web . John Wiley & Sons. págs. 797–801 . ISBN 978-1-119-36657-7.
- ^ Guo, Xiaojie; Huang, Yanyu; Sí, Jinhui; Yin, Sijie; Li, Min; Li, Zhaohui; Yiu, Siu-Ming; Cheng, Xiaochun (1 de agosto de 2021). "ShadowFPE: nueva solución de aplicación web cifrada basada en Shadow DOM" . Redes Móviles y Aplicaciones . 26 (4): 1733–1746 . doi : 10.1007/s11036-019-01509-y . ISSN 1572-8153 .
- 1 2 Matuzovic, Manuel (14 de junio de 2024). Web Accessibility Cookbook . "O'Reilly Media, Inc." pp. 301–306 . ISBN 978-1-0981-4557-6.
- 1 2 "Uso de shadow DOM" . MDN Web Docs . Mozilla . Consultado el 23 de junio de 2026 .
- ↑ Williams, Caleb (22 de marzo de 2019). "Encapsulando estilo y estructura con Shadow DOM" . CSS-Tricks . Recuperado el 23 de junio de 2026 .
- ↑ Powers, Shelley (26 de enero de 2015). JavaScript Cookbook: Programming the Web . «O'Reilly Media, Inc.». págs. 440–444 . ISBN 978-1-4919-0246-2.
- 1 2 3 "Componentes web desmitificados" . CSS-Tricks . Consultado el 23 de junio de 2026 .
- 1 2 3 4 5 Overson, Jarrod; Strimpel, Jason (17 de febrero de 2015). Desarrollo de componentes web: interfaz de usuario de jQuery a Polymer . «O'Reilly Media, Inc.». págs. 107–123 . ISBN 978-1-4919-0569-2.
- ↑ "::slotted() pseudo-elemento CSS - CSS | MDN" . MDN Web Docs . 17 de abril de 2026. Consultado el 8 de julio de 2026 .
- 1 2 Flanagan, David (14 de mayo de 2020). JavaScript: La guía definitiva: Domina el lenguaje de programación más utilizado del mundo . «O'Reilly Media, Inc.». pág. 478. ISBN 978-1-4919-5200-9.
- ↑ "Elemento: método attachShadow() - API web | MDN" . Documentación web de MDN . 17 de mayo de 2026. Consultado el 8 de julio de 2026 .
- 1 2 "Declarative Shadow DOM" . DebugBear . Consultado el 23/06/2026 .
- 1 2 "Estilo en el Shadow DOM con CSS Shadow Parts" . CSS-Tricks . 28-10-2020 . Recuperado el 23-06-2026 .
- ↑ Lambert, Steven (15 de diciembre de 2016). "Estilo de componentes web mediante una hoja de estilo compartida" . Smashing Magazine . Consultado el 23 de junio de 2026 .
- ↑ Savage, Taylor (noviembre de 2015). "Componentizando la web: podríamos estar en la cúspide de una nueva revolución en el desarrollo web" . Queue . 13 (8): 60–79 . doi : 10.1145/2838344.2844732 . ISSN 1542-7730 .
- ↑ "Trabajando con Shadow DOM – Lit" . lit.dev . Consultado el 3 de julio de 2026 .
- ↑ Equipo, Angular. "ViewEncapsulation • Angular" . angular.dev . Consultado el 08-07-2026 .
- ↑ "Vue y componentes web" . vuejs.org . Consultado el 8 de julio de 2026 .
- ↑ "Elementos personalizados • Documentación de Svelte" . svelte.dev . Consultado el 8 de julio de 2026 .
- ↑ "ShadowBreakers" . GitHub . Consultado el 23 de junio de 2026 .
- ↑ "Autoevaluación declarativa de seguridad y privacidad de Shadow DOM" . GitHub . Consultado el 23 de junio de 2026 .
- Estándares web
- Programación web