aboutsummaryrefslogtreecommitdiff
path: root/files/fr/web/css/@supports/index.html
blob: 6baf61e27c6aff4c9b9c1a1e698f9185dd0b3970 (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
---
title: '@supports'
slug: Web/CSS/@supports
tags:
  - CSS
  - Reference
  - Règle @
translation_of: Web/CSS/@supports
---
<div>{{CSSRef}}</div>

<p>La règle <strong><code>@supports</code></strong> permet de définir des déclarations qui dépendent de la prise en charge du navigateur d'une ou plusieurs fonctionnalités CSS. Cette condition est définie par un ensemble de paires de propriété/valeur qui forment une combinaison de conjonctions, disjonctions, négations. Une telle condition est appelée « condition de prise en charge » (ou <em>supports condition</em>).</p>

<pre class="brush: css no-line-numbers">@supports (display: grid) {
  div {
    display: grid;
  }
}</pre>

<pre class="brush: css no-line-numbers">@supports not (display: grid) {
  div {
    float: right;
  }
}</pre>

<p><code>@supports</code> permet ainsi au moteur de rendu de tester la présence d'une fonctionnalité (on parle de <em>feature query</em>).</p>

<p>La règle @ <code>@supports</code> peut être utilisée au niveau le plus haut de la feuille de style et également à l'intérieur d'<a href="/fr/docs/Web/CSS/Règles_@#R.C3.A8gles_conditionnelles_de_groupe">un groupe de règle conditionnel</a>. Cette règle @ peut être manipulée via le modèle d'objets CSS et JavaScript, notamment via l'interface {{domxref("CSSSupportsRule")}}.</p>

<h2 id="Syntaxe">Syntaxe</h2>

<p>Une condition de prise en charge se compose d'une ou plusieurs déclarations combinées entre elles par des opérateurs logiques (<code>and</code>, <code>or</code>, <code>not</code>). La précédence des opérateurs peut être surchargée en utilisant des parenthèses autour des déclarations.</p>

<h3 id="Syntaxe_déclarative">Syntaxe déclarative</h3>

<p>La plus simple expression est une déclaration CSS, c'est-à-dire un nom de propriété CSS suivi par deux points (:) puis une valeur. Ainsi, l'expression suivante :</p>

<pre class="brush:css">@supports ( transform-origin: 5% 5% ) { }</pre>

<p>renvoie le booléen vrai si la propriété {{cssxref("transform-origin")}} du navigateur considère que la valeur <code>5% 5%</code> est valide.</p>

<p>Une déclaration CSS est toujours encadrée par des parenthèses.</p>

<h3 id="Syntaxe_fonctionnelle">Syntaxe fonctionnelle</h3>

<p>La deuxième syntaxe permet d'utiliser une fonction. Cette syntaxe est prise en charge par les différents navigateurs mais les fonctions sont en cours de standardisation.</p>

<h4 id="selector_Experimental_inline"><code>selector()</code> {{Experimental_inline}}</h4>

<p>Dans l'exemple qui suit, on teste si le navigateur prend en charge la syntaxe du sélecteur passé en argument. Ici, le code renvoie VRAI si le navigateur prend en charge les <a href="/fr/docs/Web/CSS/Sélecteurs_enfant">sélecteurs enfants</a></p>

<pre class="brush: css">@supports selector(A &gt; B) { }</pre>

<h3 id="Lopérateur_not">L'opérateur <code>not</code></h3>

<p>L'opérateur <code>not</code> peut être utilisée avant une expression afin de créer un expression dont le résultat logique est la négation du résultat de l'expression originale. Ainsi, l'expression suivante :</p>

<pre class="brush:css">@supports not ( transform-origin: 10em 10em 10em ) { }</pre>

<p>renvoie VRAI si la propriété {{cssxref("transform-origin")}} du navigateur ne considère pas la valeur <code>10em 10em 10em</code> comme valide.</p>

<p>Comme pour les autres opérateurs, on peut appliquer l'opérateur <code>not</code> à une déclaration, quelle que soit sa complexité. Les exemples qui suivent sont donc des expressions valides :</p>

<pre class="brush:css">@supports not ( not ( transform-origin: 2px ) ) { }
@supports (display: grid) and ( not (display: inline-grid) ) { }</pre>

<div class="note style-wrap">
<p><strong>Note :</strong> Au niveau le plus haut, il n'est pas nécessaire d'encadrer l'opérateur <code>not</code> entre parenthèses. Si on souhaite le combiner avec d'autres opérateurs comme <code>and</code> ou <code>or</code>, il faudra utiliser des parenthèses.</p>
</div>

<h3 id="Lopérateur_and">L'opérateur <code>and</code></h3>

<p>L'opérateur <code>and</code> peut être utilisé pour former une nouvelle expression à partir de deux expressions. L'expression résultante sera la conjonction des deux expressions originelles. Autrement dit, le résultat de cette nouvelle expression sera VRAI si et seulement si les deux expressions de départ sont vraies et FAUX sinon. Dans l'exemple suivant, l'expression complète ne sera vérifiée que si les deux expressions sont vérifiées :</p>

<pre class="brush:css">@supports (display: table-cell) and (display: list-item) { }</pre>

<p>On peut enchaîner plusieurs conjonctions sans avoir à ajouter de parenthèses (l'opérateur est commutatif).</p>

<pre class="brush:css">@supports (display: table-cell) and (display: list-item) and (display:run-in) { }</pre>

<p>sera équivalente à :</p>

<pre class="brush:css">@supports (display: table-cell) and ((display: list-item) and (display:run-in)) { }</pre>

<h3 id="Lopérateur_or">L'opérateur <code>or</code></h3>

<p>L'opérateur <code>or</code> peut être utilisé pour former une nouvelle expression à partir de deux expressions. L'expression résultante sera la disjonction des deux expressions originelles. Autrement dit, le résultat de cette nouvelle expression sera VRAI si au moins une des deux expressions est vraie. Dans l'exemple qui suit, l'expression complète est vérifiée si au moins une des deux (ce peuvent être les deux) expressions est vérifiée :</p>

<pre class="brush:css;">@supports ( transform-style: preserve ) or ( -moz-transform-style: preserve ) { }</pre>

<p>On peut enchaîner plusieurs disjonctions sans qu'il soit nécessaire d'ajouter des parenthèses.</p>

<pre class="brush:css">@supports ( transform-style: preserve ) or ( -moz-transform-style: preserve ) or
          ( -o-transform-style: preserve ) or ( -webkit-transform-style: preserve  ) { }</pre>

<p>sera ainsi équivalente à :</p>

<pre class="brush:css">@supports ( transform-style: preserve-3d ) or (( -moz-transform-style: preserve-3d ) or
          (( -o-transform-style: preserve-3d ) or ( -webkit-transform-style: preserve-3d  ))) { }</pre>

<div class="note style-wrap">
<p><strong>Note</strong> : Lorsqu'on utilise à la fois l'opérateur <code>and</code> et l'opérateur <code>or</code>, il devient nécessaire d'utiliser des parenthèses pour que l'ordre d'application des opérateurs soit défini. Si on n'utilise pas de parenthèses, la condition sera considérée comme invalide et l'ensemble de la règle @ sera ignorée.</p>
</div>

<h3 id="Syntaxe_formelle">Syntaxe formelle</h3>

<pre class="syntaxbox">{{csssyntax}}</pre>

<h2 id="Exemples">Exemples</h2>

<h3 id="Tester_la_prise_en_charge_dune_propriété_CSS_donnée">Tester la prise en charge d'une propriété CSS donnée</h3>

<pre class="brush:css;">@supports (animation-name: test) {
    … /* Du code CSS spécifique, appliqué quand les animations sont prises en charge sans préfixe */
    @keyframes { /* @supports est une règle @ qui peut inclure d'autres règles @ */
      …
    }
}
</pre>

<h3 id="Tester_la_prise_en_charge_dune_propriété_CSS_donnée_ou_dune_version_préfixée">Tester la prise en charge d'une propriété CSS donnée ou d'une version préfixée</h3>

<pre class="brush:css;">@supports ( (perspective: 10px) or (-moz-perspective: 10px) or (-webkit-perspective: 10px) or
            (-ms-perspective: 10px) or (-o-perspective: 10px) ) {
    … /* Du code CSS spécifique, appliqué lorsque les transformations 3D,
         sont prises en charge, éventuellement avec un préfixe */
}
</pre>

<h3 id="Tester_labsence_de_prise_en_charge_dune_propriété_CSS">Tester l'absence de prise en charge d'une propriété CSS</h3>

<pre class="brush:css;">@supports not ((text-align-last:justify) or (-moz-text-align-last:justify) ){
    … /* Du code CSS spécifique, appliqué pour simuler text-align-last:justify */
}</pre>

<h3 id="Tester_la_prise_en_charge_des_propriétés_personnalisées">Tester la prise en charge des propriétés personnalisées</h3>

<pre class="brush:css;">@supports (--toto: green) {
  body {
    color: --nomVar;
  }
}</pre>

<h3 id="Tester_la_prise_en_charge_dun_sélecteur">Tester la prise en charge d'un sélecteur</h3>

<p>{{SeeCompatTable}}</p>

<pre class="brush: css;">/* Cette règle ne sera pas appliquée si le navigateur */
/* ne prend pas en charge :is() */
:is(ul, ol) &gt; li {
  … /* Le CSS à utiliser lorsque :is(…) est pris en charge */
}

@supports not selector(:is(a, b)) {
  /* Que faire lorsque :is() n'est pas pris en charge */
  ul &gt; li,
  ol &gt; li {
    …
  }
}

@supports selector(:nth-child(1n of a, b)) {
  /* Cette règle doit être placée dans un bloc @supports */
  /* Sinon elle pourra être partiellement appliquée pour les */
  /* navigateurs qui ne prennent pas en charge :is(…) */
  :is(nth-child(1n of ul, ol) a,
  details &gt; summary) {
    … /* CSS appliqué quand le sélecteur :is(…) et quand la forme
         `of` pour :nth-child sont pris en charge */
  }
}
</pre>

<h2 id="Spécifications">Spécifications</h2>

<table class="standard-table">
 <thead>
  <tr>
   <th scope="col">Spécification</th>
   <th scope="col">État</th>
   <th scope="col">Commentaires</th>
  </tr>
 </thead>
 <tbody>
  <tr>
   <td>{{SpecName("CSS4 Conditional", "#at-supports", "@supports")}}</td>
   <td>{{Spec2("CSS4 Conditional")}}</td>
   <td>Ajout de la fonction <code>selector()</code>.</td>
  </tr>
  <tr>
   <td>{{SpecName("CSS3 Conditional", "#at-supports", "@supports")}}</td>
   <td>{{Spec2("CSS3 Conditional")}}</td>
   <td>Définition initiale.</td>
  </tr>
 </tbody>
</table>

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

<div class="hidden">Ce tableau de compatibilité a été généré à partir de données structurées. Si vous souhaitez contribuer à ces données, n'hésitez pas à envoyer une <em>pull request</em> sur <a href="https://github.com/mdn/browser-compat-data">https://github.com/mdn/browser-compat-data</a>.</div>

<p>{{Compat("css.at-rules.supports")}}</p>

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

<ul>
 <li>La classe CSSOM {{domxref("CSSSupportsRule")}}</li>
 <li>La méthode {{domxref("CSS.supports")}} qui permet d'effectuer les mêmes vérifications via JavaScript.</li>
</ul>