CSS漸進(jìn)增強(qiáng)方案
首先需要明確一點(diǎn),以往瀏覽器對css
的支持是不同的,不同瀏覽器的樣式可能會存在差異,對待這種差異問題,需要寫幾套不同的css
來兼容(邊框、圓角、顏色等),這樣是非常麻煩的,瀏覽器css
顯示差異化屬于瀏覽器自身的問題,跟我們的css
是沒有關(guān)系的,好的瀏覽器就有好的顯示,糟糕的瀏覽器就只有普通顯示,我們只需要關(guān)注瀏覽器是否支持css
屬性即可。
例如:邊框圓角
border-radius : 50%
上面這一句是將邊框變成圓形,但部分瀏覽器可能會顯示為方形,這種樣式的差異問題無需理會。
現(xiàn)在就瀏覽器是否支持css
屬性來討論一下漸進(jìn)增強(qiáng)的適配方案。
1、屬性值差異實(shí)現(xiàn)兼容
2、偽類或偽元素實(shí)現(xiàn)兼容
3、瀏覽器類型區(qū)分實(shí)現(xiàn)兼容
4、@supports
實(shí)現(xiàn)兼容
屬性值差異實(shí)現(xiàn)兼容
css
的新增屬性低版本瀏覽器是不識別的,通過屬性值差異來實(shí)現(xiàn)兼容
案例一:實(shí)現(xiàn)圖片旋轉(zhuǎn)
.images{ ? ?width: 100px; ? ?height: 100px; ? ?/*所有瀏覽器識別*/
? ?background: url(../assets/loading.gif); ? ?
? ?/* IE10+ 瀏覽器識別 */
? ?background: url(../assets/loading.png),linear-gradient(transparent,transparent); ? ?background-size: 100px; ? ?animation: spin 1s linear infinite;
}/* 鍵字 "from" 和 "to"(代表 0%(開始)和 100%(完成)) */@keyframes spin{ ? ?from { transform: rotate(360deg); } ? ?to { transform: rotate(0deg); }
}

分析:
css部分寫了?background: url(../assets/loading.gif);
?這一句是所有瀏覽器都識別的,圖片為加載的gif動圖
;此外我們又多添加了?background: url(../assets/loading.png),linear-gradient(transparent,transparent);
這一句,其中linear-gradient
為IE10+才會識別的,如果當(dāng)前瀏覽器是IE10
以下則顯示動圖,如果是IE10+
則顯示png靜態(tài)圖片
,配合animation(IE10+)
來實(shí)現(xiàn)動畫效果。
案例二:實(shí)現(xiàn)邊框陰影IE8
以下的瀏覽器是不支持box-shadow
屬性的,如果想要實(shí)現(xiàn)樣式的浮動效果,可以通過border
來實(shí)現(xiàn),IE9+
支持box-shadow
,那么就可以用陰影實(shí)現(xiàn)。
.panel{ ? ?width: 50px; ? ?height: 50px; ? ?margin: 10px; ? ?/* 所有瀏覽器識別 */
? ?border: 1px solid #ddd; ? ?/* IE9+ 瀏覽器識別 */
? ?border:1px solid rgba(0,0,0,0); ? ?box-shadow: 2px 2px;
}

rgba
也是IE9+
才支持的,所以這里可以添加一個(gè)rgba(0,0,0,0)
覆蓋原來的border
效果,這樣邊框透明,底部陰影的效果就出現(xiàn)了。
偽類或偽元素實(shí)現(xiàn)兼容
上面利用css
屬性差異實(shí)現(xiàn)兼容只適合單行的css
屬性,如果要適配整個(gè)代碼塊,可以使用偽類或偽元素,IE8
以下不會識別偽元素,IE9+
識別偽元素。
關(guān)于偽元素的說明:
屬性說明::after素之后插入::before元素之前插入::first-letter首字母-第一個(gè)字::first-line首行-第一行::selection選擇的元素
詳細(xì)的請看w3school文檔:https://www.w3school.com.cn/css/css_pseudo_classes.asp
.pseudo{ ? ?width: 150px; ? ?height: 50px; ? ?margin: 10px; ? ?border: 1px solid #ddd;
} /* IE9+識別 */
_::before,.pseudo{ ? ?border:1px solid rgba(0,0,0,0); ? ?box-shadow: 2px 2px #608dfa;
}
上面這里重寫了之前的box-shadow
的案例,IE8
以下識別pseudo
代碼塊,IE9+
識別_::before,.pseudo
代碼塊,并且按照執(zhí)行順序覆蓋相同屬性。

_::before
,偽元素前的下劃線是作為一個(gè)標(biāo)簽選擇器用來占位的,本身不會產(chǎn)生任何匹配。
可以通過該案例以此類推IE10+
瀏覽器支持表單驗(yàn)證相關(guān)的偽類IE11+
支持::-ms-backdrop
偽元素(IE需要加ms
前綴,其它瀏覽器不需要)Edge12+
使用@supports
Edge13+
支持:in-range
或:out-of-range
....
瀏覽器類型區(qū)分
瀏覽器支持參考手冊:https://www.w3school.com.cn/cssref/css_browsersupport.asp

瀏覽器配合偽元素:Firefox
瀏覽器識別,可以使用帶有-moz-
私有前綴的偽類或偽元素
/* Firefox */_::-moz-progress-bar, .sth-class{}
主流瀏覽器識別
_:default, .sth-class{}
webkit
瀏覽器識別:只可使用帶有-webkit-
前綴的偽類
,不能使用帶有-webkit-
前綴的偽元素
,因?yàn)?code>Firefox瀏覽器會認(rèn)為帶有-webkit-
前綴的偽元素是合法的。
/* webkit瀏覽器 */:-webkit-any(_),.sth_class{}
Chromium Edge
瀏覽器識別
/* Chromium Edge */_::-ms-any,.sth-class{}
偽元素處理兼容性有風(fēng)險(xiǎn),如果瀏覽器哪天不支持某個(gè)偽類,那么就會出問題,這種方法只能解決一些特殊問題,需要注意。
@supports的兼容
@supports
可以用來檢測當(dāng)前瀏覽器是否支持某個(gè)css
特性,用來處理css
漸進(jìn)增強(qiáng)是最正規(guī)的。@supports
的支持是從Edge12
瀏覽器開始的,目前的主流瀏覽器都支持。
.div_supports{ ? ?width: 50px; ? ?height: 50px;
? ?background: url(../assets/music.gif); ?/* 被覆蓋 */
? ?background-size: 50px;
}/* Edge12+瀏覽器 */@supports (animation : none){ ?// 支持 ? ?.div_supports{ ? ? ? ?background: url(../assets/loading.png); ? ? ? ?background-size: 50px; ? ? ? ?animation: ?supp 1s linear infinite;
? ?}
}@keyframes supp { ? ?from { transform: rotate(360deg); } ? ?to { transform: rotate(0deg); }
}

使用@supports
實(shí)現(xiàn)加載動畫,在Edge12
之前的瀏覽器,使用gif動圖
,Edge12+
的瀏覽器則使用png
靜態(tài)圖片配合動畫效果實(shí)現(xiàn)。
@supports (animation : none) {} ?/*支持*/@supports (border-radius : aaa){} /* 不支持 */
語法:@supports CSS at-rule
?可以指定依賴于瀏覽器中的一個(gè)或多個(gè)特定的?CSS
?功能的支持聲明。這被稱為特性查詢。該規(guī)則可以放在代碼的頂層,也可以嵌套在任何其他條件組規(guī)則中。如果參數(shù)部分的語法是支持的則返回true
,否則就是false
。
操作符說明默認(rèn)判斷支持true , 不支持falsenot不支持則進(jìn)入代碼塊and同時(shí)支持or滿足其一
下面是操作符的應(yīng)用:
/* 支持彈性布局 */@supports (display: flex){}
/* 不支持彈性布局 */@supports not (display: flex){}
/* 同時(shí)支持彈性布局和網(wǎng)格布局 */@supports (display: flex) and (display: grid){}
/* 彈性布局或網(wǎng)格布局滿足其一即可 */@supports (display: flex) or (display: grid){}
@supports可以連續(xù)做多個(gè)判斷
注意:不能將支持和不支持的語法直接放在一起,會報(bào)錯
@supports (display: flex) and not (display: grid){} /* 報(bào)錯 */
解決方法:類似js
中的優(yōu)先級嵌套,用()
括起來即可
/* 支持彈性布局但不支持網(wǎng)格布局*/@supports (display: flex) and (not (display: grid)){}
/* 支持彈性布局 但不支持網(wǎng)格布局或動畫 */@supports (display: flex) and ((not (display: grid)) or (not (animation :none))){}
驗(yàn)證是否支持嵌套:
.supports_12{ ? ?width: 300px; ? ?border: 1px solid red;
}/* 支持彈性布局并且不支持border-radius: 'aaa'這種語法*/@supports (display: flex) and (not (border-radius: 'aaa')){ ? ?.supports_12 { ? ? ? ?color:red;
? ?}
}
/* 支持彈性布局,(不支持border-radius: 50% 或(滿足其一) width:'aaa') */@supports (display: flex) and ((not (border-radius: 50%)) or (not (width:'aaa'))){ ? ?.supports_12 { ? ? ? ?color:cyan;
? ?}
}