如何優雅地實現瀏覽器兼容與CSS規則回退


Marco Samaniego @ unsplash.com

讀完了《Visual Studio Code權威指南》,前端方面書籍不能停,於是撿起「CSS一姐」 Lea Verou 的《CSS魔法》。

我們沒法控制用戶使用新版本還是老版本的瀏覽器,因此往往需要根據瀏覽器對於屬性的兼容情況書寫多套 CSS 代碼。本文就是探討如何優雅地應對瀏覽器兼容問題,包括四點:層疊機制來支持較早的瀏覽器,Modernizr設置輔助類來分別編寫樣式,使用 @supports 規則回退,簡短的 JavaScript 代碼實現回退。

提供瀏覽器兼容的網站

層疊機制來支持較早的瀏覽器

/* 防止 linear-gradient 在老瀏覽器中掛掉導致沒有背景 */
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);
/* 應該將標准語法放在最后,來確保最終生效的是是標准語法 */
background: linear-gradient(90deg, yellow, red);

Modernizr設置輔助類來分別編寫樣式

這里參考了一篇14年的老博客 Modernizr 的介紹和使用

Modernizr 官網:https://modernizr.com/

Modernizr 如何生效?如果頁面支持 text-shadow 屬性,那么 Modernizr 會添加 textshadow 類。如果不支持,那么它用 no-textshadow 類作為替代進行添加。

因此,前端開發人員就可以設置兩套代碼,來應對瀏覽器提供或者不提供 text-shadow 支持的兩種情況。

/* 瀏覽器不支持 text-shaow */
h1 { color: gray }

/* 瀏覽器支持 text-shaow */
.textshaow h1 {
  color: transparent;
  text-shadow: 0 0 .3rem gray;
}

使用 @supports 規則回退

除了使用 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 的瀏覽器中才會生效。因此慎用 @supports

簡短的 JavaScript 代碼實現回退

思路與 Modernizr 相同,做特性檢測,然后添加輔助類。

var root = document.documentElement;  // <html>

if ('textShadow' in root.style) {
  root.classList.add('textshadow')
} else {
  rott.classList.add('no-textshadow')
}

如上,我們為 html 添加了輔助類:

  • 如果瀏覽器支持 text-shadow ,那么添加 textshadow
  • 如果瀏覽器不支持 text-shadow ,那么添加 no-textshadow

上述代碼可以被封裝為函數:

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;
}

注意到上述方法只能用來檢測屬性是否支持,而非屬性值。(如下,解釋一下屬性和屬性值,如下代碼)

background : linear-gradient(red, tan);
    屬性    :     屬性值                ;

檢測屬性值是否支持,常見的思路是:賦給對應屬性,然后看瀏覽器是否還保存着這個值。這個方法會改變元素樣式,因此可以用隱藏元素防止樣式因為檢測被改變。

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');
}

封裝函數如下:

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;
}

CSS一姐的書真的很有水平,怪不得前端大大們把她的《CSS揭秘》列為必讀書目。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM