CSS中 特性查询(@supports)详解及使用

206

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第7天,点击查看活动详情

1. 简介

CSS中的 @supports 用于检测浏览器是否支持 CSS 的某个属性。其实就是条件判断,如果支持某个属性可以写一套样式,如果不支持某个属性,可以提供另外一套样式作为替补。可以放在代码的顶层,也可以嵌套在任何其他条件组规则中。

语法

@supports 规则由一组样式声明和一条支持条件构成。支持条件由一条或多条使用 逻辑与(and)、逻辑或(or)、逻辑非(not)结合的名称 - 值对(name-value pair)组成。可以使用圆括号调整操作符的优先级。

声明语法

最基本的支持条件就是 CSS 声明,也就是一个 CSS 属性后跟一个值,中间用冒号分开。

@supports(prop:value) {
  /* more styles */
}

如:检查是否支持 dispaly: flex

@supports (display: flex) {
  div {
    display: flex;
  }
}

函数语法

第二种基本支持条件是支持函数,几乎所有浏览器都支持这种语法,但函数本身仍在标准化进程中。 测试浏览器是否支持经过测试的选择器语法。如果浏览器支持子组合器,则以下示例返回 true。

@supports selector(A > B) {}

2. 操作符

not 操作符

将 not 操作符放在任何表达式之前就能否定一条表达式。

/* 如果浏览器不支持display:flex属性的话,那么div的样式就是 float: right */
@supports not (display: flex) { 
  div {    
    float: right;  
  }
}

和其他操作符一样,not 操作符可以应用在任意复杂度的表达式上。

@supports not (not (transform-origin: 2px)) {}
@supports (display: grid) and (not (display: inline-grid)) {}

注意: 如果 not 操作符位于表达式的最外层,则没有必要使用圆括号将它括起来。但如果要将该表达式与其他表达式连接起来使用,比如 and 和 or,则需要外面的圆括号。

and 操作符

and 操作符用来将两个原始的表达式做逻辑与后生成一个新的表达式,如果两个原始表达式的值都为真,则生成的表达式也为真。

/* 如果浏览器支持 display:flex 和 box-shadow 的属性,就执行里面自己的样式 */
@supports (display: flex) and ( box-shadow: 2px 2px 2px black ) { }

可以将多个合取词并置而不需要更多的括号。以下两者都是等效的:

@supports (display: table-cell) and (display: list-item) and (display:run-in) {}
@supports (display: table-cell) and ((display: list-item) and (display:run-in)) {}

or 操作符

or 操作符用来将两个原始的表达式做逻辑或后生成一个新的表达式,如果两个原始表达式的值有一个或者都为真,则生成的表达式也为真。

/* 如果浏览器支持其中一个,就可执行里面自己的样式 */
@supports (display: -webkit-flex) or (display: -moz-flex) or(display: flex) {
  /*自己的样式 */
}

可以将多个析取词并置而不需要更多的括号。以下两者都是等效的:

@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))) {}

注意: 在使用 and 和 or 操作符时,如果是为了定义多个表达式的执行顺序,则必须使用圆括号。如果不这样做的话,该条件就是无效的,会导致整个规则失效。

@Supports 使用

@supports 的用途是将一组较旧的样式设置为备份,然后取消这些样式并在支持给定属性的情况下进行增强。 @supports 的一个优秀用例是布局。一些边缘浏览器现在提供对 flexbox 的支持,而其他浏览器则落后。

.wrap{
  float: right;
}

@supports (display: -webkit-flex) or (display: -moz-flex) or (display: flex) {
  .wrap{
    display: -webkit-flex;
    display: -moz-flex;
    display: flex;
    float: none;
  }
}

3. CSS.supports()

CSS @supports 对应的 JavaScript 是 window.CSS.supports。

CSS.supports() 静态方法返回一个Boolean 值,用来校验浏览器是否支持一个给定的 CSS 特性。

语法

boolValue = CSS.supports(propertyName, value);
boolValue = CSS.supports(supportCondition);
参数
第一种用来检验浏览器对于一对“属性 - 属性值”的支持:
  propertyName  要检查的 CSS 属性名称
  value  要检查的 CSS 属性值
第二种语法需要一个匹配@supports条件的参数:
  supportCondition  检查条件

eg

const supportsFlex = CSS.supports('display', 'flex');
const flexAndAppearance = CSS.supports('(display: flex) and (-webkit-appearance: caret)')

在使用 supports 的 JavaScript 方法之前,首先检测功能是很重要的。Opera 使用了一个不同的方法名,因此会抛出一些东西:

const supportsCSS = !!((window.CSS && window.CSS.supports) || window.supportsCSS || false)

4. 浏览器兼容性

在这里插入图片描述