使用特性查询
特性查询是条件组规则,用于测试用户代理是否支持一个或多个 CSS 特性,例如 CSS 属性和属性值。特性查询为 Web 开发者提供了一种方法,可以测试浏览器是否支持某个特性,然后根据测试结果提供仅在该条件下运行的 CSS。在本指南中,你将学习如何使用特性查询实现渐进增强。
特性查询是使用 CSS at-rule @supports(或 @import at-rules 中的 supports() 函数)创建的。
语法
CSS 特性查询是 CSS 条件规则模块的一部分,该模块还定义了媒体查询 @media at-rule。特性查询的行为类似于媒体查询。区别在于,媒体查询是测试 Web 页面运行环境的某些方面,而特性查询是测试浏览器对 CSS 特性的支持。
特性查询由 @supports at-rule 及其后的支持条件,或 @import at-rule 声明中的 supports() 函数和声明参数组成。
/* `@supports` at-rule */
@supports <support-condition> {
/* CSS rules to apply */
}
/* `supports()` function */
@import url_to_import supports(<declaration>);
例如,如果用户代理支持 red 作为 CSS color 属性的有效值,我们可以应用一组样式或导入整个样式表
/* `@supports` at-rule */
@supports (color: red) {
/* CSS rules to apply */
}
/* `supports()` function */
@import "/css/styles.css" supports(color: red);
再举一个例子,如果你想检查浏览器是否支持 row-gap 属性,你可以编写以下特性查询。在很多情况下,你使用什么值并不重要:如果你只是想检查浏览器是否支持此属性,那么任何有效值都可以。
<div class="box">
If your browser supports the row-gap property, the border will be dashed and
text will be red.
</div>
body {
font: 1.2em / 1.5 sans-serif;
}
.box {
border: 4px solid blue;
color: blue;
padding: 1em;
}
@supports (row-gap: 10px) {
.box {
border: 4px dashed darkgreen;
color: red;
}
}
如果你正在测试特定属性的新值,属性-值对的值部分就更重要了。所有浏览器都支持 color: red:这可以追溯到 CSS1。然而,CSS 中经常会向属性添加额外的值,例如相对颜色,这些值可能不受支持。特性查询可以测试属性和值对,这意味着我们可以检测对值的支持。
在上方的 color 属性示例基础上,我们在这里检查浏览器是否支持 color: AccentColor 声明
/* `@supports` at-rule */
@supports (color: AccentColor) {
/* CSS rules to apply */
}
/* `supports()` function */
@import "/css/styles.css" supports(color: AccentColor);
在这些示例中,我们使用特性查询来检查用户代理是否支持 CSS 属性的特定值,将单个声明列在括号内。你可以测试多个属性值或不支持的情况。
测试不支持某特性
除了询问浏览器是否支持某个特性外,你还可以通过添加 not 关键字来测试相反的情况
/* `@supports` at-rule with `not` */
@supports not (property: value) {
/* CSS rules to apply */
}
如果浏览器不支持 row-gap,以下示例特性查询中的 CSS 将会运行。
<div class="box">
If your browser does not support row-gap, the content will be darkgreen with a
dashed border.
</div>
body {
font: 1.2em / 1.5 sans-serif;
}
.box {
border: 4px solid blue;
color: blue;
padding: 1em;
}
@supports not (row-gap: 10px) {
.box {
border: 4px dashed darkgreen;
color: darkgreen;
}
}
测试多个特性
你可能需要在特性查询中测试多个属性的支持情况。为此,你可以包含一个要测试的特性列表,用 and 关键字分隔
/* multiple feature `@supports` at-rule */
@supports (property1: value) and (property2: value) {
/* CSS rules to apply */
}
例如,如果你想要运行的 CSS 需要浏览器支持 CSS Shapes 和 CSS Grid,你可以创建一个规则来测试浏览器对这两个特性的支持。以下规则仅在浏览器同时支持 shape-outside: circle() 和 display: grid 时才返回 true。
<div class="box">
If your browser supports <code>display: grid</code> and
<code>shape-outside: circle()</code>, the content will be darkgreen with a
dashed border.
</div>
body {
font: 1.2em / 1.5 sans-serif;
}
.box {
border: 4px solid blue;
color: blue;
padding: 1em;
}
@supports (display: grid) and (shape-outside: circle()) {
.box {
border: 4px dashed darkgreen;
color: darkgreen;
}
}
测试多个特性中的至少一个
你还可以使用 or,仅当支持一个或多个声明时才应用 CSS
/* any feature `@supports` at-rule */
@supports (property1: value) or (property2: value) {
/* CSS rules to apply */
}
如果某个特性带有供应商前缀,这会特别有用,因为你可以测试标准属性以及任何供应商前缀。
<div class="box">
The text and border will be green if your browser supports font smoothing.
</div>
body {
font: 1.2em / 1.5 sans-serif;
}
.box {
border: 4px solid blue;
color: blue;
padding: 1em;
}
@supports (font-smooth: always) or (-webkit-font-smoothing: antialiased) {
.box {
border: 4px dashed darkgreen;
color: darkgreen;
}
}
其他特性查询选项
特性查询不限于属性-值对。你可以在特性查询中包含 font-tech()、font-format() 和 selector() 函数,以根据用户代理是否支持指定的字体技术、字体格式或选择器语法有选择地应用 CSS。
例如,selector() 函数可以用于为支持带供应商前缀的伪元素的浏览器导入样式表
/* A `selector()` query within a `supports()` function */
@import "/css/webkitShadowStyles.css"
supports(selector(::-webkit-inner-spin-button));
示例
浏览器支持测试
在此示例中,我们检查浏览器是否支持 AccentColor <system-color>,如果支持该颜色类型,则使用 display: none 将默认的“不支持”消息更改为“已支持”消息。
HTML
<p class="accentcolor">
Your browser does <span>not</span> support <code>AccentColor</code> as a color
value.
</p>
CSS
body {
font: 1.2em / 1.5 sans-serif;
}
p {
padding: 1em;
}
@supports (color: AccentColor) {
p {
color: green;
border: 2px solid;
}
span {
display: none;
}
}
@supports not (color: AccentColor) {
p {
color: red;
}
}
结果
特性查询的局限性
@supports 规则用于测试浏览器是否可以解析一个或多个属性/值对,并因此是否声称支持相关特性。如果浏览器理解这些属性/值对,它将返回一个肯定的响应。特性查询会检查声明是否被浏览器认为是有效的,但不能用于检查它是否正确支持某个特性而没有错误或违反规范。特性查询无法测试部分实现。
总结
特性查询是渐进增强网站的有用工具。它们使你能够为所有浏览器提供一个良好的解决方案,并为支持新属性和值的浏览器提供一个增强的解决方案。
你不需要使用特性查询才能开始使用新的 CSS 特性;CSS 错误处理意味着浏览器会简单地忽略它尚不识别的 CSS。然而,特性查询是回退声明的有用替代方案,并且能够一次编写代码,最终在所有地方都能得到支持。