Cette page a été traduite à partir de l'anglais par la communauté. Vous pouvez contribuer en rejoignant la communauté francophone sur MDN Web Docs.

View in English Always switch to English

Fonction CSS attr()

Baseline Large disponibilité *

Cette fonctionnalité est bien établie et fonctionne sur de nombreux appareils et versions de navigateurs. Elle est disponible sur tous les navigateurs depuis juillet 2015.

* Certaines parties de cette fonctionnalité peuvent bénéficier de prise en charge variables.

Note : La fonction attr() peut être utilisée sur n'importe quelle propriété CSS, mais la prise en charge des propriétés autres que content est expérimentale.

La fonction CSS attr() est utilisée pour récupérer la valeur d'un attribut de l'élément sélectionné et l'utiliser dans une valeur de propriété, de manière similaire à la fonction var() qui substitue une valeur de propriété personnalisée. Elle peut également être utilisée avec les pseudo-éléments, auquel cas la valeur de l'attribut sur l'élément d'origine du pseudo-élément est retournée.

Exemple interactif

blockquote {
  margin: 1em 0;
}

blockquote::after {
  display: block;
  content: " (source : " attr(cite) ") ";
  color: hotpink;
}
<blockquote cite="https://mozilla.org/fr/about/">
  Mozilla œuvre pour permettre aux internautes de reprendre le contrôle
  d'Internet.
</blockquote>

<blockquote cite="https://web.dev/about/">
  Créer des sites Web attrayants, accessibles, rapides et sécurisés, compatibles
  avec tous les navigateurs.
</blockquote>

Syntaxe

css
/* Utilisation simple */
attr(data-count)
attr(href)

/* Avec un type */
attr(data-width px)
attr(data-size rem)
attr(data-name raw-string)
attr(id type(<custom-ident>))
attr(data-count type(<number>))
attr(data-size type(<length> | <percentage>))

/* Avec une solution de repli */
attr(data-count type(<number>), 0)
attr(data-width px, inherit)
attr(data-something, "default")

/* Avec un espace de noms */
attr(color|myAttr type(*), red)

Paramètres

La syntaxe de la fonction attr() est la suivante :

attr(<attr-name> <attr-type>? , <fallback-value>?)

Les paramètres sont les suivants :

<attr-name>

Le nom de l'attribut dont la valeur doit être récupérée à partir de l'élément HTML sélectionné.

Espaces de noms

Le nom de l'attribut peut contenir un namespace qui permet de cibler les éléments des langages de balisage basés sur XML tels que SVG ou MathML.

css
@namespace svg url("http://www.w3.org/2000/svg");
a {
  fill: attr(svg|myattr type(*), green);
}

Note : Si aucun espace de noms n'est défini (seul un identifiant est donné, comme attr(toto)), l'espace de noms nul est implicite. C'est généralement ce qui est souhaité, car les attributs avec espace de noms sont rares. Comme pour les sélecteurs d'attributs, la sensibilité à la casse de <attr-name> dépend du langage du document.

<attr-type>

Définit comment la valeur de l'attribut est analysée en une valeur CSS. Cela peut être le mot-clé raw-string, une fonction type(), ou une unité de dimension CSS (définie à l'aide d'un identifiant <attr-unit>). Lorsqu'il est omis, il est par défaut à raw-string.

raw-string

Le mot-clé raw-string fait en sorte que la valeur littérale de l'attribut soit traitée comme la valeur d'une chaîne de caractères CSS, sans analyse CSS effectuée (y compris les échappements CSS, la suppression des espaces, les commentaires, etc.). La <fallback-value> n'est utilisée que si l'attribut est omis ; définir une valeur vide ne déclenche pas la solution de repli.

css
attr(data-name raw-string, "stranger")

Note : Ce mot-clé était à l'origine nommé et pris en charge dans les navigateurs Chromium sous le nom de string. Les deux mots-clés seront pris en charge pendant une courte période, à des fins de rétrocompatibilité.

type()

La fonction type() prend un <syntax> comme argument qui définit le type de données dans lequel analyser la valeur.

Note : Pour des raisons de sécurité, <url> n'est pas autorisé en tant que type de données de attr().

<attr-unit>

L'identifiant <attr-unit> définit l'unité qu'une valeur numérique doit avoir (le cas échéant). Il peut s'agir du caractère % (pourcentage) ou d'une unité de distance CSS telle que px, rem, deg, s, etc.

css
attr(data-size rem)
attr(data-width px, inherit)
attr(data-rotation deg)
<fallback-value>

La valeur à utiliser si l'attribut défini est manquant ou contient une valeur invalide.

Valeur de retour

La valeur de retour de attr() est la valeur de l'attribut HTML dont le nom est <attr-name> analysée selon le <attr-type> donné ou analysée comme une chaîne de caractères CSS.

Lorsque un <attr-type> est défini, attr() tentera d'analyser l'attribut dans ce <attr-type> défini et de le retourner. Si l'attribut ne peut pas être analysé dans le <attr-type> donné, la <fallback-value> sera retournée à la place. Lorsqu'aucun <attr-type> n'est défini, l'attribut sera analysé en tant que chaîne de caractères CSS.

Si aucune valeur <fallback-value> n'est définie, la valeur de retour sera par défaut une chaîne de caractères vide lorsque aucun <attr-type> n'est défini ou la valeur garantie invalide lorsqu'un <attr-type> est défini.

Description

Limitations et sécurité

La fonction attr() peut référencer des attributs qui n'étaient jamais destinés à être utilisés pour le style et qui pourraient contenir des informations sensibles (par exemple, un jeton de sécurité utilisé par des scripts sur la page). En général, cela ne pose pas de problème, mais cela peut devenir une menace pour la sécurité lorsqu'il est utilisé dans des URL. Par conséquent, vous ne pouvez pas utiliser attr() pour construire dynamiquement des URL.

html
<!-- Ceci ne fonctionnera pas ! -->
<span data-icon="https://example.org/icons/question-mark.svg">aide</span>
css
span[data-icon] {
  background-image: url(attr(data-icon));
}

Cependant, cette restriction ne s'applique qu'aux endroits qui nécessitent strictement un type <url>. Certaines fonctions — comme image-set() — peuvent accepter une valeur <string> qui est ensuite interprétée comme une URL, permettant à attr() de fonctionner dans ces contextes, en fonction du support du navigateur :

css
span[data-icon] {
  background: image-set(attr(data-icon));
}

Les valeurs qui utilisent attr() sont marquées comme altérées par attr(). L'utilisation d'une valeur altérée par attr() en tant que <url> rend la déclaration « invalide au moment du calcul de la valeur » ou IACVT pour faire court (angl.).

Rétrocompatibilité

En général, la syntaxe moderne de attr() est rétrocompatible, car l'ancienne manière de l'utiliser — sans définir un <attr-type> — se comporte de la même manière qu'auparavant. Avoir attr(data-attr) dans votre code est équivalent à écrire attr(data-attr type(<string>)) ou le plus simple attr(data-attr string)).

Cependant, il existe deux cas limites où la syntaxe moderne de attr() se comporte différemment de l'ancienne syntaxe.

Dans l'extrait suivant, les navigateurs qui ne prennent pas en charge la syntaxe moderne de attr() ignoreront la deuxième déclaration car ils ne peuvent pas l'analyser. Le résultat dans ces navigateurs est "Bonjour le monde".

html
<div text="Bonjour"></div>
css
div::before {
  content: attr(text) " le monde";
}
div::before {
  content: attr(text) 1px;
}

Dans les navigateurs qui prennent en charge la syntaxe moderne, le résultat sera… rien. Ces navigateurs analyseront correctement la deuxième déclaration, mais comme elle est un contenu invalide pour la propriété content, la déclaration devient « invalide au moment du calcul de la valeur » ou IACVT pour faire court (angl.).

Pour éviter ce genre de situation, il est recommandé d'utiliser la détection de fonctionnalités.

Un deuxième cas limite est le suivant :

html
<div id="parent"><div id="enfant" data-attr="toto"></div></div>
css
#parent {
  --x: attr(data-attr);
}
#enfant::before {
  content: var(--x);
}

Les navigateurs sans prise en charge de la syntaxe moderne affichent le texte "toto". Dans les navigateurs avec prise en charge moderne de attr(), il n'y a aucune sortie.

Cela s'explique par le fait que attr() — similaire aux propriétés personnalisées qui utilisent la fonction var() — est substitué au moment du calcul de la valeur (angl.). Avec le comportement moderne, --x tente d'abord de lire l'attribut data-attr de l'élément #parent, ce qui donne une chaîne de caractères vide car il n'y a pas un tel attribut sur #parent. Cette chaîne de caractères vide est ensuite héritée par l'élément #enfant, ce qui entraîne une déclaration content: ;.

Pour éviter ce genre de situation, il est recommandé de ne pas transmettre les valeurs héritées de attr() aux enfants sauf si vous le souhaitez explicitement.

Détection de fonctionnalités

Vous pouvez détecter la prise en charge de la syntaxe moderne de attr() en utilisant la règle @supports. Dans le test, essayez d'assigner un attr() avancé à une propriété CSS (non personnalisée).

Par exemple :

css
@supports (x: attr(x type(*))) {
  /* Le navigateur prend en charge la syntaxe moderne de attr() */
}

@supports not (x: attr(x type(*))) {
  /* Le navigateur ne prend pas en charge la syntaxe moderne de attr() */
}

Nous pouvons effectuer le même test en JavaScript avec CSS.supports() :

js
if (CSS.supports("x: attr(x type(*))")) {
  /* Le navigateur prend en charge la syntaxe moderne de attr() */
}

if (!CSS.supports("x: attr(x type(*))")) {
  /* Le navigateur ne prend pas en charge la syntaxe moderne de attr() */
}

Syntaxe formelle

<attr()> = 
attr( <attr-name> <attr-type>? , <declaration-value>? )

<attr-name> =
[ <ident-token>? '|' ]? <ident-token>

<attr-type> =
type( <syntax> ) |
raw-string |
number |
<attr-unit>

<syntax> =
'*' |
<syntax-component> [ <syntax-combinator> <syntax-component> ]* |
<syntax-string>

<syntax-component> =
<syntax-single-component> <syntax-multiplier>? |
'<' transform-list '>'

<syntax-combinator> =
'|'

<syntax-string> =
<string>

<syntax-single-component> =
'<' <syntax-type-name> '>' |
<ident>

<syntax-multiplier> =
'#' |
'+'

<syntax-type-name> =
angle |
color |
custom-ident |
image |
integer |
length |
length-percentage |
number |
percentage |
resolution |
string |
time |
url |
transform-function

Exemples

Utiliser la propriété content

Dans cet exemple, nous préfixons la valeur de l'attribut universel data-* data-toto au contenu de l'élément HTML <p>.

HTML

html
<p data-toto="coucou">le monde</p>

CSS

css
[data-toto]::before {
  content: attr(data-toto) " ";
}

Résultat

Utiliser une valeur de repli

Expérimental: Il s'agit d'une technologie expérimentale.
Vérifiez attentivement le tableau de compatibilité des navigateurs avant de l'utiliser en production.

Dans cet exemple, nous ajoutons la valeur de l'attribut universel data-* data-browser au contenu de l'élément HTML <p>. Si l'attribut data-browser est absent de l'élément HTML <p>, nous ajoutons la valeur de repli « Inconnu ».

HTML

html
<p data-browser="Firefox">Mon navigateur préféré est&nbsp;:</p>
<p>Votre navigateur préféré est&nbsp;:</p>

CSS

css
p::after {
  content: " " attr(data-browser, "Inconnu");
  color: tomato;
}

Résultat

Valeur de type <color>

Expérimental: Il s'agit d'une technologie expérimentale.
Vérifiez attentivement le tableau de compatibilité des navigateurs avant de l'utiliser en production.

Dans cet exemple, nous définissons la valeur CSS de background-color à la valeur de l'attribut universel data-* data-background assigné à l'élément HTML <div>.

HTML

html
<div class="background" data-background="lime">
  Le fond devrait être rouge si votre navigateur ne prend pas en charge
  l'utilisation avancée de attr()
</div>

CSS

css
.background {
  background-color: red;
}

.background[data-background] {
  background-color: attr(data-background type(<color>), red);
}

Résultat

Utiliser des unités de dimension

Expérimental: Il s'agit d'une technologie expérimentale.
Vérifiez attentivement le tableau de compatibilité des navigateurs avant de l'utiliser en production.

Dans cet exemple, l'attribut data-rotation est analysé en une unité deg, qui définit la rotation de l'élément.

HTML

html
<div data-rotation="-3">Je suis tourné de -3 degrés</div>
<div data-rotation="2">Et moi de 2 degrés</div>
<div>Et moi aussi, en utilisant la valeur de repli de 1,5deg</div>

CSS

css
div {
  width: fit-content;
  transform-origin: 50% 50%;
  rotate: attr(data-rotation deg, 1.5deg);
}

Résultat

Analyser les valeurs de attr() en tant que <custom-ident>

Expérimental: Il s'agit d'une technologie expérimentale.
Vérifiez attentivement le tableau de compatibilité des navigateurs avant de l'utiliser en production.

Dans cet exemple, les valeurs de la propriété view-transition-name sont dérivées de l'attribut id de l'élément. L'attribut est analysé en un identifiant personnalisé (<custom-ident>), ce qui est accepté comme valeur par view-transition-name.

Les valeurs résultantes pour view-transition-name sont carte-1, carte-2, carte-3, etc.

HTML

Le HTML contient quatre cartes avec différents attributs id et un <button> « Mélanger les cartes », qui mélange les cartes.

html
<div class="cartes">
  <div class="carte" id="carte-1">1</div>
  <div class="carte" id="carte-2">2</div>
  <div class="carte" id="carte-3">3</div>
  <div class="carte" id="carte-4">4</div>
</div>
<button>Mélanger les cartes</button>

CSS

Les cartes sont disposées dans un conteneur flexible :

css
.cartes {
  display: flex;
  flex-direction: row;
  gap: 1em;
  padding: 1em;
}

Sur chaque carte, la fonction attr() récupère l'attribut id et l'analyse en un <custom-ident>, qui est utilisé comme valeur pour la propriété view-transition-name. Lorsqu'aucun id n'est défini sur une carte, la valeur de repli none est utilisée à la place.

css
.carte {
  view-transition-name: attr(id type(<custom-ident>), none);
  view-transition-class: carte;
}

JavaScript

Lorsque le <button> est pressé, les cartes sont mélangées. Cela se fait en rendant aléatoire l'ordre d'un tableau contenant des références à toutes les cartes, puis en mettant à jour la propriété order de chaque carte avec sa nouvelle position dans le tableau.

Pour animer chaque carte vers sa nouvelle position, les transitions de vue sont utilisées. Cela se fait en enveloppant la mise à jour de order dans un appel à document.startViewTransition.

js
const melanger = (array) => {
  for (let i = array.length - 1; i >= 0; i--) {
    const j = Math.floor(Math.random() * (i + 1));
    [array[i], array[j]] = [array[j], array[i]];
  }
};

document.querySelector("button").addEventListener("click", (e) => {
  const $cartes = Array.from(document.querySelectorAll(".carte"));
  melanger($cartes);
  document.startViewTransition(() => {
    $cartes.forEach(($carte, i) => {
      $carte.style.setProperty("order", i);
    });
  });
});

Résultat

Spécifications

Spécification
CSS Values and Units Module Level 5
# attr-notation

Compatibilité des navigateurs

Voir aussi