Ingénieur IT, photographe amateur, musicien du dimanche
L’API Shadow DOM du HTML5
L’API Shadow DOM du HTML5

L’API Shadow DOM du HTML5

TL;DR;

Le Shadow DOM est un DOM encapsulé dans un élément et qui est isolé du reste de la page. On peut néanmoins y accéder via un objet javascript ou des sélecteurs CSS spécifiques.

Depuis cet article, la spec à changé et ne colle plus à la description ci-dessous. Référez-vous plutôt à la spec V1 décrite ici :  https://developers.google.com/web/fundamentals/web-components/ 

Introduction

Le Shadow DOM correspond au « DOM caché » qui est encapsulé dans un composant. Ce DOM est isolé du reste de la page au niveau CSS et JavaScript, c’est à dire que les styles de la page courante ne lui seront pas appliqués, et que la fonction querySelector  n’y accèdera pas non plus.

Les nouveaux éléments complexes du HTML5 implémentent déjà cette notion, comme par exemple avec la balise <video>  dont les contrôles sont invisible par défaut. La différence est qu’il n’est pas possible d’accéder à leur contenu isolé via JS.

Inspecter le Shadow DOM

Par défaut, le shadow DOM n’est pas visible dans les Chrome Dev Tools. Si on inspecte le DOM d’un élément vidéo (voir image 1), on ne verra rien d’autre que l’élément root du composant, c’est à dire la balise <video> , ainsi que ses enfants directs qui représente la source du fichier média, les balises <source> .

Shadow Dom invisible
Shadow Dom non visible dans les Chrome Dev Tools

Il faudra volontairement activer la fonctionnalité pour voir tout le détail du DOM. Pour cela, ouvrez les paramètres des Chrome Dev Tools et rendez vous dans la section « préférence des éléments » afin d’activer la visualisation complète à l’aide d’une checkbox nommée en anglais : ‘Show user agent shadow DOM’.

Si à présent nous reprenons le même exemple et inspectons la balise vidéo, nous remarquons qu’un élément nommé shadow-root  est disponible (voir image suivante). Cet élément correspond à la racine de notre arbre caché et donc aux boutons du lecteur vidéo. Il est très important car c’est lui qui nous permettra d’accéder aux éléments isolés à partir d’un script de la page.

Shadow DOM visible
Inspection du shadow DOM dans les Chrome Dev Tools

Manipulation via JavaScript

La création de cet arbre caché peut se faire via quelques lignes de JavaScript. Mais il faudra dans tout les cas commencer par créer l’élément racine, la shadow-root.

Pour cette manipulation, il y’a actuellement 2 manières de le faire. La première correspond à la méthode qui a été implémentée dans la version 0 de la spec, et qui devrait donc être dépréciée sous peu.

La seconde correspond à la méthode définie dans la version 1 de la spec, et qui est celle choisie pour implémentation dans la plupart des browsers. Ce sera donc la seule valide une fois que cette api sera définitivement implémentée. Le paramètre mode doit valoir open pour que l’accès soit possible via JS. Si la valeur vaut closed, le DOM isolé sera, comme pour le cas d’une balise vidéo, inaccessible via JS.

// implémentation en version 0
var shadowroot = element.createShadowRoot();
// implémentation en version 1
let shadowRoot = element.attachShadow({mode: 'open'});

Dès que ce shadow-root est créé, la manipulation des éléments imbriqués se fait de la même manière que pour des éléments standards de la page. Il est donc possible d’utiliser des méthodes standards comme innerHTML , querySelector , etc…

Manipulation via CSS

L’isolation de l’arbre est valable aussi pour les styles. Une class .title  présente dans le DOM isolé ne subira pas le style .title  défini dans la page hôte, ceci afin que le composant ne subisse pas les perturbations extérieurs.

Mais si cela est nécessaire, la page hôte aura tout de même la possibilité de modifier le style du composant à l’aide de sélecteurs spécifiques :

  • :host(<selector>)  qui permet de styliser le host d’un élément ciblé par son sélecteur (optionnel)
  • :host-context(<selector>)  : pour styliser un élément en se basant sur ses éléments englobants.
  • Le pseudo élément ::shadow  qui permet de cibler l’élément shadow-root
  • Le mot clé /deep/  qui, utilisé avec d’autres sélecteur, permet de passer au travers de n’importe quel nombre d’imbrication de shadow DOM.

Tous ces sélecteurs peuvent être utilisé dans le CSS, mais également en JS à l’aide de la méthode querySelector .

Voici quelques exemples d’utilisation tiré de HTML5rocks.com :

:host {
  opacity: 0.4;
  transition: opacity 420ms ease-in-out;
}
:host(:hover) {
  opacity: 1;
}
:host-context(.different) {
  color: red;
}
#host::shadow span {
  color: red;
}
body /deep/ .library-theme {
  border: 1px solid red;
}

Support des navigateurs

Voici le support actuel de cette api: http://caniuse.com/#feat=shadowdom

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *