CSS3條件判斷,聽起來「不明覺厲」,若是你對CSS稍爲熟悉一點的話,你會發現CSS中的「@media」就是條件判斷之一。是的,在CSS3的條件判斷規範文檔中包含了兩個部分,其一是「@media」規則,主要用來「根據媒體屬性區分樣式表」(特別是在Responsive設計中,發揮的做用更是強大);其二是「@supports」規則,主要用來代替前面經常使用的Modernizr庫,在不支持CSS3的瀏覽器下實現漸進加強式設計。換句話來講,@supports可讓咱們在不支持CSS3屬性的瀏覽器下配上單獨的樣式,看起來很強大,那具體如何使用呢?咱們今天一塊兒簡單的來學習一下:javascript
衆所周知,不一樣的瀏覽器(不論是現代瀏覽器仍是老版本的IE瀏覽器)對Web頁面的解析都是不同,爲了讓Web頁面在這些瀏覽器下渲染達到基本一致的狀況,給用戶更好的體驗,咱們必須爲他們寫不一樣的樣式代碼。css
不一樣特徵的檢測方法咱們早期都是依賴於javascript來檢測,後來經過第三方js庫Modernizr來完成。但這樣真的有用嗎?除了要懂怎麼檢測以外,咱們還須要瞭解更多的瀏覽器解析機制,這樣一來對於咱們前端人員來講就是「沒辦法」。還好CSS3 Conditional Rules Module Level 3推出了「@supports」條件判斷規則,它充許咱們能夠根據瀏覽器對CSS特性的支持狀況來定義不一樣的樣式。這對咱們來講是很是重要。html
要想更好的使用@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最基本的使用規則。
@supports可使用not邏輯聲明,主要做用是,在不支持新特性時,能夠提供備用樣式。換過來也能夠理解,若是你的瀏覽器不支持@supports條件判斷中的樣式,你能夠經過@supports爲瀏覽器提供一種備用樣式,如:
@supports not (display: flex){
#container div{float:left;} }
上面的代碼表示的是,若是你的瀏覽器不支持「display:flex」屬性,那麼你可使用「float:left」來替代。
@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){ /*樣式*/ }
@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的幾種語法的使用規則介紹,在使用這幾種規則時,有幾點須要特別注意:
在@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提供的兼容性表格:
雖然目前僅有兩個瀏覽器支持,但咱們應該相信,這將是一種趨勢,早晚其餘瀏覽器也會跟上的,最終被支持。
在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);
衆說周知,早前都是使用Modernizr庫來作一些瀏覽器對屬性的檢測,從而判斷瀏覽器是否支持這些特性。自從@supports推出後,Modernizr真的是老了嗎?他們之間有什麼優點呢?
@supports和Modernizr相比,在速度、性能和功能都要比Modernizr強。爲何這麼說呢?由於@supports採用瀏覽器本地方法實現,這樣速度會更快、效率也會更高;另外Modernizr須要依賴於js庫,而@supports避免了引入js庫,減小了http的請求量和服務器流量,而且讓開發更簡單快捷;並且@support支持多種邏輯條件樣式判斷,能夠很好的知足多種需求。
但話又說回來,若是你的瀏覽器不支持@supports,目前來講你仍是須要依賴於Modernizr來作一些檢測。其實Paul Irish說過,Modernizr也在計劃,將來將使用@supports來替代自身的檢測方法。
無論使用@supports或者說使用Modernizr來作一些漸進加強式的處理,咱們都避免不了寫多個樣式,這樣從而也增長了樣式的體積,但惟的一好處是,能減小對文件的請求,加強了用戶對產品的體驗感。
所以,如今對你來講是否使用@supports,正確的是在使用@supports以前先檢測是滯支持CSS.supports()和@supports,若是檢測出不支持,在加載Modernizr,這樣你的頁面就會有一個很好的兼容性。下面是實現的方法:
if ( !(window.supportsCSS || (window.CSS && window.CSS.supports) )) load_modernizr()
在大多數狀況之下,使用@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來實現的(案例),案例效果以下所示:
上圖是在瀏覽器支持3D旋轉,卡片翻轉的一個很好的動畫。
上圖是在瀏覽器不支持3D轉換但支持2D轉換,賀卡的正面旋轉和動畫,底面顯示出來。
上圖是在瀏覽器不支持3D或2D轉換,賀卡的正面就移動左邊,顯示後面沒有動畫。
接下來,咱們來看看使用@supports修改後的實現方法。
<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部分。
卡片基本樣式:
/* 自定義體體、導入字體 */
@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(