aboutsummaryrefslogtreecommitdiff
path: root/files/fr/web/css/using_css_custom_properties/index.html
blob: 718ed14de441e2493e46b79682f2b41a62704e70 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
---
title: Les variables CSS
slug: Web/CSS/Using_CSS_custom_properties
tags:
  - CSS
  - Guide
  - Intermédiaire
  - Web
translation_of: Web/CSS/Using_CSS_custom_properties
---
<div>{{CSSRef}}</div>

<p><strong>Les propriétés personnalisées CSS</strong> (<em>custom properties</em> en anglais, aussi parfois appelés <strong>variables CSS</strong>) sont des entités définies par les développeurs ou les utilisateurs d'une page Web, contenant des valeurs spécifiques utilisables à travers le document. Elles sont initialisées avec des propriétés personnalisées (par exemple <strong><code>--main-color: black;</code></strong>) et accessibles en utilisant la notation spécifique {{cssxref("var", "var()")}} (par exemple : <strong><code>color: var(--main-color);</code></strong>).</p>

<p>Des sites et applications web complexes peuvent avoir des feuilles de style où de nombreuses valeurs sont répétées. Ainsi, la même couleur pourra être utilisée à des centaines d'endroits où il faudra la mettre à jour si besoin. Les propriétés personnalisées permettent de stocker une valeur à un endroit puis de réutiliser cette valeur (on factorise ainsi le code).</p>

<h2 id="Utilisation_simple">Utilisation simple</h2>

<p>Voici comment on déclare une variable :</p>

<pre class="brush:css; highlight:[2]">element {
  --main-bg-color: brown;
}
</pre>

<p>Et voici comment on l'utilise</p>

<pre class="brush:css; highlight:[2]">element {
  background-color: var(--main-bg-color);
}
</pre>

<h2 id="Problématique">Problématique</h2>

<p>Lors de l'élaboration de sites de grande envergure, leurs auteurs font parfois face à des soucis de maintenabilité. De grandes feuilles de styles sont utilisées et de nombreuses informations se répètent. Par exemple, maintenir un thème de couleurs à travers un document nécessite la réutilisation des valeurs des couleurs à plusieurs endroits dans les fichiers CSS. Modifier un thème, en changeant une couleur ou en le récrivant entièrement, devient alors une tâche complexe demandant de la précision, là où un simple trouver et remplacer ne suffit pas.</p>

<p>Le problème peut s'aggraver en utilisant les <em>frameworks</em> CSS puisque modifier une couleur demande de modifier le framework lui-même. Les pré-processeurs comme <a href="https://lesscss.org/">LESS</a> ou <a href="https://sass-lang.com/">Sass</a> peuvent faciliter cette tâche, mais peuvent également complexifier le processus de création en ajoutant une étape de compilation. Les propriétés personnalisées permettent d'utiliser une des principales fonctionnalités des pré-processeurs, sans cette étape de compilation.</p>

<p>Le deuxième avantage de ces variables vient du fait que le nom lui-même contient des informations sémantiques. Les fichiers CSS deviennent alors plus facile à lire et à comprendre : écrire <code>main-text-color</code> permet de mieux s'y retrouver au fur et à mesure de la lecture qu'une valeur hexadécimale comme <code>#00ff00</code>, surtout si la même couleur est utilisée dans un autre contexte.</p>

<h2 id="Définition">Définition</h2>

<p>Les propriétés personnalisées ont actuellement deux formes :</p>

<ul>
 <li>les variables, qui sont des associations entre un identifiant et une valeur utilisables à la place de n'importe quelle valeur normale, en utilisant la notation fonctionnelle <code>var()</code> : <code>var(--example-variable)</code> retourne la valeur de <code>--example-variable</code>.</li>
 <li>les propriétés personnalisées, qui sont des propriétés spéciales notées <code>--*</code> où <code>*</code> représente le nom de la variable. Elles sont utilisées pour définir la valeur d'une variable donnée : <code>--example-variable: 20px;</code> est une déclaration en CSS, utilisant la propriété personnalisée <code>--*</code> pour initialiser la valeur de la variable CSS <code>--example-variable</code> à <code>20px</code>.</li>
</ul>

<div class="note"><strong>Note :</strong> Le préfixe de propriété personnalisée était noté <code>var-</code> dans les précédentes spécifications, mais a ensuite été changé pour <code>--</code>. Firefox 31 et supérieurs respectent cette nouvelle notation. ({{bug(985838)}})</div>

<p>Les propriétés personnalisées sont similaires aux propriétés ordinaires. Elles sont sujettes à la cascade et héritent leur valeur de leur parent si elles ne sont pas redéfinies.</p>

<h2 id="Premiers_pas_avec_les_propriétés_personnalisées_CSS">Premiers pas avec les propriétés personnalisées CSS</h2>

<p>Commençons avec cette feuille CSS simple colorant les éléments de différentes classes avec la même couleur :</p>

<div id="sample1">
<pre class="brush:css; highlight:[3,20,26,32]">.un {
  color: white;
  background-color: brown;
  margin: 10px;
  width: 50px;
  height: 50px;
  display: inline-block;
}

.deux {
  color: white;
  background-color: black;
  margin: 10px;
  width: 150px;
  height: 70px;
  display: inline-block;
}
.trois {
  color: white;
  background-color: brown;
  margin: 10px;
  width: 75px;
}
.quatre {
  color: white;
  background-color: brown;
  margin: 10px;
  width: 100px;
}

.cinq {
  background-color: brown;
}

</pre>

<p>Appliquons-le à ce code HTML :</p>

<pre class="brush:html">&lt;div&gt;
    &lt;div class="un"&gt;Toto&lt;/div&gt;
    &lt;div class="deux"&gt;Texte &lt;span class="cinq"&gt;- encore du texte&lt;/span&gt;&lt;/div&gt;
    &lt;input class="trois"&gt;
    &lt;textarea class="quatre"&gt;Lorem Ipsum&lt;/textarea&gt;
&lt;/div&gt;
</pre>

<p>ce qui donne ceci :</p>

<p>{{EmbedLiveSample("sample1",600,180)}}</p>

<p>Remarquez la répétition dans le CSS. La couleur d'arrière-plan est définie à <code>brown</code> à plusieurs endroits. Certaines déclarations peuvent être faites plus haut dans la cascade et le problème se résoudra grâce à l'héritage. Mais pour des projets non-triviaux, cela n'est pas toujours possible. En déclarant une variable dans la pseudo-classe {{cssxref(":root")}}, un développeur CSS peut éviter certaines répétitions en utilisant cette variable.</p>
</div>

<div id="sample2">
<pre class="brush:css; highlight:[2, 7, 24,30,36]">:root {
  --main-bg-color: brown;
}

.un {
  color: white;
  background-color: var(--main-bg-color);
  margin: 10px;
  width: 50px;
  height: 50px;
  display: inline-block;
}

.deux {
  color: white;
  background-color: black;
  margin: 10px;
  width: 150px;
  height: 70px;
  display: inline-block;
}
.trois {
  color: white;
  background-color: var(--main-bg-color);
  margin: 10px;
  width: 75px;
}
.quatre {
  color: white;
  background-color: var(--main-bg-color);
  margin: 10px;
  width: 100px;
}

.cinq {
  background-color: var(--main-bg-color);
}

</pre>

<pre class="brush:html hidden">&lt;div&gt;
    &lt;div class="un"&gt;Toto&lt;/div&gt;
    &lt;div class="deux"&gt;Text &lt;span class="cinq"&gt;- more text&lt;/span&gt;&lt;/div&gt;
    &lt;input class="trois"&gt;
    &lt;textarea class="quatre"&gt;Lorem Ipsum&lt;/textarea&gt;
&lt;/div&gt;
</pre>

<p>Ce code donne le même résultat que précédemment mais permet de n'utiliser la propriété désirée qu'une seule fois.</p>

<h2 id="Héritage_des_propriétés_personnalisées_et_valeurs_par_défaut">Héritage des propriétés personnalisées et valeurs par défaut</h2>

<p>Il y a un héritage des propriétés personnalisées. Cela signifie que si une propriété n'est pas définie sur un élément, la valeur prise en compte sera celle utilisée pour la propriété de l'élément parent. Le fragment de document suivant :</p>

<pre class="brush: html">&lt;div class="un"&gt;
  &lt;div class="deux"&gt;
    &lt;div class="trois"&gt;
    &lt;/div&gt;
    &lt;div class="quatre"&gt;
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;</pre>
</div>

<p>associé à cette feuille de style :</p>

<pre class="brush: css">.deux {
  --test: 10px;
}

.trois {
  --test: 2em;
}
</pre>

<p>Dans ce cas, les résultats de <code>var(--test)</code> seront :</p>

<ul>
 <li><code>10px</code> pour l'élément avec <code>class="deux"</code></li>
 <li><code>2em</code> pour l'élément avec <code>class="trois"</code></li>
 <li><code>10px</code> pour l'élément avec <code>class="quatre"</code> : la valeur est héritée depuis le parent</li>
 <li><em>invalid value</em> pour l'élément avec <code>class="un"</code>, c'est la valeur par défaut utilisée pour les différentes propriétés personnalisées.</li>
</ul>

<p>Gardez à l'esprit qu'il s'agit de propriétés personnalisées et non de propriétés personnalisées réelles. La valeur est calculée là où elle est nécessaire, non stockée pour être utilisée dans d'autres règles. Par exemple, vous ne pouvez pas définir une propriété pour un élément et espérer l'extraire dans la règle du descendant d'un frère. La propriété est uniquement définie pour le sélecteur correspondant et ses descendants, comme tout CSS normal.</p>

<p>Avec <code><a href="/fr/docs/Web/CSS/var()">var()</a></code> on peut définir plusieurs valeurs par défaut lorsque la variable donnée n'est pas définie. Cela peut s'avérer utile lorsqu'on travaille avec des éléments personnalisés (<em>Custom Elements</em>) et le <em>Shadow DOM</em>.</p>

<p>Le premier argument passé à la fonction est le nom de la <a href="https://www.w3.org/TR/css-variables/#custom-property" title="CSS Custom Properties for Cascading Variables Module Level 1">propriété personnalisée</a> qui doit être substituée. Le deuxième argument, s'il est fourni, indique la valeur par défaut qui est utilisée lorsque la <a href="https://www.w3.org/TR/css-variables/#custom-property" title="CSS Custom Properties for Cascading Variables Module Level 1">propriété personnalisée</a> en question est invalide.</p>

<div class="blockIndicator note">
<p><strong>Note :</strong> Attention, la valeur fournie comme valeur par défaut ne pourra pas être utilisée si le navigateur ne prend pas en charge les propriétés personnalisées CSS. Elle sera uniquement utilisée si la valeur précédente n'a pu être calculée ou si elle est invalide.</p>
</div>

<pre class="brush: css">.deux {
  color: var(--my-var, red);
  /* Red si --my-var n'est pas définie */
}

.trois {
  background-color: var(--my-var, var(--my-background, pink));
  /* rose (pink) si --my-var et --my-background ne sont pas définies */
}

// Suite invalide :
.trois {
  background-color: var(--my-var, --my-background, pink);
}
</pre>

<div class="note">
<p><strong>Note : </strong>La syntaxe pour la valeur de recours, comme celle des <a dir="ltr" href="https://www.w3.org/TR/css-variables/#custom-property" title="CSS Custom Properties for Cascading Variables Module Level 1">propriétés personnalisées</a>, permet d'utiliser une virgule. Ainsi, <code>var(--toto, red, blue)</code> définit une valeur de recours égale à <code>red, blue</code>, c'est-à-dire tout ce qui est écrit après la première virgule. Si la deuxième valeur est incorrecte, elle ne pourra pas être utilisée et la règle sera invalide.</p>

<p>La syntaxe de la deuxième règle (sur <code>.trois</code>) permet d'utiliser une autre variable comme variable de secours et une autre valeur (<code>pink</code>) dans le cas où cette deuxième variable ne fonctionne pas.</p>
</div>

<div class="note">
<p><strong>Note :</strong> Des problèmes de performances ont pu être observés<sup>[source ?] </sup> causant un rendu plus lent des pages car le navigateur doit analyser l'ensemble des variables pour voir si elles sont disponibles.</p>
</div>

<h2 id="Validité_et_valeurs">Validité et valeurs</h2>

<p>Le concept classique de validité en CSS, lié à chaque propriété, n'est pas très utile en ce qui concerne les propriétés personnalisées. Quand la valeur d'une propriété personnalisée est lue, le navigateur ne sait pas à quel moment elle sera utilisée. Il doit donc considérer quasiment toutes les valeurs comme <em>valides</em>.</p>

<p>Malheureusement, ces valeurs valides peuvent être utilisées, via la notation fonctionnelle <code>var()</code>, dans un contexte où cela n'aurait pas de sens. Les propriétés et variables personnalisées peuvent mener à des déclarations CSS invalides, conduisant à un nouveau concept de <em>valide lors de l'exécution</em>.</p>

<h2 id="Gestion_des_variables_invalides">Gestion des variables invalides</h2>

<p>Lorsque le navigateur analyse une substitution <code>var()</code> invalide, c'est la valeur initiale ou héritée de la propriété qui est utilisée. Par exemple :</p>

<h3 id="HTML">HTML</h3>

<pre class="brush: html">&lt;p&gt;La couleur initiale d'un paragraphe est noire.&lt;/p&gt; </pre>

<h3 id="CSS">CSS</h3>

<pre class="brush: css">:root { --text-color: 16px; }
p { color: blue; }
p { color: var(--text-color); }
</pre>

<p>Comme on pourrait s'y attendre, le valeur applique la substitution aec <code>--text-color</code> à la place de <code>var(--text-color)</code> mais <code>16px</code> n'est pas une valeur valide pour {{cssxref("color")}}. Après la substitution, la déclaration n'a plus aucun sens. Le navigateur résoud ce problème en deux étapes :</p>

<ol>
 <li>Il vérifie si la propriété peut être héritée (ici <code>color</code>) : c'est bien le cas mais dans notre exemple <code>&lt;p&gt;</code> n'a aucun parent avec une couleur définie, il passe donc à l'étape suivante.</li>
 <li>La valeur utilisée est <strong>la valeur initiale par défaut</strong>, pour <code>color</code>, c'est <code>black</code>.</li>
</ol>

<h3 id="Résultat">Résultat</h3>

<p>{{EmbedLiveSample('Gestion_des_valeurs_invalides')}}</p>

<div class="note">
<p><strong>Note :</strong> La couleur du paragraphe ne sera pas bleue car une substitution invalide est remplacée par la valeur héritée ou la valeur initiale, pas par les valeurs provenant d'éventuelles autres règles.</p>

<p>Si on avait directement écrit <code>color: 16px</code> (sans substitution), c'est alors la déclaration précédente qui aurait été utilisée.</p>
</div>

<h2 id="Manipulation_des_variables_en_JavaScript">Manipulation des variables en JavaScript</h2>

<p>Il est possible d'utiliser les valeurs des propriétés personnalisés en JavaScript de la même façon que les propriétés standards.</p>

<pre class="brush: js">// obtenir une variable à partir d'un style en ligne (dans un élément html)
element.style.getPropertyValue("--ma-variable");

// obtenir une variable par ailleurs
getComputedStyle(element).getPropertyValue("--ma-variable");

// définir une variable dans un style en ligne
element.style.setProperty("--ma-variable", varJS + 4);</pre>

<h2 id="Compatibilité_des_navigateurs">Compatibilité des navigateurs</h2>

<p>{{Compat("css.properties.custom-property")}}</p>

<div class="note">
<p><strong>Note :</strong> Dans les versions antérieures de la spécification, le préfixe indiquant les propriétés personnalisées était <code>var-</code>. Ce préfixe a ensuite été modifié en <code>--</code>. et Firefox 31 et les versions ultérieures respectent cette spécification  (cf. {{bug(985838)}})</p>
</div>

<h2 id="Voir_aussi">Voir aussi</h2>

<ul>
 <li>{{cssxref("--*", "Les propriétés personnalisées")}}</li>
</ul>