Utilisation d'attributs de données au lieu de classes CSS

Apr 22 2023
Nous utilisons des classes dans nos sélecteurs CSS depuis toujours. Et avec l'essor des frameworks de "classes utilitaires" comme Tailwind, notre balisage HTML s'est gonflé de classes.
Photo de Jackson Sophat sur Unsplash

Nous utilisons des classes dans nos sélecteurs CSS depuis toujours. Et avec l'essor des frameworks de "classes utilitaires" comme Tailwind, notre balisage HTML s'est gonflé de classes. Mais y a-t-il une meilleure façon?

Considérons quelque chose que nous voyons tout le temps - un lien de bouton. Nous pourrions commencer par une simple balise d'ancrage :

<a href="/page">Go somewhere</a>

identifiants

Si vous connaissez déjà un peu le CSS, vous saurez probablement que ce ne sera pas notre meilleure solution. Mais jetons-y juste un coup d'œil, pour être complet.

Nous pouvons appliquer une idpropriété à notre élément de lien et l'utiliser pour le cibler avec CSS.

<a href="/page" id="my-button">Go somewhere</a>
#button {
  /* styles go here */
}

Un idattribut ne peut également contenir qu'une seule valeur, sans espace. Cela signifie qu'un élément ne peut avoir qu'un seul identifiant.

Les identifiants ont leur place, mais ce n'est pas tout à fait ce que nous recherchons. Alors, comment créer des styles réutilisables ?

Des classes

Si vous avez lu le titre, il ne sera pas surprenant que ce ne soit pas non plus la solution vers laquelle nous nous dirigeons. Mais, encore une fois, regardons-le un instant pour comprendre comment nous devrions - et ne devrions pas - utiliser les classes.

<a href="/page" class="button">Go somewhere</a>
.button {
  /* styles go here */
}

<a href="/page" class="button is-blue is-rounded">Go somewhere</a>
<a href="/another" class="button is-orange">Go elsewhere</a>
.button {
  /* common styles go here */
}
.is-blue {
  background: blue;
  color: white;
}
.is-orange {
  background: orange;
  color: white;
}
.is-rounded {
  border-radius: 1em;
}

Le problème est qu'il buttondécrit une famille, alors qu'il is-blueest destiné à décrire une propriété dont il dispose. Les mettre tous les deux dans des classes fonctionne, mais nous perdons une partie du sens. Et, plus important encore, rien ne nous empêche de faire une bêtise :

<a href="/page" class="is-blue is-orange">What am I?</a>

Attributs de données

Merci pour votre patience. Nous sommes ici maintenant.

Les éléments HTML peuvent avoir toutes sortes d'attributs. Jusqu'à présent, nous avons utilisé href, idet class. Et il y a beaucoup d'autres attributs définis dans la spécification HTML. Nous ne pouvons pas ajouter notre propre bon gré mal gré, car cela conduirait potentiellement à des conflits et à de mauvaises pratiques. Mais HTML nous permet d'utiliser des "attributs de données" personnalisés, qui sont des attributs commençant par data-.

Dans notre cas, nous pourrions utiliser un attribut de données pour définir le « thème » du bouton, en précisant que chaque élément ne doit avoir qu'une seule valeur.

<a href="/page" class="button" data-theme="blue">Go somewhere</a>
.button {
  /* base styles go here */
}
[data-theme="blue"] {
  background: blue;
  color: white;
}
[data-theme="orange"] {
  background: orange;
  color: white;
}

Une autre chose intéressante à propos des attributs de données est qu'ils n'ont même pas besoin d'avoir une valeur, ce qui fonctionne très bien pour les propriétés booléennes.

<a href="/page" class="button" data-theme="blue" data-rounded>Go somewhere</a>
[data-rounded] {
  border-radius: 1em;
}

Mettons tout cela ensemble, avec quelques autres morceaux épicés ajoutés…

J'ai défini deux options pour data-theme, chacune définissant des variables CSS pour les couleurs de premier plan et d'arrière-plan de l'élément. Dans le CSS, notez que le [data-theme]sélecteur ne se soucie pas du type d'élément auquel il s'applique, nous pouvons donc l'appliquer à .buttonou sectionà tout ce que nous voulons.

En revanche, la data-roundedpropriété n'a vraiment de sens que pour certains types d'éléments, c'est pourquoi nous l'avons définie comme .button[data-rounded]. Même si nous utilisions par erreur l'attribut sur un section, il ne s'appliquerait pas.

Il y a aussi quelques autres petites touches agréables dans cette démo, comme l'utilisation filterpour les états de survol et de bouton actif. Jetez un œil au code source de cette démo et voyez ce qui attire votre attention !