Cette page a été traduite à partir de l'anglais par la communauté.Vous pouvez contribuer en rejoignant la communauté francophone sur MDN Web Docs.
<template> : l'élément de modèle de contenu
Baseline Widely available *
Cette fonctionnalité est bien établie et fonctionne sur de nombreux appareils et versions de navigateurs. Elle est disponible sur tous les navigateurs depuis novembre 2015.
* Certaines parties de cette fonctionnalité peuvent bénéficier de prise en charge variables.
L'élémentHTML<template> sert de mécanisme pour contenir des fragmentsHTML, qui peuvent être utilisés plus tard via JavaScript ou générés immédiatement dans le DOM d'ombre.
Dans cet article
Attributs
Cet élément inclutles attributs universels.
shadowrootmodeCrée uneracine d'ombre pour l'élément parent.Il s'agit d'une version déclarative de la méthode
Element.attachShadow()et accepte les mêmes valeursénumérées.openExpose le DOM interne de la racine d'ombre pour JavaScript (recommandé pour la plupart des cas d'usage).
closedMasque le DOM interne de la racine d'ombre pour JavaScript.
Note :L'analyseur HTML crée un objet
ShadowRootdans le DOM pour le premier<template>d'un nœud dont cet attribut est défini sur une valeur autorisée.Si l'attribut n'est pas défini, ou n'est pas défini sur une valeur autorisée — ou si uneShadowRoota déjà été créée de manière déclarative dans le même parent — alors unHTMLTemplateElementest construit.UnHTMLTemplateElementne peut pas être transformé en racine d'ombre après l'analyse, par exemple, en définissantHTMLTemplateElement.shadowRootMode.Note :Vous pouvez rencontrer l'attribut non standard
shadowrootdans d'anciens tutoriels et exemples qui étaient pris en charge dans Chrome 90-110. Cet attribut a depuis été supprimé et remplacé par l'attribut standardshadowrootmode.shadowrootclonableDéfinit la valeur de la propriété
clonabled'un objetShadowRootcréé avec cet élément àtrue.Si défini, un clone de l'hôte d'ombre (l'élément parent de ce<template>) créé avecNode.cloneNode()ouDocument.importNode()inclura une racine d'ombre dans la copie.shadowrootdelegatesfocusDéfinit la valeur de la propriété
ShadowRoot.delegatesFocusd'un objetShadowRootcréé avec cet élément àtrue.Si cela est défini et qu'un élément non sélectionnable dans l'arbre d'ombre est sélectionné, la sélection est déléguée au premier élément sélectionnable de l'arbre.La valeur par défaut estfalse.shadowrootreferencetargetExpérimentalDéfinit la valeur de la propriété
referenceTargetd'un objetShadowRootcréé avec cet élément. La valeur doit être l'identifiant d'un élément à l'intérieur du DOM d'ombre. Si défini, les références ciblant l'élément hôte depuis l'extérieur du DOM d'ombre feront que l'élément cible référencé deviendra la cible effective de la référence à l'élément hôte.shadowrootserializableDéfinit la valeur de la propriété
ShadowRoot.serializabled'un objetShadowRootcréé avec cet élément àtrue.Si défini, la racine d'ombre peut être sérialisée en appelant les méthodesElement.getHTML()ouShadowRoot.getHTML()avec le paramètreoptions.serializableShadowRootsdéfini àtrue.La valeur par défaut estfalse.
Notes d'utilisation
Cet élément n'a pas de contenu autorisé, car tout ce qui est imbriqué à l'intérieur dans le code source HTML ne devient pas réellement enfant de l'élément<template>. La propriétéNode.childNodes de l'élément<template> est toujours vide, et vous ne pouvez accéder à ce contenu imbriqué que via la propriété spécialecontent. Cependant, si vous appelezNode.appendChild() ou des méthodes similaires sur l'élément<template>, vous insérerez des enfants dans l'élément<template> lui-même, ce qui viole son modèle de contenu et ne met pas à jour leDocumentFragment retourné par la propriétécontent.
En raison de la façon dont l'élément<template> est analysé, toutes les balises<html>,<head> et<body> ouvrantes et fermantes à l'intérieur du template sont des erreurs de syntaxe et sont ignorées par l'analyseur, donc<template><head><title>Test</title></head></template> équivaut à<template><title>Test</title></template>.
Il existe deux principales façons d'utiliser l'élément<template>.
Fragment de document de template
Par défaut, le contenu de l'élément n'est pas affiché.L'interfaceHTMLTemplateElement correspondante inclut une propriété standardcontent (sans attribut de contenu/marquage équivalent). Cette propriétécontent est en lecture seule et contient unDocumentFragment qui inclut le sous-arbre DOM représenté par le template.
Les méthodesNode.cloneNode() etDocument.importNode() créent toutes deux une copie d'un nœud. La différence est queimportNode() clone le nœud dans le contexte du document appelant, tandis quecloneNode() utilise le document du nœud cloné. Le contexte du document détermine leCustomElementRegistry pour la construction de tout élément personnalisé. Pour cette raison, utilisezdocument.importNode() pour cloner le fragmentcontent afin que les descendants d'éléments personnalisés soient construits selon les définitions du document courant, plutôt que du document séparé qui possède le contenu du template. Voir les exemples de la pageNode.cloneNode() pour plus de détails.
Notez que le conteneurDocumentFragment lui-même ne doit pas contenir de données. Voir l'exempleLes données sur le DocumentFragment ne sont pas clonées pour plus de détails.
DOM d'ombre déclaratif
Si l'élément<template> contient l'attributshadowrootmode avec la valeuropen ouclosed, l'analyseur HTML génère immédiatement un DOM d'ombre. L'élément est remplacé dans le DOM par son contenu enveloppé dans unShadowRoot, qui est attaché à l'élément parent.C'est l'équivalent déclaratif de l'appel àElement.attachShadow() pour attacher une racine d'ombre à un élément.
Si l'élément a une autre valeur pourshadowrootmode, ou n'a pas l'attributshadowrootmode, l'analyseur génère unHTMLTemplateElement.De même, s'il y a plusieurs racines d'ombre déclaratives, seule la première est remplacée par unShadowRoot — les suivantes sont analysées comme des objetsHTMLTemplateElement.
Exemples
>Générer des lignes de tableau
Nous commençons d'abord par la partie HTML de l'exemple.
<table> <thead> <tr> <td>UPC_Code</td> <td>Product_Name</td> </tr> </thead> <tbody> <!-- des données existantes pourraient éventuellement être incluses ici --> </tbody></table><template> <tr> <td></td> <td></td> </tr></template>Au début, on a un tableau HTML pour lequel on insèrera du contenu plus tard grâce à l'aide d'un script JavaScript. Ensuite, on a letemplate qui décrit la structure du fragment HTML représentant une ligne de tableau.
Avec le tableau créé et le template défini, on utilise JavaScript pour insérer des lignes dans le tableau dont chacune est construite à partir dutemplate.
// On vérifie si le navigateur prend en charge// l'élément HTML template en vérifiant la présence// de l'attribut content pour l'élément template.if ("content" in document.createElement("template")) { // On prépare une ligne pour le tableau const tbody = document.querySelector("tbody"); const template = document.querySelector("#productrow"); // On clone la ligne et on l'insère dans le tableau const clone = document.importNode(template.content, true); let td = clone.querySelectorAll("td"); td[0].textContent = "1235646565"; td[1].textContent = "Pistolet à portails"; tbody.appendChild(clone); // On fait de même pour une autre ligne const clone2 = document.importNode(template.content, true); td = clone2.querySelectorAll("td"); td[0].textContent = "0384928528"; td[1].textContent = "Compagnon cube"; tbody.appendChild(clone2);} else { // Une autre méthode pour ajouter les lignes // car l'élément HTML n'est pas pris en charge.}Le résultat correspond au tableau HTML original avec deux lignes supplémentaires qui ont été ajoutées grâce au code JavaScript :
table { background: black;}table td { background: white;}Implémentation d'un DOM d'ombre déclaratif
Dans cet exemple, un avertissement de compatibilité caché est inclus au début du balisage. Cet avertissement est ensuite affiché via JavaScript si le navigateur ne prend pas en charge l'attributshadowrootmode. Ensuite, il y a deux éléments<article>, chacun contenant des éléments<style> imbriqués avec des comportements différents. Le premier élément<style> est global à tout le document. Le second est limité à la racine d'ombre générée à la place de l'élément<template> grâce à la présence de l'attributshadowrootmode.
<p hidden> ⛔ Votre navigateur ne prend pas encore en charge l'attribut <code>shadowrootmode</code>.</p><article> <style> p { padding: 8px; background-color: wheat; } </style> <p>Je suis dans le DOM.</p></article><article> <template shadowrootmode="open"> <style> p { padding: 8px; background-color: plum; } </style> <p>Je suis dans le DOM d'ombre.</p> </template></article>const isShadowRootModeSupported = Object.hasOwn( HTMLTemplateElement.prototype, "shadowRootMode",);document .querySelector("p[hidden]") .toggleAttribute("hidden", isShadowRootModeSupported);DOM d'ombre déclaratif avec délégation de sélection
Cet exemple montre commentshadowrootdelegatesfocus est appliqué à une racine d'ombre créée de manière déclarative, et l'effet que cela a sur la sélection.
Le code commence par déclarer une racine d'ombre à l'intérieur d'un élément<div>, en utilisant l'élément<template> avec l'attributshadowrootmode.Cela affiche à la fois un<div> non sélectionnable contenant du texte et un élément<input> sélectionnable.Il utilise également du CSS pour mettre en forme les éléments avec:focus en bleu, et pour définir la mise en forme normale de l'élément hôte.
<div> <template shadowrootmode="open"> <style> :host { display: block; border: 1px dotted black; padding: 10px; margin: 10px; } :focus { outline: 2px solid blue; } </style> <div>Texte cliquable dans le DOM d'ombre</div> <input type="text" placeholder="Entrée dans le DOM d'ombre" /> </template></div>Le second bloc de code est identique, à ceci près qu'il définit l'attributshadowrootdelegatesfocus, qui délègue la sélection au premier élément sélectionnable de l'arbre si un élément non sélectionnable est sélectionné.
<div> <template shadowrootmode="open" shadowrootdelegatesfocus> <style> :host { display: block; border: 1px dotted black; padding: 10px; margin: 10px; } :focus { outline: 2px solid blue; } </style> <div>Texte cliquable dans le DOM d'ombre</div> <input type="text" placeholder="Entrée dans le DOM d'ombre" /> </template></div>Enfin, on utilise le CSS suivant pour appliquer une bordure rouge à l'élément parent<div> lorsqu'il est sélectionné.
div:focus { border: 2px solid red;}Les résultats sont affichés ci-dessous.Lorsque le HTML est d'abord rendu, les éléments n'ont aucune mise en forme, comme le montre la première image.Pour la racine d'ombre qui n'a pas l'attributshadowrootdelegatesfocus défini, vous pouvez cliquer n'importe où sauf sur l'élément<input> et la sélection ne change pas (si vous sélectionnez l'élément<input>, il ressemblera à la seconde image).

Pour la racine d'ombre avec l'attributshadowrootdelegatesfocus défini, cliquer sur le texte (qui n'est pas sélectionnable) sélectionne l'élément<input>, car c'est le premier élément sélectionnable de l'arbre.Cela sélectionne également l'élément parent comme illustré ci-dessous.

Les données sur le DocumentFragment ne sont pas clonées
Lorsqu'une valeurDocumentFragment est transmise,Node.appendChild et des méthodes similaires déplacent uniquement lesnœuds enfants de cette valeur dans le nœud cible. Il est donc généralement préférable d'attacher les gestionnaires d'évènements aux enfants d'unDocumentFragment, plutôt qu'auDocumentFragment lui-même.
Considérez l'exemple HTML et JavaScript suivant :
HTML
<div></div><template> <div>Cliquez sur moi</div></template>JavaScript
const container = document.getElementById("container");const template = document.getElementById("template");function clickHandler(event) { event.target.append(" — Div cliqué");}const firstClone = document.importNode(template.content, true);firstClone.addEventListener("click", clickHandler);container.appendChild(firstClone);const secondClone = document.importNode(template.content, true);secondClone.children[0].addEventListener("click", clickHandler);container.appendChild(secondClone);Résultat
CommefirstClone est unDocumentFragment, seuls ses enfants sont ajoutés àcontainer lorsqueappendChild est appelé ; les gestionnaires d'évènements defirstClone ne sont pas copiés. En revanche, comme un gestionnaire d'évènements est ajouté au premiernœud enfant desecondClone, le gestionnaire est copié lors de l'appel àappendChild, et le clic fonctionne comme attendu.
Résumé technique
| Catégories de contenu | Contenu de méta-données,contenu de flux,contenu phrasé,élément destiné aux scripts. |
|---|---|
| Contenu autorisé | Aucune (voir lesNotes d'utilisation). |
| Omission de balises | Aucune, la balise d'ouverture et la balise de fermeture sont obligatoires. |
| Parents autorisés | Tout élément qui accepte duContenu de méta-données, ducontenu phrasé, oudes éléments destinés aux scripts. L'élément<colgroup> est également autorisé s'il n'a pas l'attributspan. |
| Rôle ARIA implicite | Pas de rôle correspondant(angl.) |
| Rôles ARIA autorisés | Aucunrole autorisé |
| Interface DOM | HTMLTemplateElement |
Spécifications
| Specification |
|---|
| HTML> # the-template-element> |
Compatibilité des navigateurs
Voir aussi
- Les attributs HTML
partetexportparts - L'élément
<slot> - Les pseudo-classes CSS
:has-slotted,:host,:host()et:host-context() - Les pseudo-éléments CSS
::partet::slotted - L'interface API
ShadowRoot - Utilisation des modèles et des emplacements
- Le modulede délimitation de CSS
- DOM d'ombre déclaratif (avec html) dansUtiliser le DOM d'ombre
- DOM d'ombre déclaratif(angl.) sur web.dev (2023)