Ahora que sabemos ¿Qué es el Shadow DOM? y que se utiliza para encapsular elementos en nuestro documento HTML, se nos podría plantear la siguiente duda: ¿Necesito Javascript para crear un Shadow DOM?
Generalmente, la respuesta a esta pregunta es sí, ya que hasta ahora era necesario realizar los pasos anteriores para crear un Shadow DOM en un elemento HTML. Por esta razón, el trabajo con Shadow DOM se reducía a aplicaciones web o documentos que trabajan en el cliente, es decir, en el navegador del usuario.
<app-element></app-element>
const element = document.querySelector("app-element");
element.attachShadow({ mode: "open" });
Sin embargo, con el Shadow DOM declarativo, podría ser posible hacerlo también desde el servidor, ya que permite crear Shadow DOM utilizando únicamente HTML.
Shadow DOM desde HTML
Mediante la propuesta de crear un Shadow DOM de forma declarativa, es decir, desde el HTML (sin necesidad de Javascript) se ha abierto un mundo de posibilidades muy interesantes, ya que aparte de simplificar su creación, permite incluso su generación desde la parte del servidor.
En esta modalidad, utilizaríamos la etiqueta HTML <template>
con el atributo shadowrootmode
indicando la modalidad del Shadow DOM, ya sea open
o close
, al igual que su análogo en Javascript:
<app-element>
<template shadowrootmode="open">
<style>
h2 { color: red }
::slotted(h2) { color: purple }
</style>
<h2>Shadow DOM</h2>
<slot></slot>
</template>
<h2>Light DOM</h2>
</app-element>
<h2>Global DOM</h2>
Observa que en este fragmento de código estamos utilizando la etiqueta <template>
, sin embargo, está utilizando un atributo shadowroot
para indicar el modo del Shadow DOM, que es lo que lo diferencia de otras etiquetas template normales.
En el caso de navegadores que soporten los Shadow DOM declarativos, esta etiqueta <template>
se renderizará como un Shadow DOM resultando algo parecido a lo siguiente:
Shadow DOM
en rojo, ya que se aplica el estilo delh2
desde dentro del Shadow DOMLight DOM
en lila, ya que se aplica el estilo del::slotted()
desde dentro del Shadow DOMGlobal DOM
en negro, ya que no se aplica ninguno de los anteriores, debido al Shadow DOM
En el caso de no soportarlo, sólo se vería el texto Light DOM
y Global DOM
, ambos en color negro.
Soporte en navegadores
Si quieres ofrecer soporte a algún navegador que aún no soporte Declarative Shadow Root, puedes utilizar este pequeño fragmento de código Javascript, ejecutándolo al cargar una página. Esto buscará todas las etiquetas <template>
con el atributo shadowrootmode
y las eliminará creando una nueva con el Shadow DOM creado y adjuntado:
const dsr = document.querySelectorAll("template[shadowrootmode]");
dsr.forEach(template => {
const mode = template.getAttribute("shadowrootmode");
const shadowRoot = template.parentNode.attachShadow({ mode });
shadowRoot.appendChild(template.content);
template.remove();
});