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

  • 相关阅读:
    Postgresql主从流复制+Redis集群部署
    数据仓库实时数据同步方案
    数据库与WEB服务器的配置
    HOSTS文件
    Android 命令设置获取、IP地址、网关、dns
    转:mysqld与mysqld_safe的区别
    mysql 5.7 创建用户报错ERROR 1364 (HY000): Field 'ssl_cipher' doesn't have a default value
    MySql 5.7中添加用户,新建数据库,用户授权,删除用户,修改密码
    监控网卡设备流量
    获取进程所有信息
  • 原文地址:https://www.cnblogs.com/piperliu/p/14977985.html
Copyright © 2020-2023  润新知