logo oujood
🔍

Custom Elements : définir ses propres balises HTML en JavaScript

Avec l'API Custom Elements, vous créez de nouvelles balises HTML — comme <carte-profil> ou <bouton-like> — directement dans le navigateur, sans React ni Vue. Ce tutoriel couvre la création, le cycle de vie et la manipulation de vos éléments personnalisés, du plus simple au plus complet.

OUJOOD.COM

Qu'est-ce qu'un Custom Element ?

JavaScript API – mise à jour 2026

Un Custom Element, c'est une balise HTML que vous inventez vous-même. Au lieu d'être limité à <div>, <button> ou <input>, vous pouvez écrire <carte-produit>, <menu-navigation> ou <bouton-like> — et le navigateur sait quoi en faire parce que vous lui avez expliqué.

Avant cette API, la seule façon de créer un composant réutilisable était de passer par React, Vue ou Angular. Depuis Chrome 54 et Firefox 63, le navigateur gère ça nativement. Pas de npm, pas de build, pas de dépendance : juste du JavaScript standard.

Il existe deux variantes de Custom Elements. Les autonomous custom elements sont des éléments entièrement nouveaux — ils étendent HTMLElement directement et n'ont aucun comportement HTML préexistant. Les customized built-in elements étendent une balise existante comme <button> ou <input> pour en hériter les fonctionnalités natives (accessibilité, focus, événements).

Ce tutoriel porte sur les autonomous custom elements : ils couvrent 95% des cas d'usage et sont supportés uniformément sur tous les navigateurs modernes.


Compatibilité navigateurs

Chrome 54+, Firefox 63+, Safari 10.1+ et Edge 79+ supportent tous Custom Elements. Internet Explorer est hors jeu. En pratique en 2026, vous pouvez utiliser cette API sans polyfill sur la quasi-totalité des navigateurs en circulation. Une vérification reste utile si votre audience peut inclure des environnements embarqués ou des navigateurs anciens :

  📋 Copier le code

if ('customElements' in window) {
  // L'API Custom Elements est disponible
  console.log('Custom Elements supporté.');
} else {
  // Prévoir un polyfill ou une alternative
  console.log('Custom Elements non supporté.');
}
  

Créer un Custom Element minimal

Deux étapes suffisent : écrire une classe JavaScript qui étend HTMLElement, puis appeler customElements.define() pour associer cette classe à un nom de balise.

Le nom doit contenir au moins un tiret — c'est obligatoire. Cette règle permet au navigateur de distinguer vos balises des éléments HTML standards sans ambiguïté. <mon-element> est valide, <monelement> déclenche une erreur.

  📋 Copier le code

// 1. Définir la classe du composant
class MonElement extends HTMLElement {
  constructor() {
    super(); // Toujours appeler super() en premier
    this.textContent = 'Bonjour depuis mon Custom Element !';
  }
}

// 2. Enregistrer la balise personnalisée
customElements.define('mon-element', MonElement);
  

Une fois enregistré, vous pouvez utiliser <mon-element> directement dans votre HTML :

  📋 Copier le code

<!-- Dans votre HTML -->
<mon-element></mon-element>

<!-- Résultat affiché : Bonjour depuis mon Custom Element ! -->
  

Le cycle de vie d'un Custom Element

Le navigateur appelle automatiquement certaines méthodes de votre classe à des moments précis : quand l'élément est inséré dans la page, quand il en est retiré, quand un attribut change. Ces méthodes s'appellent les callbacks de cycle de vie. Elles n'ont pas à être déclenchées manuellement — il suffit de les définir dans la classe.

connectedCallback

Le navigateur appelle connectedCallback chaque fois que l'élément est inséré dans le DOM. C'est là qu'on initialise le rendu, qu'on attache des écouteurs d'événements ou qu'on lance une requête réseau.

  📋 Copier le code

class MonElement extends HTMLElement {
  connectedCallback() {
    // L'élément vient d'être ajouté à la page
    console.log('mon-element ajouté au DOM.');
    this.innerHTML = '<p>Composant prêt !</p>';
  }
}
  

disconnectedCallback

disconnectedCallback se déclenche quand l'élément est retiré du DOM. C'est le bon endroit pour supprimer les écouteurs d'événements et libérer les ressources — évite les fuites mémoire sur les applications longue durée.

  📋 Copier le code

class MonElement extends HTMLElement {
  disconnectedCallback() {
    // Nettoyage : supprimer les écouteurs d'événements
    console.log('mon-element retiré du DOM.');
  }
}
  

attributeChangedCallback

attributeChangedCallback se déclenche chaque fois qu'un attribut observé change de valeur — que ce soit via HTML ou via setAttribute() en JavaScript. Pour qu'un attribut soit surveillé, il faut le déclarer dans le tableau statique observedAttributes. Sans cette déclaration, le callback ne se déclenche jamais.

  📋 Copier le code

class MonElement extends HTMLElement {

  // Déclarer les attributs à surveiller
  static get observedAttributes() {
    return ['couleur', 'taille'];
  }

  attributeChangedCallback(nom, ancienneValeur, nouvelleValeur) {
    // Appelé quand 'couleur' ou 'taille' change
    console.log(`Attribut "${nom}" : ${ancienneValeur} → ${nouvelleValeur}`);
    this.style.color = this.getAttribute('couleur') || 'black';
  }
}
  

Exemple complet : une carte de profil

Voici un cas concret : un Custom Element <carte-profil> qui affiche un nom et un rôle passés en attributs. Quand vous changez un attribut depuis JavaScript, la carte se met à jour automatiquement grâce à attributeChangedCallback.

  📋 Copier le code

class CarteProfil extends HTMLElement {

  static get observedAttributes() {
    return ['nom', 'role'];
  }

  connectedCallback() {
    this.render();
  }

  attributeChangedCallback() {
    // Redessiner le composant quand un attribut change
    this.render();
  }

  render() {
    const nom  = this.getAttribute('nom')  || 'Inconnu';
    const role = this.getAttribute('role') || 'Visiteur';
    this.innerHTML = `
      <div style="border:1px solid #ccc; padding:1rem; border-radius:8px;">
        <strong>${nom}</strong>
        <p>${role}</p>
      </div>
    `;
  }
}

customElements.define('carte-profil', CarteProfil);
  

Utilisation dans le HTML :

  📋 Copier le code

<carte-profil nom="Oujood" role="Développeur Web"></carte-profil>
<carte-profil nom="Karim"  role="Designer UI"></carte-profil>
  

Accéder à un Custom Element depuis JavaScript

Un Custom Element se manipule exactement comme une balise HTML ordinaire : querySelector() le sélectionne, setAttribute() modifie ses attributs, addEventListener() écoute ses événements. Pas d'API spéciale à apprendre.

  📋 Copier le code

const carte = document.querySelector('carte-profil');

// Changer un attribut : déclenche attributeChangedCallback
carte.setAttribute('nom', 'Yassine');
carte.setAttribute('role', 'Administrateur');

// Créer un élément dynamiquement
const nouvelleCarte = document.createElement('carte-profil');
nouvelleCarte.setAttribute('nom', 'Sara');
nouvelleCarte.setAttribute('role', 'Chef de projet');
document.body.appendChild(nouvelleCarte);
  

Récapitulatif

Un Custom Element, c'est une classe JS qui étend HTMLElement, enregistrée avec customElements.define() sous un nom contenant un tiret. Les trois callbacks essentiels sont connectedCallback (insertion dans le DOM), disconnectedCallback (retrait du DOM) et attributeChangedCallback (changement d'attribut observé). C'est la première brique des Web Components — Shadow DOM et Templates viennent compléter le tableau pour produire des composants vraiment encapsulés.

Par carabde | Mis à jour le 17 avril 2026


chapitre précédent   sommaire   chapitre suivant