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
|
---
title: '@supports'
slug: Web/CSS/@supports
tags:
- '@规则'
- At-rule
- CSS
- Web
- 参考
- 支持
translation_of: Web/CSS/@supports
---
<div>{{CSSRef}}</div>
<p><strong><code>@supports</code></strong> <a href="/en-US/docs/Web/CSS">CSS</a> <a href="/en-US/docs/Web/CSS/At-rule">at-rule</a> 您可以指定依赖于浏览器中的一个或多个特定的CSS功能的支持声明。这被称为<em>特性查询</em>。该规则可以放在代码的顶层,也可以嵌套在任何其他<a href="/en-US/docs/Web/CSS/At-rule#Conditional_group_rules">条件组规则中</a>。</p>
<pre class="brush: css; no-line-numbers notranslate">@supports (display: grid) {
div {
display: grid;
}
}</pre>
<pre class="brush: css; no-line-numbers notranslate">@supports not (display: grid) {
div {
float: right;
}
}</pre>
<p>在 JavaScript 中,可以通过 CSS 对象模型接口 {{DOMxRef("CSSSupportsRule")}} 来访问 <code>@supports</code>。</p>
<h2 id="语法">语法</h2>
<p><code>@supports</code> at-rule 由一组样式声明和一条<em>支持条件</em>构成。支持条件由一条或多条使用 逻辑与(<code>and</code>)、逻辑或(<code>or</code>)、逻辑非(<code>not</code>)结合的名称-值对(name-value pair)组成。可以使用圆括号调整操作符的优先级。</p>
<h3 id="声明语法">声明语法</h3>
<p>最基本的支持条件就是 CSS 声明,也就是一个 CSS 属性后跟一个值,中间用冒号分开。如果 {{cssxref("transform-origin")}} 的实现语法认为 <code>5% 5%</code> 是有效的值,则下面的表达式会返回 true。</p>
<pre class="brush: css notranslate">@supports (transform-origin: 5% 5%) {}</pre>
<h3 id="函数语法">函数语法</h3>
<p>第二种基本支持条件是支持函数,几乎所有浏览器都支持这种语法,但函数本身仍在标准化进程中。</p>
<h4 id="selector" name="selector()"><code>selector()</code> {{Experimental_Inline}}</h4>
<p>测试浏览器是否支持经过测试的选择器语法。如果浏览器支持<a href="/en-US/docs/Web/CSS/Child_combinator">子组合器</a>,则以下示例返回true:</p>
<pre class="brush: css notranslate">@supports selector(A > B) {}</pre>
<h3 id="not_操作符"><code>not</code> 操作符</h3>
<p>将 <code>not</code> 操作符放在任何表达式之前就能否定一条表达式。如果 {{CSSxRef("transform-origin")}} 的实现语法认为 <code>10em 10em 10em</code> 是<strong>无效</strong>的,则下面的表达式会返回 true。</p>
<pre class="brush: css notranslate">@supports not (transform-origin: 10em 10em 10em) {}</pre>
<p>和其他操作符一样,<code>not</code> 操作符可以应用在任意复杂度的表达式上。下面的几个例子中都是合法的表达式:</p>
<pre class="brush: css notranslate">@supports not (not (transform-origin: 2px)) {}
@supports (display: grid) and (not (display: inline-grid)) {}</pre>
<div class="note style-wrap">
<p><strong>注意:</strong>如果 <code>not</code> 操作符位于表达式的最外层,则没有必要使用圆括号将它括起来。但如果要将该表达式与其他表达式连接起来使用,比如 <code>and</code> 和 <code>or</code>,则需要外面的圆括号。</p>
</div>
<h3 id="and_操作符"><code>and</code> 操作符</h3>
<p><code>and</code> 操作符用来将两个原始的表达式做逻辑与后生成一个新的表达式,如果两个原始表达式的值<strong>都为真</strong>,则生成的表达式也为真。在下例中,当且仅当两个原始表达式同时为真时,整个表达式才为真:</p>
<pre class="brush: css notranslate">@supports (display: table-cell) and (display: list-item) {}</pre>
<p>可以将多个合取词并置而不需要更多的括号。以下两者都是等效的:</p>
<pre class="brush: css notranslate">@supports (display: table-cell) and (display: list-item) and (display:run-in) {}
@supports (display: table-cell) and ((display: list-item) and (display:run-in)) {}</pre>
<h3 id="or_操作符"><code>or</code> 操作符</h3>
<p><code>or</code> 操作符用来将两个原始的表达式做逻辑或后生成一个新的表达式,如果两个原始表达式的值<strong>有一个或者都</strong>为真,则生成的表达式也为真。在下例中,当两个原始表达式中至少有一个为真时,整个表达式才为真:</p>
<pre class="brush: css notranslate">@supports (transform-style: preserve) or (-moz-transform-style: preserve) {}</pre>
<p>可以将多个析取词并置而不需要更多的括号。以下两者都是等效的:</p>
<pre class="brush: css notranslate">@supports (transform-style: preserve) or (-moz-transform-style: preserve) or
(-o-transform-style: preserve) or (-webkit-transform-style: preserve) {}
@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="blockIndicator note">
<p><strong>注意</strong>:在使用 <code>and</code> 和 <code>or</code> 操作符时,如果是为了定义多个表达式的执行顺序,则必须使用圆括号。如果不这样做的话,该条件就是无效的,会导致整个 at-rule 失效。</p>
</div>
<h3 id="形式化语法">形式化语法</h3>
{{CSSSyntax}}
<h2 id="示例">示例</h2>
<h3 id="检测是否支持指定的_CSS_属性">检测是否支持指定的 CSS 属性</h3>
<pre class="brush:css; notranslate">@supports (animation-name: test) {
… /* 如果支持不带前缀的animation-name,则下面指定的CSS会生效 */
@keyframes { /* @supports是一个CSS条件组at-rule,它可以包含其他相关的at-rules */
…
}
}
</pre>
<h3 id="检测是否支持指定的CSS属性或者其带前缀版本">检测是否支持指定的CSS属性或者其带前缀版本</h3>
<pre class="brush:css; notranslate">@supports ( (perspective: 10px) or (-moz-perspective: 10px) or (-webkit-perspective: 10px) or
(-ms-perspective: 10px) or (-o-perspective: 10px) ) {
… /* 如果支持不带前缀以及带前缀的perspective属性,则下面指定的CSS会生效 */
}
</pre>
<h3 id="检测是否不支持指定的CSS属性">检测是否不支持指定的CSS属性</h3>
<pre class="brush:css; notranslate">@supports ( not ((text-align-last:justify) or (-moz-text-align-last:justify) ){
… /* 这里的CSS代码用来模拟text-align-last:justify */
}</pre>
<h3 id="测试是否支持自定义属性">测试是否支持自定义属性</h3>
<pre class="brush: css notranslate">@supports (--foo: green) {
body {
color: var(--varName);
}
}</pre>
<h3 id="Testing_for_the_support_of_a_selector" name="Testing_for_the_support_of_a_selector">测试是否支持选择器 (eg. {{CSSxRef(":is", ":is()")}})</h3>
<p>{{SeeCompatTable}}</p>
<pre class="brush: css highlight[6, 14] notranslate">/* 这条 CSS 规则在不支持 is:() 的浏览器中无效 */
:is(ul, ol) > li {
… /* 支持 :is(...) 选择器时,这里的 CSS 生效 */
}
@supports not selector(:is(a, b)) {
/* 不支持 :is() 时的备选方案 */
ul > li,
ol > li {
… /* 以上给不支持 :is(...) 的浏览器展开了 CSS 选择器规则 */
}
}
@supports selector(:nth-child(1n of a, b)) {
/* 这条规则需要内嵌在 @supports 块内。
否则该规则在支持 :nth-child(…)但不支持其内的 `of` 参数的浏览器中,
只有部分生效 */
:is(:nth-child(1n of ul, ol) a,
details > summary) {
… /* 当:is(...) 选择器以及 :nth-child(…) 的 `of` 参数都支持时,
这里的 CSS 会生效 */
}
}
</pre>
<h2 id="规范">规范</h2>
<table class="standard-table">
<thead>
<tr>
<th scope="col">规范</th>
<th scope="col">状态</th>
<th scope="col">备注</th>
</tr>
</thead>
<tbody>
<tr>
<td>{{SpecName("CSS4 Conditional", "#at-supports-ext", "@supports")}}</td>
<td>{{Spec2("CSS4 Conditional")}}</td>
<td>Adds the <code>selector()</code> function.</td>
</tr>
<tr>
<td>{{SpecName("CSS3 Conditional", "#at-supports", "@supports")}}</td>
<td>{{Spec2("CSS3 Conditional")}}</td>
<td>Initial definition.</td>
</tr>
</tbody>
</table>
<h2 id="浏览器兼容性">浏览器兼容性</h2>
<p>{{Compat("css.at-rules.supports")}}</p>
<h2 id="参见">参见</h2>
<ul>
<li><a href="/zh-CN/docs/Web/CSS/CSS_Conditional_Rules/Using_Feature_Queries">Using feature queries</a></li>
<li>The CSSOM class {{DOMxRef("CSSSupportsRule")}}, and the {{DOMxRef("CSS.supports()")}} method that allows the same check to be performed via JavaScript.</li>
</ul>
|