OUJOOD.COM
Les trois briques des Web Components
HTML5 API – mise à jour 2026Les Web Components regroupent trois technologies natives du navigateur. Chacune est utilisable seule, mais c'est leur combinaison qui produit un vrai composant autonome :
- Custom Elements : on définit une nouvelle balise HTML avec sa propre classe JavaScript.
- Shadow DOM : on lui attache un DOM privé — les styles restent à l'intérieur, la page n'y touche pas.
- Templates & Slots : on écrit la structure HTML une seule fois dans un
<template>, et les<slot>laissent entrer le contenu depuis l'extérieur.
Ce tutoriel construit un composant <carte-notification> complet en quatre étapes — template, classe JavaScript, utilisation HTML, instanciation dynamique. Aucun npm, aucun bundler, aucun framework.
Ce que nous allons construire
Le composant <carte-notification> affiche un message avec quatre niveaux de sévérité : info, succès, avertissement, erreur. Il expose trois slots nommés — icône, titre, message — que l'utilisateur du composant remplit librement. La couleur de la carte change selon l'attribut type, sans aucun JavaScript de rendu supplémentaire grâce au sélecteur CSS :host.
<carte-notification type="succes"> <span slot="icone">✅</span> <span slot="titre">Enregistrement réussi</span> <span slot="message">Vos données ont bien été sauvegardées.</span> </carte-notification> <carte-notification type="erreur"> <span slot="icone">❌</span> <span slot="titre">Connexion échouée</span> <span slot="message">Vérifiez votre identifiant et mot de passe.</span> </carte-notification>
Étape 1 — Définir le template HTML
On écrit la structure du composant dans un <template>. Il contient le CSS encapsulé via :host, trois slots nommés et la mise en page de la carte. Tant que le Custom Element ne le clone pas, ce template reste invisible et inactif dans la page.
<template id="tpl-notification">
<style>
:host { display: block; margin-bottom: 1rem; }
:host([type="info"]) { --couleur: #0066cc; --fond: #e8f0fe; }
:host([type="succes"]) { --couleur: #1a7f3c; --fond: #e6f4ea; }
:host([type="avertissement"]) { --couleur: #b45309; --fond: #fef9c3; }
:host([type="erreur"]) { --couleur: #c0392b; --fond: #fdecea; }
.carte {
display: flex;
align-items: flex-start;
gap: 0.8rem;
padding: 1rem 1.2rem;
border-radius: 8px;
border-left: 4px solid var(--couleur, #0066cc);
background: var(--fond, #e8f0fe);
font-family: sans-serif;
}
.icone { font-size: 1.4rem; line-height: 1; }
.corps { display: flex; flex-direction: column; gap: 0.2rem; }
.titre { font-weight: bold; color: var(--couleur, #0066cc); }
.message { color: #333; font-size: 0.95rem; }
</style>
<div class="carte">
<div class="icone"><slot name="icone">ℹ️</slot></div>
<div class="corps">
<div class="titre"><slot name="titre">Notification</slot></div>
<div class="message"><slot name="message">Aucun message.</slot></div>
</div>
</div>
</template>
Le sélecteur :host cible l'élément hôte depuis l'intérieur du Shadow DOM — ici <carte-notification> lui-même. :host([type="succes"]) applique des styles conditionnels selon la valeur de l'attribut type, sans toucher au JavaScript.
Étape 2 — Créer le Custom Element
La classe observe l'attribut type. Dans connectedCallback, elle attache un Shadow DOM, récupère le template et le clone dedans. Le sélecteur :host dans le CSS réagit seul aux changements de type — pas besoin de re-rendre le composant.
class CarteNotification extends HTMLElement {
static get observedAttributes() {
return ['type'];
}
connectedCallback() {
// Attacher le Shadow DOM
const shadow = this.attachShadow({ mode: 'open' });
// Cloner le template et l'injecter dans le shadow root
const template = document.getElementById('tpl-notification');
shadow.appendChild(template.content.cloneNode(true));
}
attributeChangedCallback(nom, ancienne, nouvelle) {
// Le sélecteur :host réagit automatiquement — pas besoin de re-render
console.log(`Attribut "${nom}" changé : ${ancienne} → ${nouvelle}`);
}
}
customElements.define('carte-notification', CarteNotification);
Étape 3 — Utiliser le composant dans la page
Le composant est enregistré. On l'utilise avec des contenus et des types différents — le Shadow DOM garantit que rien dans la feuille de style globale ne peut l'affecter :
<!-- Notification d'information --> <carte-notification type="info"> <span slot="icone">ℹ️</span> <span slot="titre">Mise à jour disponible</span> <span slot="message">Une nouvelle version est prête à être installée.</span> </carte-notification> <!-- Notification de succès --> <carte-notification type="succes"> <span slot="icone">✅</span> <span slot="titre">Profil mis à jour</span> <span slot="message">Vos modifications ont bien été enregistrées.</span> </carte-notification> <!-- Notification d'avertissement --> <carte-notification type="avertissement"> <span slot="icone">⚠️</span> <span slot="titre">Session expirée bientôt</span> <span slot="message">Vous serez déconnecté dans 5 minutes.</span> </carte-notification> <!-- Notification d'erreur --> <carte-notification type="erreur"> <span slot="icone">❌</span> <span slot="titre">Paiement refusé</span> <span slot="message">Vérifiez les informations de votre carte bancaire.</span> </carte-notification>
Étape 4 — Instancier le composant dynamiquement en JavaScript
document.createElement('carte-notification') crée le composant comme n'importe quelle balise HTML. On remplit les slots via innerHTML, on fixe l'attribut type avec setAttribute(), et on l'insère dans la page. Ici on ajoute aussi une suppression automatique après 5 secondes :
function afficherNotification(type, icone, titre, message) {
const carte = document.createElement('carte-notification');
carte.setAttribute('type', type);
// Créer et injecter les slots
carte.innerHTML = `
<span slot="icone">${icone}</span>
<span slot="titre">${titre}</span>
<span slot="message">${message}</span>
`;
document.getElementById('notifications').appendChild(carte);
// Supprimer automatiquement après 5 secondes
setTimeout(() => carte.remove(), 5000);
}
// Appel de la fonction
afficherNotification('succes', '✅', 'Fichier envoyé', 'Votre fichier a été uploadé avec succès.');
Récapitulatif : les trois technologies en un coup d'œil
Dans <carte-notification>, chaque technologie a un rôle précis. Custom Elements : la classe CarteNotification enregistre la balise et observe l'attribut type. Shadow DOM : attachShadow({ mode: 'open' }) isole les styles via :host. Template & Slots : le <template id="tpl-notification"> structure la mise en page, les trois <slot> nommés reçoivent icône, titre et message depuis l'extérieur.
Web Components vs frameworks JavaScript
Web Components ne remplace pas React ou Vue sur des applications complexes — mais dans certains contextes, c'est le bon outil :
- Zéro dépendance : aucun package npm, aucun bundler. Un fichier HTML et un fichier JS suffisent.
- Interopérabilité totale : un Web Component fonctionne dans React, Vue, Angular ou un simple fichier HTML sans modification.
- Pérennité : les standards du navigateur bougent lentement — un composant écrit aujourd'hui fonctionnera dans dix ans.
- Performance directe : pas de virtual DOM, pas de couche d'abstraction — le navigateur manipule le DOM réel.
Par carabde | Mis à jour le 17 avril 2026