什么是 CSS 特性检测?我们知道,前端技术日新月异的今天,各种新技术新属性层出不穷。在 CSS 层面亦不例外。

一些新属性能极大提升用户体验以及减少工程师的工作量,并且在当下的前端氛围下:

  • 很多实验性功能未成为标准却被大量使用;
  • 需要兼容多终端,多浏览器,而各浏览器对某一新功能的实现表现的天差地别;

所以有了优雅降级和渐进增强的说法,在这种背景下,又想使用新的技术给用户提供更好的体验,又想做好回退机制保证低版本终端用户的基本体验,CSS 特性检测就应运而生了。

CSS 特性检测就是针对不同浏览器终端,判断当前浏览器对某个特性是否支持。运用 CSS 特性检测,我们可以在支持当前特性的浏览器环境下使用新的技术,而不支持的则做出某些回退机制。

本文将主要介绍两种 CSS 特性检测的方式:

  1. @supports
  2. modernizr

及使用 javascript 进行特性检测的原理

 

CSS @supports

传统的 CSS 特性检测都是通过 javascript 实现的,但是未来,原生 CSS 即可实现。

CSS @supports 通过 CSS 语法来实现特性检测,并在内部 CSS 区块中写入如果特性检测通过希望实现的 CSS 语句。

语法:

@supports <supports_condition> {
    /* specific rules */
}

举个例子:

div {
	position: fixed;
}

@supports (position:sticky) {
    div {
        position:sticky;
    }
}

上面的例子中,position: sticky 是 position 的一个新属性,用于实现黏性布局,可以轻松实现一些以往需要 javascript 才能实现的布局(戳我了解详情),但是目前只有在 -webkit- 内核下才得到支持。

上面的写法,首先定义了 div 的 position: fixed ,紧接着下面一句 @supports (position:sticky) 则是特性检测括号内的内容,如果当前浏览器支持 @supports 语法,并且支持 position:sticky 语法,那么 div 的 则会被设置为 position:sticky 。

我们可以看到,@supports 语法的核心就在于这一句:@supports (...) { } ,括号内是一个 CSS 表达式,如果浏览器判断括号内的表达式合法,那么接下来就会去渲染括号内的 CSS 表达式。除了这种最常规的用法,还可以配合其他几个关键字:

 

@supports not && @supports and && @supports or

@supports not -- 非

not 操作符可以放在任何表达式的前面来产生一个新的表达式,新的表达式为原表达式的值的否定。看个例子:

@supports not (background: linear-gradient(90deg, red, yellow)) {
    div {
        background: red;
    }
}

因为添加了 not 关键字,所以与上面第一个例子相反,这里如果检测到浏览器不支持线性渐变 background: linear-gradient(90deg, red, yellow) 的语法,则将 div 的颜色设置为红色 background: red 。

 

@supports and -- 与

这个也好理解,多重判断,类似 javascript 的 && 运算符符。用 and 操作符连接两个原始的表达式。只有两个原始表达式的值都为真,生成的表达式才为真,反之为假。

当然,and 可以连接任意多个表达式看个例子:

p {
    overflow: hidden;
    text-overflow: ellipsis;
}
@supports (display:-webkit-box) and (-webkit-line-clamp:2) and (-webkit-box-orient:vertical) {
    p {
        display: -webkit-box;
        -webkit-line-clamp: 2;
        -webkit-box-orient: vertical;
    }
}

上面同时,检测 @supports (display:-webkit-box) and (-webkit-line-clamp:2) and (-webkit-box-orient:vertical) 了三个语法,如果同时支持,则设定三个 CSS 规则。这三个语法必须同时得到浏览器的支持,如果表达式为真,则可以用于实现多行省略效果:

Demo戳我