Les shadow DOM sont conçus pour encapsuler les éléments et les styles d’un composant web, les rendant inaccessibles depuis l’extérieur pour plusieurs raisons importantes :
- Encapsulation et Isolation
- Réutilisabilité des Composants
- Sécurité
- Simplicité de Développement
- Performance

Mon objectif était de pouvoir modifier les styles d’une extension WordPress (un chatbot) nommée 3CX Free Live Chat, Calls & WhatsApp). Cette extension injecte un shadow DOM directement dans mon front. Il me fallait pouvoir injecter du styles supplémentaire afin de pouvoir en modifier l’apparence de l’extension.
Les premiers tests directement dans la console :
const shadowRoot = document.querySelector('call-us-selector').shadowRoot; // Injecter des styles const style = document.createElement('style'); style.textContent = ` * { color: red; } `; shadowRoot.appendChild(style);
Ça fonctionne.
Reste à l’intégrer dans WordPress via un nouveau fichier JavaScript. Cela se passe dans le dossier du thème enfant dans le fichier functions.php
:
function regJavaScript() { // Enregistre et ajoute le script wp_enqueue_script('regApp', get_stylesheet_directory_uri() . '/app.js', array(), '1.0.0', true); } add_action('wp_enqueue_scripts', 'regJavaScript');
On créer le fichier app.js
dans le thème enfant. J’ai du ajouté une condition supplémentaire pour attendre que le DOM soit chargé…et également un timer pour attendre et vérifier que 3CX avait bien fini d’injecté son code.
// Ajoute les styles function regModifie3CX() { const shadowRoot = document.querySelector('call-us-selector').shadowRoot.querySelector('call-us').shadowRoot; // Injecter des styles const style = document.createElement('style'); style.textContent = ` #wplc-chat-button { background-color: #f53603; } #wplc-chat-button svg rect { fill: #ffffff; } svg { fill: #f53603 !important; } `; shadowRoot.appendChild(style); } document.addEventListener('DOMContentLoaded', function() { const checkExist = setInterval(function() { const injectedElement = document.querySelector('call-us-selector'); // Remplacez par le sélecteur approprié if (injectedElement) { console.log('HTML injecté, exécution du script...'); regModifie3CX(); clearInterval(checkExist); // Arrête l'intervalle après l'exécution } }, 300); // Vérifie toutes les 300 ms });
