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
/* 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
namespacequi 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 fonctiontype(), 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-stringfait 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.cssattr(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 deattr(). <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 quepx,rem,deg,s, etc.cssattr(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.
<!-- Ceci ne fonctionnera pas ! -->
<span data-icon="https://example.org/icons/question-mark.svg">aide</span>
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 :
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".
<div text="Bonjour"></div>
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 :
<div id="parent"><div id="enfant" data-attr="toto"></div></div>
#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 :
@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() :
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
<p data-toto="coucou">le monde</p>
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
<p data-browser="Firefox">Mon navigateur préféré est :</p>
<p>Votre navigateur préféré est :</p>
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
<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
.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
<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
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.
<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 :
.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.
.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.
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> |