如何优雅地实现浏览器兼容与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 官网: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揭秘》列为必读书目。

如何优雅地实现浏览器兼容与CSS规则回退的更多相关文章
- 转载于山边小溪的博客--编写跨浏览器兼容的 CSS 代码的金科玉律
		
http://www.cnblogs.com/lhb25/archive/2010/06/19/1760786.html 原始网页 作为 Web 设计师,你的网站在各种浏览器中有完全一样的表现是很 ...
 - 转:【总结】浏览器CSS Hacks汇总,浏览器兼容方式CSS Hacks
		
[总结]浏览器CSS Hacks汇总 浏览器兼容可以说是前端开发所要面对的第一个挑战,目前我的电脑上已经安装了6种浏览器(基于IE内核的不算,如Maxthon等). CSS hacks利用浏览器的 ...
 - 聊聊一直困扰前端程序员的浏览器兼容-【css】
		
1.为什么会出现浏览器兼容问题? 由于各大主流浏览器由不同的厂家开发,所用的核心架构和代码也很难重和,这就为各种莫名其妙的Bug(代码错误)提供了温床.再加上各大厂商出于自身利益考虑而设置的种种技术壁 ...
 - 浏览器兼容的css hack
		
<style> div{ background:green; /* for firefox */ *background:red; /* for IE6 */ } </style&g ...
 - CSS实现背景透明,文字不透明(各浏览器兼容)
		
/*CSS*/.waps{ background:url(07158.bmp) no-repeat top center fixed; width:1004px; text-align:center; ...
 - CSS实现背景透明,文字不透明(各浏览器兼容) (转)
		
/*CSS*/ .waps{ background:url(07158.bmp) no-repeat top center fixed; width:1004px; text-align:center ...
 - 最全的CSS浏览器兼容问题(转至http://68design.net/Web-Guide/HTMLCSS/37154-1.html)
		
最全的CSS浏览器兼容问题 CSS对浏览器的兼容性有时让人很头疼,或许当你了解当中的技巧跟原理,就会觉得也不是难事,从网上收集了IE7,6与Fireofx的兼容性处理方法并整理了一下.对于web2 ...
 - 浏览器兼容问题汇总<转>
		
浏览器的内核 Mozilla Firefox ( Gecko ) Internet Explorer ( Trident ) Opera ( Presto ) Safari ( WebKit ) Go ...
 - 跨浏览器开发:CSS
		
理解CSS盒子模型 如果不需要很多奇巧淫技的跨浏览器兼容的 CSS 代码,透彻地理解 CSS 盒子模型是首要事情,CSS 盒子模型并不难,且基本支持所有浏览器,除了某些特定条件下的 IE 浏览器.CS ...
 
随机推荐
- 【Mysql】数据库索引,百万数据测试索引效果
			
Mysql官方对索引的定义是:索引(index)是帮助Mysql高效获取数据的数据结构.进而,我们可以知道索引的本质是数据结构. 一.索引的分类 主键索引:也就是我们常见的 PRIMARY KEY,只 ...
 - Shell 脚本重启项目
			
每次发打包好项目后都需要手动重启项目,写个Shell脚本一键重启项目 Shell 脚本 #!/bin/bash while getopts "n:p:" arg do case $ ...
 - git push 时发生错误 error: src refspec master does not match any. error: failed to push some refs to
			
很多相关解决办法都是最后要 push 到远端的 master 上,但很多其实要求不能把个人的修改内容直接 push 到 master 主分支. 因此,当我想将本地 feature/work1 分支的修 ...
 - 完全理解Python 迭代对象、迭代器、生成器
			
在了解Python的数据结构时,容器(container).可迭代对象(iterable).迭代器(iterator).生成器(generator).列表/集合/字典推导式(list,set,dict ...
 - kubernetes技能图谱
			
深入剖析Kubernetes-张磊(Kubernetes社区资深成员与项目维护者) Kubernetes集群搭建 ver1.20.5
 - Linux 查看实时网卡流量的方法 网速 nload sar iftop dstat
			
1.使用nload yum install -y gcc gcc-c++ ncurses-devel make wgetwget http://www.roland-riegel.de/nload/n ...
 - 机器学习算法之K近邻算法
			
0x00 概述 K近邻算法是机器学习中非常重要的分类算法.可利用K近邻基于不同的特征提取方式来检测异常操作,比如使用K近邻检测Rootkit,使用K近邻检测webshell等. 0x01 原理 ...
 - redis中AOF和RDB的关闭方法
			
redis中AOF和RDB的关闭方法 问题:当往redis中导入数据时,有时会出现redis server went away的情况: 原因: 导入的数据量太大,而内存不够(即内存1G,但数据有2 ...
 - 昇腾AI 软硬件全栈平台
			
昇腾AI 软硬件全栈平台
 - OFRecord 数据集加载
			
OFRecord 数据集加载 在数据输入一文中知道了使用 DataLoader 及相关算子加载数据,往往效率更高,并且学习了如何使用 DataLoader 及相关算子. 在 OFrecord 数据格式 ...