如何優雅地實現瀏覽器兼容與CSS規則回退
讀完了《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 官網://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揭秘》列為必讀書目。