说说CSS中的@supports
CSS中的@supports
属性已经不是新东西了,只不过一直以来,大家碍于浏览器对其支持度不强,而无人问冿。这两天看到两篇新文单都是介绍@supports
。其中一篇是介绍怎么使用@supports
来查询CSS的新特性,另外一篇是如何使用@supports
来改变你的生活。
- How to use CSS Feature Queries by @Abbey Fitzgerald
@supports
will change your life by @CHARLOTTE JACKSON
今天也继续来说说这个@supports
属性。
@supports是什么
@supports
是CSS条件查询规范(CSS3 Conditional Rules Specification)中属性之一,CSS中条件查询除了今天要说的@supports
之外,还有大家较为熟悉的媒体查询(@media
)和@viewport
。
@supports作用是什么
从@Abbey Fitzgerald的《How to use CSS Feature Queries》一文的标题来看,就大概知道@supports
是用来查询CSS的新特性的。那么查询CSS的新特性有什么用处呢?或许你知道新出现的CSS特性,但又担心浏览器不支持,从而又不敢使用。很多时候就算是使用了CSS的新特,达到自己需要的效果,但为了让自己的项目给用户带来更好的体验,希望在一些不支持新特性的浏览器做一些降级方案。那么这个时候@supports
功效或者说作用就出来了。
从这一点而言,CSS的@supports
作用就是用来查询浏览器是否支持CSS的特性。
对于Web前端开发的同学,对Modernizr这个JavaScript库并不会陌生,一直以来都是依赖于这个库帮助大家做一些降级处理。那么有了CSS的@supports
,将可以抛弃这个JavaScript库。先来简单的看看一个小示例:
body {
width: 100vw;
height: 100vh;
background-blend-mode: hue;
background-image:linear-gradient(to right, rgb(166, 80, 80), rgb(139, 0, 0)), url(//c8.staticflickr.com/4/3654/3485478215_19a06ca23c_b.jpg);
background-repeat:repeat, no-repeat;
background-position: center;
background-size: cover;
}
早期,我们依赖Modernizr库,需要这样处理:
.no-background-blend-mode {
background-image:url(//c8.staticflickr.com/4/3654/3485478215_19a06ca23c_b.jpg);
}
而现在,我们只需要这样做即可:
body {
width: 100vw;
height: 100vh;
background: url(//c8.staticflickr.com/4/3654/3485478215_19a06ca23c_b.jpg) no-repeat center;
background-size: cover;
}
@supports (background-blend-mode: hue) {
body {
background-blend-mode: hue;
background-image:linear-gradient(to right, rgb(166, 80, 80), rgb(139, 0, 0)), url(//c8.staticflickr.com/4/3654/3485478215_19a06ca23c_b.jpg);
}
}
对于支持 CSS的background-blend-mode
属性的Firefox和Chrome浏览器,你可以看到上面的效果,而对于不支持的Safari浏览器,你看到的效果如下图看示:
上面简单的示例,再次证明CSS的@supports
能帮助浏览器很好的检测是否支持CSS的属性,而且能更好的帮助我们对自己的效果做优雅的降级处理。
@supports的兼容性
当你看到这里的时候,你或许会担心。@supports
也是CSS的新特性,如果浏览器对这个属性不支持的话,上面的一切都是空谈了吗?原则上是这样的,但值得庆幸的时,到目前为止,现代浏览器除了IE系列之外,都对@supports
有很强的支持性,甚至在移动设备上支持度也非常的好。
如何使用@supports
对于@supports
的使用,其实很简单,早期在《CSS3条件判断:@supports
》一文中有详细的介绍怎么使用@supports
。这里简单的回顾一下怎么使用。
最常见的方式:
@supports (property: value) {
element {
property: value;
}
}
基中property: value
是@supports
用来判断的条件语块。如果浏览器支持property: value
,将会返回true
,也就是说浏览器将会渲染element {property:value}
样式块,如果不支持,则会返回false
,将不会渲染这里的样式。当然对于不支持条件语块,还可以通过 not()
语块来执行:
@supports not (property: value) {
element {
property: value;
}
}
来看一个简单示例:
<article class="artwork">
<img src="myimg.jpg" alt="cityscape">
</article>
结构很简单,主要来看下面这段CSS:
@supports (mix-blend-mode: overlay) {
.artwork img {
mix-blend-mode: overlay;
}
}
@supports not(mix-blend-mode: overlay) {
.artwork img {
opacity: 0.5;
}
}
上面的示例是说,如果浏览器支持mix-blend-mode:overlay
,将会执行@supports (){...}
,如果不支持则会执行@supports not() {...}
。支持的浏览器能看到的效果如下:
不支持的浏览器,看到的效果则是图片有50%
的透明度。
另外,在使用@supports
时,条件语句块一定要放到()
里面,如果不放在这里面的话,将会失效(错语语法)。比如:
// 无效的@supports写法
@supports mix-blend-mode:overlay {
.artwork img {
mix-blend-mode: overlay;
}
}
// 有效的@supports写法
@supports (mix-blend-mode:overlay) {
.artwork img {
mix-blend-mode: overlay;
}
}
上面的示例展示的都是单个条件块的,其实还可以支持多个条件块。它支持与(and
)、或(or
)和非(not
):
and
@supports (property1: value1) and (property2: value2) {
element {
property1: value1;
property2: value2;
}
}
条件都成立,才会返回true
,浏览器才会渲染。只要其中有一个条件不符合,都不会渲染。
or
@supports (property1: value1) or (-webkit-property1: value1) {
element {
-webkit-property1: value1;
property1: value1;
}
}
多个条件中只要有一个条件成立,就会返回true
。所以只要满足其中一个条件,浏览器就会渲染。只有所有都件都不满足,才会返回false
,浏览器不渲染。
not
前面也简单说过了,当在@supports
中使用not
时,表示浏览器不支持条件块中的条件,对应的样式将会渲染。
@supports not(property: value) {
element {
...
}
}
在实际使用当中,还可以把or
和and
混合一起使用:
@supports ((property1: value1) or
(-webkit-property1: value1)) and
(property2: value2) {
element {
-webkit-property1: value1;
property1: value1;
property2: value2;
}
}
@supports使用示例
如果坚持阅读到这里的话,对于@supports
如何使用并不是一件难事了。接下来,还是来看两个简单的示例。
先来看一个有关于CSS的Shapes方面的案例。CSS中的Shapes可以帮且我们排版不再局限于矩形块,可以使用各种图形。但支持该属性的浏览器很少。拿他来做@supports
将是一个很好的示例:
.shape{
width: 20em;
height: 20em;
float: left;
margin: 0.25em 2em 1em 0;
}
@supports (shape-outside: circle()) {
.shape {
shape-outside: circle(50%);
border-radius: 25em;
}
}
如果你的浏览器支持CSS Shapes的属性,那么你看到的效果是下图左侧的样子,否则看到的是右侧的样子:
再来看一个首字下沉的案例,我们以前做首字下沉一般都是这样来做:
p::first-letter {
float: left;
font-size: 5em;
line-height: 1;
font-weight: bold;
margin-right: .2em;
color: #00FFFF;
font-family: serif;
}
但在CSS中有一个initial-letter
属性,可以更轻松的实现首字下沉的效果。只是目前浏览器支持度非常非常的少。那么使用@supports
,我们可以这样来处理:
@supports (initial-letter: 5) or (-webkit-initial-letter: 5) {
p::first-letter {
-webkit-initial-letter: 5;
initial-letter: 5;
color: #00FFFF;
font-weight: bold;
margin-right: 0.5em;
font-family: serif;
}
}
一旦有一天,浏览器支持了initial-letter
属性,你的浏览器将会渲染@supports
中的代码块,实现首字下沉效果。
CSS.supports()接口
到今天为止有一个supports()
函数可以帮助我们更好的利用CSS特性查询功能。在使用当中,可以通过两种方式来调用CSS.supports()
。
// 第一种方式
CSS.supports('mix-blend-mode', 'overlay'); // true
// 第二种方式
CSS.supports('(mix-blend-mode: overlay)'); // true
如果浏览器支持supports()
中的条件则返回true
,否则返回false
。
CSS.supports('(initial-letter: 5)'); //false
这样一来,就可以很容易根据.supports()
来做一个判断,做一些事情。比如说,如果浏览器支持mix-blend-mode: luminosity
我就给目标元素添加luminosity-blend
类名,否则就给目标元素添加noluminosity
类名。
var init = function() {
var test = CSS.supports('mix-blend-mode', 'luminosity'),
targetElement = document.querySelector('img');
if (test) {
targetElement.classList.add('luminosity-blend');
} else {
targetElement.classList.add('noluminosity');
}
};
window.addEventListener('DOMContentLoaded', init, false);
比如下面这个DEMO:
总结
在这篇文章中,简单的了解了如何使用CSS的条件属性@supports
以及CSS.supports()
方法怎么对CSS特性做查询,用来判断浏览器是否支持这些最新的属性。如果支持将返回的是一个true
,将会渲染对应的样式;如果不支持,则将返回false
,将不会渲染对应的样式。
虽然CSS的@supports
得到了很好的支持,但如果在项目中使用@supports
的话,建议还是在项目中添加相关的polyfill,比如@Han Lin Yap的css-supports.js
或者@termi的CSS.supports
。