CSS3条件判断——@supports

CSS3条件判断,听起来“不明觉厉”,若是你对CSS稍为熟悉一点的话,你会发现CSS中的“@media”就是条件判断之一。是的,在CSS3的条件判断规范文档中包含了两个部分,其一是“@media”规则,主要用来“根据媒体属性区分样式表”(特别是在Responsive设计中,发挥的做用更是强大);其二是“@supports”规则,主要用来代替前面经常使用的Modernizr库,在不支持CSS3的浏览器下实现渐进加强式设计。换句话来讲,@supports可让咱们在不支持CSS3属性的浏览器下配上单独的样式,看起来很强大,那具体如何使用呢?咱们今天一块儿简单的来学习一下:javascript

@supports起源

 

众所周知,不一样的浏览器(不论是现代浏览器仍是老版本的IE浏览器)对Web页面的解析都是不同,为了让Web页面在这些浏览器下渲染达到基本一致的状况,给用户更好的体验,咱们必须为他们写不一样的样式代码。css

不一样特征的检测方法咱们早期都是依赖于javascript来检测,后来经过第三方js库Modernizr来完成。但这样真的有用吗?除了要懂怎么检测以外,咱们还须要了解更多的浏览器解析机制,这样一来对于咱们前端人员来讲就是“没办法”。还好CSS3 Conditional Rules Module Level 3推出了“@supports”条件判断规则,它充许咱们能够根据浏览器对CSS特性的支持状况来定义不一样的样式。这对咱们来讲是很是重要。html

@supports语法规则

要想更好的使用@supports,咱们有必要先从其语法开始入手,只有知道了怎么用,咱们才能更好的去用。前端

@supports <条件规则> { /* 特殊样式规则 */ } 

@supports中的“条件规则”能够声明一条或者几个由不一样的逻辑运算符相结合的声明(好比说,非(not),或(or),与(and)等)。并且还可使用括号来肯定其操做的优先级关系。java

最简单的条件表达式是一个CSS声明,一个CSS属性名,后面加上一个属性值,属性名与属性值以前用分号隔开,好比:css3

(display:flex) 

咱们来看一个简单的例子:web

@supports (display:flex) {
  section { display: flex } ... } 

上面这段代码的意思是:若是浏览器支持“display:flex”属性,那么在“section”元素上就运用“display:flex”样式。浏览器

@supports还能够根据不一样的逻辑运算符相结合,具备不一样的语法规则,接下来咱们一块儿来细化一下@supports的语法规则,以及使用细节。ruby

基本属性的检查

正如前面的示例同样,你可使用CSS的基本属性来进行检查:bash

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

这种是@supports最基本的使用规则。

not逻辑声明——排除

@supports可使用not逻辑声明,主要做用是,在不支持新特性时,能够提供备用样式。换过来也能够理解,若是你的浏览器不支持@supports条件判断中的样式,你能够经过@supports为浏览器提供一种备用样式,如:

@supports not (display: flex){
  #container div{float:left;} } 

上面的代码表示的是,若是你的浏览器不支持“display:flex”属性,那么你可使用“float:left”来替代。

and逻辑声明——联合(与)

@supports的条件判断中也可使用“and”逻辑声明。用来判断是否支持多个属性。例如:

@supports (column-width: 20rem) and (column-span: all) { div { column-width: 20rem } div h2 { column-span: all } div h2 + p { margin-top: 0; } ... } 

上面的代码表示的是,若是你的浏览器同时支持“column-width:20rem”和“column-span:all”两个条件,浏览器将会调用下面的样式:

div { column-width: 20rem } div h2 { column-span: all } div h2 + p { margin-top: 0; } ... 

反之,若是不一样时支持这两个条件,那么浏览器将不会调用这部分样式。

注:多个and边接并不须要使用括号:

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

or逻辑声明——or(或)

@supports除了“not”和“and”逻辑声明以外,还可使用“or”逻辑声明。主要用来判断浏览器是否支持某一CSS特性。也就是说,可使用“or”逻辑声明,同时专声明多个条件,只要其中一个条件成立就会启用@supports中的样式:

@supports (display: -webkit-flex) or (display: -moz-flex) or (display: flex) {
  section { display: -webkit-flex; display: -moz-flex; display: flex; … } } 

上面的例子是@supports中“or”运用场景之一。flex在opera和IE10中不须要前缀,而在其余的现代浏览器中仍是须要浏览器厂商的前缀,经过上面的使得,浏览器支持“flex”属性就会调用下面的样式:

section { display: -webkit-flex; display: -moz-flex; display: flex; … } 

上面是有关于@supports的几种语法的使用规则介绍,在使用这几种规则时,有几点须要特别注意:

“or”和“and”混用

在@supports中“or”和“and”混用时,必须使用括号()来区分其优先级:

@supports ((transition-property: color) or (animation-name: foo)) and (transform: rotate(10deg)) { // ... } @supports (transition-property: color) or ((animation-name: foo) and (transform: rotate(10deg))) { // ... } 

之前两种写法优先级计算并不同。

只有一条表达式时必须用括号()

在@supports中,若是条件判断表达式只有一条,那么这条表达式必须使用括号包起来:

@supports (display: flex) { // ... } 

浏览器兼容性

经过上面对@supports的语法介绍,你们都知道这个属性对于作一些渐进增长式样式,或者浏览器的兼容性特别方便,但浏览器自己对其的兼容性如何呢?咱们一块儿来看Caniuse.com提供的兼容性表格:

@supports

虽然目前仅有两个浏览器支持,但咱们应该相信,这将是一种趋势,早晚其余浏览器也会跟上的,最终被支持。

CSS.supports

在javascript中支持css的@supports的写法是“window.CSS.supports”。CSS.supports规范提供了两种写法。第一种方法包括了两个参数,一个是属性,另外一个是属性值:

var supportsFlex = CSS.supports("display", "flex"); 

第二种写法简单的提供整个字符串的写法:

var supportsFlexAndAppearance = CSS.supports("(display: flex) and (-webkit-appearance: caret)"); 

在使用javascript的supports,最重要的是先检测他的特性,Opera浏览器使用不一样的名称方法:

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

使用@supports来替代Modernizr库?

众说周知,早前都是使用Modernizr库来作一些浏览器对属性的检测,从而判断浏览器是否支持这些特性。自从@supports推出后,Modernizr真的是老了吗?他们之间有什么优点呢?

@supports和Modernizr相比,在速度、性能和功能都要比Modernizr强。为何这么说呢?由于@supports采用浏览器本地方法实现,这样速度会更快、效率也会更高;另外Modernizr须要依赖于js库,而@supports避免了引入js库,减小了http的请求量和服务器流量,而且让开发更简单快捷;并且@support支持多种逻辑条件样式判断,能够很好的知足多种需求。

但话又说回来,若是你的浏览器不支持@supports,目前来讲你仍是须要依赖于Modernizr来作一些检测。其实Paul Irish说过,Modernizr也在计划,将来将使用@supports来替代自身的检测方法。

能使用@supports?

无论使用@supports或者说使用Modernizr来作一些渐进加强式的处理,咱们都避免不了写多个样式,这样从而也增长了样式的体积,但惟的一好处是,能减小对文件的请求,加强了用户对产品的体验感。

所以,如今对你来讲是否使用@supports,正确的是在使用@supports以前先检测是滞支持CSS.supports()和@supports,若是检测出不支持,在加载Modernizr,这样你的页面就会有一个很好的兼容性。下面是实现的方法:

if ( !(window.supportsCSS || (window.CSS && window.CSS.supports) )) load_modernizr()	

@supports使用

在大多数状况之下,使用@supports都是设置一个老的样式作为备份,而后新的样式写在@supports中用来支持现代浏览器。例如“flex”弹性布局,到目前有下些版本浏览器不支持,但你使用这个属性,为了让其余的浏览器不至于布局混乱,你能够像下面这样写:

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

上面仅是一个简单的例子,咱们来看看Chris Mills在《Native CSS feature detection via the @supports rule》提供的一个案例

这个例子,是Chris Mills早前写的一个旋转案例,为了兼容其余浏览器的旋转效果,明前是使用Modernizr来实现的(案例),案例效果以下所示:

@supports

上图是在浏览器支持3D旋转,卡片翻转的一个很好的动画。

@supports

上图是在浏览器不支持3D转换但支持2D转换,贺卡的正面旋转和动画,底面显示出来。

@supports

上图是在浏览器不支持3D或2D转换,贺卡的正面就移动左边,显示后面没有动画。

接下来,咱们来看看使用@supports修改后的实现方法。

HTML结构

<div id="wrapper" tabindex="0"> <div id="inner-wrapper"> <div id="front"> <hgroup> <h1>Chris Mills</h1> <h2>Heavy metal web designer</h2> </hgroup> <p>Available for copy writing, web design, drums, guitar and bad jokes.</p> <p>Please contact me on...</p> </div> <div id="back"> <ul> <li><strong>Email:</strong> cmills@opera.com</li> <li><strong>Phone:</strong> +44 123 456 7890</li> <li><strong>Twitter:</strong> @chrisdavidmills</li> </ul> </div> </div> </div> 

结构就很少说了,并非很复杂,接下来主要看CSS部分。

CSS代码

卡片基本样式:

/* 自定义体体、导入字体 */

@font-face { font-family: 'DeutschGothicNormal'; src: url('fonts/deutsch-webfont.eot'); src: url('fonts/deutsch-webfont.eot?#iefix') format('embedded-opentype'), url('fonts/deutsch-webfont.woff') format('woff'), url('fonts/deutsch-webfont.ttf') format('truetype'), url('fonts/deutsch-webfont.svg#DeutschGothicNormal') format('svg'); font-weight: normal; font-style: normal; } @font-face { font-family: 'SFArcheryBlackSCRegular'; src: url('fonts/sf_archery_black_sc-webfont.eot'); src: url('fonts/sf_archery_black_sc-webfont.eot?#iefix') format('embedded-opentype'), url('fonts/sf_archery_black_sc-webfont.woff') format('woff'), url('fonts/sf_archery_black_sc-webfont.ttf') format('truetype'), url('fonts/sf_archery_black_sc-webfont.svg#SFArcheryBlackSCRegular') format('svg'); font-weight: normal; font-style: normal; } /* 基本的布局样式*/ body { height: 800px; font-size: 62.5%; background-color: #eee; } html,body,h1,h2,p { margin: 0; padding: 0; } footer { position: absolute; bottom: 0; } #inner-wrapper { width: 85.6mm; height: 53.98mm; margin: 120px auto; margin: 12rem auto; position: relative; -webkit-transition: 1.5s all; -moz-transition: 1.5s all; -ms-transition: 1.5s all; -o-transition: 1.5s all; transition: 1.5s all; -webkit-transform-style: preserve-3d; -moz-transform-style: preserve-3d; -ms-transform-style: preserve-3d; -o-transform-style: preserve-3d; transform-style: preserve-3d; } #front, #back { position: absolute; top: 0; left: 0; width: 75.6mm; height: 43.98mm; padding: 5mm; box-shadow: 5px 5px 10px rgba(0,0,0,0.7); background: #FF3500; background: -webkit-linear-gradient(top,rgba(0,0,0,0),rgba(0,0,0,0.6)), -webkit-linear-gradient(45deg,#FF3500 37.7mm,#FF7600 37.8mm,#FF7600 59.7mm,#FF3500 59.8mm); background: -moz-linear-gradient(top,rgba(0,0,0,0),rgba(0,0,0,0.6)), -moz-linear-gradient(45deg,#FF3500 37.7mm,#FF7600 37.8mm,#FF7600 59.7mm,#FF3500 59.8mm); background: -ms-linear-gradient(top,rgba(0,0,0,0),rgba(0,0,0,0.6)), -ms-linear-gradient(45deg,#FF3500 37.7mm,#FF7600 37.8mm,#FF7600 59.7mm,#FF3500 59.8mm); background: -o-linear-gradient(top,rgba(0,0,0,0),rgba(0,0,0,0.6)), -o-linear-gradient(45deg,#FF3500 37.7mm,#FF7600 37.8mm,#FF7600 59.7mm,#FF3500 59.8mm); background: linear-gradient(to bottom,rgba(0,0,0,0),rgba(0,0,0,0.6)), linear-gradient(45deg,#FF3500 37.7mm,#FF7600 37.8mm,#FF7600 59.7mm,#FF3500 59.8mm); } #front { z-index: 2; } /*文本排版样式*/ h1, h2 { font-family: DeutschGothicNormal, sans-serif; } h1 { position: relative; font-size: 30px; font-size: 3rem; z-index: 3; } h2 { position: relative; top: 2mm; font-size: 15px; font-size: 1.5rem; text-shadow: 0 0 4px white, 0 -5px 4px #FFFF33, 2px -10px 6px #FFDD33, -2px -15px 11px #FF8800, 2px -25px 18px #FF2200; } p, li { font-family: SFArcheryBlackSCRegular; font-size: 11px; font-size: 1.1rem; margin-top: 5px; margin-top: 0.5rem; } li { position: relative; top: 8mm; } 

上面只是一些基本样式,下面咱们来看这个实例中的关键部分:

/* 不支持transform 2D 或者transform 3D的浏览器执行 */
#wrapper:hover #inner-wrapper #front, #wrapper:focus #inner-wrapper #front { margin-left: -350px; } 

首先在不支持transform 2D 或者transform 3D的浏览器定义了一个样式,让卡片向左移动,显示底部的卡片。

/*支持transform 2D的浏览执行 */

@supports (-webkit-transform: rotate(-30deg)) or (-moz-transform: rotate(-30deg)) or (-ms-transform: rotate(-30deg)) or (-o-transform: rotate(-30deg)) or (transform: rotate(-30deg)) { #inner-wrapper #front { -webkit-transition: 0.8s all ease-in; -moz-transition: 0.8s all ease-in; -ms-transition: 0.8s all ease-in; -o-transition: 0.8s all ease-in; transition: 0.8s all ease-in; } #wrapper:hover #inner-wrapper #front, #wrapper:focus #inner-wrapper #front { margin-left: 0; -webkit-transform: rotate(-30deg) translate(-50%,-100%); -moz-transform: rotate(-30deg) translate(-50%,-100%); -ms-transform: rotate(-30deg) translate(-50%,-100%); -o-transform: rotate(-30deg) translate(-50%,-100%); transform: rotate(-30deg) translate(-50%,-100%); } } 

经过@supports在支持transform 2D属性的浏览器中实现旋转和位移的效果。

/* 在支持 3D transforms的浏览器执行 */

@supports (-webkit-transform: rotateX(0deg)) or (-moz-transform: rotateX(0deg)) or (-ms-transform: rotateX(0deg)) or (-o-transform: rotateX(0deg)) or (transform: rotateX(0deg)) { #front, #back { -webkit-backface-visibility: hidden; -moz-backface-visibility: hidden; -ms-backface-visibility: hidden; -o-backface-visibility: hidden; backface-visibility: hidden; } #front { -webkit-transform: rotateX(0deg); -moz-transform: rotateX(0deg); -ms-transform: rotateX(0deg); -o-transform: rotateX(0deg); transform: rotateX(0deg); } #back { -webkit-transform: rotateX(180deg); -moz-transform: rotateX(180deg); -ms-transform: rotateX(180deg); -o-transform: rotateX(180deg); transform: rotateX(180deg); } #wrapper:hover #inner-wrapper, #wrapper:focus #inner-wrapper { -webkit-transform: rotateX(180deg); -moz-transform: rotateX(180deg); -ms-transform: rotateX(180deg); -o-transform: rotateX(180deg); transform: rotateX(180deg); } #wrapper:hover #inner-wrapper #front, #wrapper:focus #inner-wrapper #front { -webkit-transform: none; -moz-transform: none; -ms-transform: none; -o-transform: none; transform: none; } } 

最后也使用@supports属性,在支持transform 3D属性的浏览器中实现旋转功能。

@supports效果 Modernizr效果

特别声明:上面代码来自于Chris Mills在《Native CSS feature detection via the @supports rule》提供的一个案例

注:请使用支持@supports的浏览器查看上面的案例。

著做权归做者全部。
商业转载请联系做者得到受权,非商业转载请注明出处。
原文: https://www.w3cplus.com/css3/css3-supports.html © w3cplus.com著做权归做者全部。
商业转载请联系做者得到受权,非商业转载请注明出处。
原文: https://www.w3cplus.com/css3/css3-supports.html © w3cplus.com

相关文章
相关标签/搜索