Utiliser les attributs de données
HTML est conçu pour être extensible et permettre d'associer des données à un élément particulier sans que ces données aient nécessairement une signification définie. Les attributs data-* permettent de stocker des informations supplémentaires sur des éléments HTML standards et sémantiques, sans recourir à des astuces comme des attributs non standard ou des propriétés supplémentaires sur le DOM.
Syntaxe HTML
La syntaxe est simple. Tout attribut d'un élément dont le nom commence par data- est un attribut de données (data attribute). Si par exemple vous avez un article pour lequel vous souhaitez stocker des informations supplémentaires et qui n'ont pas de représentation visuelle, il vous suffit d'utiliser des attributs de données pour cela :
<main>
<article
id="voiture-electrique"
data-columns="3"
data-index-number="12314"
data-parent="cars">
<!-- Contenu de la voiture électrique -->
</article>
<article
id="voiture-solaire"
data-columns="3"
data-index-number="12315"
data-parent="cars">
<!-- Contenu de la voiture solaire -->
</article>
<article
id="voiture-volante"
data-columns="4"
data-index-number="12316"
data-parent="cars">
<!-- Contenu de la voiture volante -->
</article>
</main>
Accéder avec du JavaScript
Lire les valeurs de ces attributs avec du JavaScript est également très simple. Vous pourriez utiliser getAttribute() avec leur nom HTML complet pour les lire, mais le standard les définit d'une manière plus simple : un DOMStringMap peut être lu avec une propriété dataset.
Pour obtenir un attribut data avec l'objet dataset, repérez la propriété avec la partie du nom de l'attribut qui suit le préfixe data- (notez que les tirets sont convertis en camel case).
const article = document.querySelector("#voiture-electrique");
// La ligne suivante fonctionnerait également :
// const article = document.getElementById("voiture-electrique")
article.dataset.columns; // "3"
article.dataset.indexNumber; // "12314"
article.dataset.parent; // "cars"
Chaque propriété est une chaîne de caractères et peut être lue ou modifiée. Dans l'exemple ci-dessus, affecter article.dataset.columns = 5 changerait la valeur de cet attribut en "5".
Vous pouvez également utiliser document.querySelector() ou document.querySelectorAll() avec des sélecteurs d'attributs data pour trouver un élément ou tous les éléments correspondants :
// Trouver tous les éléments ayant un attribut data-columns
const articles = document.querySelectorAll("[data-columns]");
// Trouver tous les éléments avec data-columns="3"
const threeColumnArticles = document.querySelectorAll('[data-columns="3"]');
// Vous pouvez ensuite itérer sur les résultats
threeColumnArticles.forEach((article) => {
console.log(article.dataset.indexNumber);
});
Accéder avec du CSS
Remarquez que, dans la mesure où les attributs data sont de simples attributs HTML, vous pouvez même y accéder par les CSS. Par exemple, pour afficher les données associées à l'article, vous pouvez utiliser des contenus générés en CSS avec la fonction attr() :
article::before {
content: attr(data-parent);
}
Vous pouvez également utiliser les sélecteurs d'attributs en CSS pour modifier les styles en fonction des données :
article[data-columns="3"] {
width: 400px;
}
article[data-columns="4"] {
width: 600px;
}
Les valeurs des données sont des chaînes de caractères. Les valeurs numériques doivent être placées entre guillemets dans le sélecteur pour que la mise en forme soit appliquée.
Exemples
>Variantes de style
Imaginons que vous ayez une classe callout. Vous souhaitez maintenant implémenter différentes variantes, comme « note » et « attention ». Traditionnellement, on utilise simplement des noms de classes différents.
<div class="callout callout--note">...</div>
<div class="callout callout--warning">...</div>
.callout {
margin: 0.5em 0;
padding: 0.5em;
border-radius: 4px;
border-width: 2px;
border-style: solid;
}
.callout--note {
border-color: rgb(15 15 235);
background-color: rgb(15 15 235 / 0.2);
}
.callout--warning {
border-color: rgb(235 15 15);
background-color: rgb(235 15 15 / 0.2);
}
Avec les attributs data, voici une alternative que vous pouvez envisager :
<div class="callout">...</div>
<div class="callout" data-variant="note">...</div>
<div class="callout" data-variant="warning">...</div>
.callout {
margin: 0.5em 0;
padding: 0.5em;
border-radius: 4px;
border-width: 2px;
border-style: solid;
}
/* Default style */
.callout:not([data-variant]) {
border-color: rgb(15 15 15);
background-color: rgb(15 15 15 / 0.2);
}
.callout[data-variant="note"] {
border-color: rgb(15 15 235);
background-color: rgb(15 15 235 / 0.2);
}
.callout[data-variant="warning"] {
border-color: rgb(235 15 15);
background-color: rgb(235 15 15 / 0.2);
}
Cela présente plusieurs avantages :
- Cela élimine de nombreux états invalides, comme appliquer
callout--notesans ajouter aussicallout, ou appliquer plusieurs variantes simultanément. - Un attribut
data-variantséparé permet une analyse statique des valeurs valides via un linter ou une vérification de type. - Basculer la variante est plus intuitif : vous pouvez utiliser
div.dataset.variant = "warning";au lieu de manipuler la propriétéclassList, ce qui nécessite plusieurs étapes.
Associer des données arbitraires à des éléments du DOM
De nombreuses applications web utilisent des données JavaScript comme source de vérité pour l'état de leur interface. Dans ces cas, vous n'ajoutez que les attributs HTML nécessaires à l'affichage. Les attributs data sont utiles lorsque toutes les informations sont présentes dans le balisage, et que JavaScript n'est nécessaire que pour gérer les évènements, synchroniser l'état, etc.
Par exemple, dans notre exemple de carrousel avec marge de défilement, nous avons une page HTML déjà remplie de nombreux éléments <img>. La source de l'image est d'abord stockée dans data-src pour éviter tout chargement prématuré, et le vrai src n'est ajouté que lorsque l'élément <img> entre dans la zone d'affichage. Les données (source de l'image) sont donc associées à l'élément, et JavaScript ne sert qu'à définir le comportement.
Problèmes
Ne stockez pas de contenu qui devrait être visible et accessible dans les attributs data-*, car les technologies d'assistance pourraient ne pas y avoir accès. De plus, les moteurs de recherche pourraient ne pas indexer les valeurs des attributs de données. Souvent, si vous souhaitez seulement afficher la valeur de l'attribut data-*, vous pouvez directement manipuler textContent.
Voir aussi
- Cet article est une adaptation de « Utiliser les attributs de données en JavaScript et CSS » (angl.) publié sur hacks.mozilla.org (en anglais).
- Les attributs personnalisés sont également pris en charge en SVG 2 ; consultez
SVGElement.datasetetdata-*pour davantage d'informations. - Comment utiliser les attributs de données HTML (angl.) sur SitePoint