如何優(yōu)雅地實(shí)現(xiàn)瀏覽器兼容與CSS規(guī)則回退
我們沒法控制用戶使用新版本還是老版本的瀏覽器,因此往往需要根據(jù)瀏覽器對(duì)于屬性的兼容情況書寫多套 CSS 代碼。本文就是探討如何優(yōu)雅地應(yīng)對(duì)瀏覽器兼容問題,包括四點(diǎn):層疊機(jī)制來支持較早的瀏覽器,Modernizr設(shè)置輔助類來分別編寫樣式,使用 @supports 規(guī)則回退,簡(jiǎn)短的 JavaScript 代碼實(shí)現(xiàn)回退。
提供瀏覽器兼容的網(wǎng)站
- https://caniuse.com/
- https://webplatform.github.io/
- https://developer.mozilla.org/en-US/
層疊機(jī)制來支持較早的瀏覽器
- /* 防止 linear-gradient 在老瀏覽器中掛掉導(dǎo)致沒有背景 */
- background: rgb(255, 128, 0);
- background: -moz-linear-gradient(0deg, yellow, red);
- background: -o-linear-gradient(0deg, yellow, red);
- background: -webkit-linear-gradient(0deg, yellow, red);
- /* 應(yīng)該將標(biāo)準(zhǔn)語(yǔ)法放在最后,來確保最終生效的是是標(biāo)準(zhǔn)語(yǔ)法 */
- background: linear-gradient(90deg, yellow, red);
Modernizr設(shè)置輔助類來分別編寫樣式
這里參考了一篇14年的老博客 Modernizr 的介紹和使用。
Modernizr 官網(wǎng):https://modernizr.com/
Modernizr 如何生效?如果頁(yè)面支持 text-shadow 屬性,那么 Modernizr 會(huì)添加 textshadow 類。如果不支持,那么它用 no-textshadow 類作為替代進(jìn)行添加。
因此,前端開發(fā)人員就可以設(shè)置兩套代碼,來應(yīng)對(duì)瀏覽器提供或者不提供 text-shadow 支持的兩種情況。
- /* 瀏覽器不支持 text-shaow */
- h1 { color: gray }
- /* 瀏覽器支持 text-shaow */
- .textshaow h1 {
- color: transparent;
- text-shadow: 0 0 .3rem gray;
- }
使用 @supports 規(guī)則回退
除了使用 Modernizr ,也可以使用瀏覽器自帶的 @supports :
- /* 瀏覽器不支持 text-shaow */
- h1 { color: gray }
- /* 瀏覽器支持 text-shaow */
- @supports (text-shadow: 0 0 .3rem gray){
- h1 {
- color: transparent;
- text-shadow: 0 0 .3rem gray;
- }
- }
但是 Lea Verou 指出,上述代碼的投影效果只有在即支持 @supports 又支持 text-shadow 的瀏覽器中才會(huì)生效。因此慎用 @supports 。
簡(jiǎn)短的 JavaScript 代碼實(shí)現(xiàn)回退
思路與 Modernizr 相同,做特性檢測(cè),然后添加輔助類。
- var root = document.documentElement; // <html>
- if ('textShadow' in root.style) {
- root.classList.add('textshadow')
- } else {
- rott.classList.add('no-textshadow')
- }
如上,我們?yōu)?html 添加了輔助類:
- 如果瀏覽器支持 text-shadow ,那么添加 textshadow
- 如果瀏覽器不支持 text-shadow ,那么添加 no-textshadow
上述代碼可以被封裝為函數(shù):
- function testProperty(property) {
- var root = document.documentElement;
- if (property in root.style) {
- root.classList.add(property.toLowerCase());
- return true;
- }
- root.classList.add('no-' + property.toLowerCase());
- return false;
- }
注意到上述方法只能用來檢測(cè)屬性是否支持,而非屬性值。(如下,解釋一下屬性和屬性值,如下代碼)
- background : linear-gradient(red, tan);
- 屬性 : 屬性值 ;
檢測(cè)屬性值是否支持,常見的思路是:賦給對(duì)應(yīng)屬性,然后看瀏覽器是否還保存著這個(gè)值。這個(gè)方法會(huì)改變?cè)貥邮?,因此可以用隱藏元素防止樣式因?yàn)闄z測(cè)被改變。
- var dummy = document.createElement('p');
- dummy.style.backgroundImage = 'linear-gradient(red, tan)';
- if (dummy.style.backgroundImage) {
- root.classList.add('lineargradients');
- } else {
- root.classList.add('no-lineargradients');
- }
封裝函數(shù)如下:
- function testValue(id, value, property) {
- var dummy = document.createElement('p');
- dummy.style[property] = value;
- if (dummy.style[property]) // 屬性值被瀏覽器保留
- {
- root.classList.add(id);
- return true;
- }
- root.classList.add('no-' + id);
- return false;
- }