学习 CSS At Rules 特性查询 — @supports

概述/简介

什么是 Web 标准

Web 标准主要由 W3C(万维网联盟)负责规划和制定,其中 IETF (TCP/IP 协议)、Ecma (ECMAScript 标准)、WHATWG (如 Fetch 标准Stream 标准) 也是 Web 标准的重要参与者和制定者。一些浏览器厂商和其他 Web 标准实现者通过对 Web 标准的支持和遵循,确保互联网上的网页和应用程序在不同的平台和设备上能够一致地工作和展示。这些标准旨在提高 Web 内容的可访问性、互操作性、可维护性和可持续性。

  • 可访问性:促进创建无障碍的网页和应用程序,使残障人士、老年人和其他特殊需求用户能够轻松访问和使用Web内容。

  • 互操作性:不同的浏览器、操作系统和设备能够正确地解析和显示Web内容,确保用户在不同平台上都能获得一致的体验。

  • 可维护性:因其标准化的代码结构和样式规范使得代码更加清晰、可重用和易于维护,开发者更可以轻松地编写、更新和维护网页和应用程序。

  • 可持续性:鼓励使用模块化和可扩展的技术,使得网页和应用程序能够适应不断变化的需求和新的技术发展。

有关 Web 标准更多信息,暂不展开。有兴趣可以看这篇 ------ 《前端应该知道的Web标准》

什么是 特性查询

由于浏览器之间存在差异性,对 Web 标准的支持和实现各有不同。它不仅限于浏览器之间内核的不同 (例如 Chrome、Safari、Firefox),即使是同一内核的浏览器在不同操作系统中,又或是不同版本的编译下,对 Web 标准各个特性的支持度也是各有长短。所以在使用较新的语法或特性时,我们往往需要考虑浏览器的兼容性,进行功能或特征的检测,对其不支持的特性或语法进行优雅降级。

在 Javascript 语法中,我们可以通过编写 polyfill 或者第三方插件(例如 babel)来检测或补全功能的基本属性、方法等。而在 CSS 语法中,虽然 CSS 的性质已经允许优雅降级,通过忽略不受支持的属性或值从而不破坏样式表中的其他样式,例如:

css 复制代码
  :root {
    --color: red;
  }
  
  .title {
    color: red;
    color: var(--color); /* 当不支持 css 自定义属性时,上一行 color: red; 仍起效  */
  }
  

这非常有用,但有时候我们需要更多,因为 CSS 样式始终是整体应用,我们往往需要一系列的 CSS 特性一起配合使用,尤其是在构建网页布局时最为常见。这就要求我们能够对 CSS 特性进行特征查询,并针对查询的结果(支持/不支持) 应用不同的系列样式,例如:

css 复制代码
  /* 不支持 display: flex */
  @supports not (display: flex) {
    .flex-container {
      width: 100%;
      height: auto;
      font-size: 0;
      display: block;
    }
    
    .flex-container > .item {
      width: 80px;
      height: 44px;
      margin: 10px 20px;
      font-size: 12px;
      line-height: 44px;
    }
  }
  
  /* 支持 display: flex */
  @supports (display: flex) {
    .flex-container {
      width: 100%;
      height: auto;
      display: flex;
      justify-content: space-evenly;
      align-items: center;
    }
    
    .flex-container > .item {
      flex: 0 0 auto;
      width: 80px;
      height: 44px;
      margin: 10px 0;
      font-size: 12px;
    }
  }

如上所见,就是特性查询,即 @supports,它属于 CSS At Rules 中一种,它仅将块中的声明样式应用于支持或不支持某个属性-值对的状态。

特性查询 @supports

兼容性

特性查询 @supports 自 Opera 浏览器于 2012 年 11 月实现了以来,各主流浏览器都已完全支持!(🚧 IE 果断抛弃)

语法定义

特性查询 @supports 由一组 样式声明 和若干 支持条件 构成。

  • 声明语法

    最基本的支持条件就是 CSS 声明,也就是一个 CSS 属性后跟一个值,中间用冒号分开

    css 复制代码
      /* 如果支持 transform: rotate(45deg); 则会应用 .square 样式 */
      @supports (transform: rotate(45deg)) {
        .square {
          width: 100px;
          height: 100px;
          background-color: #f34d4d;
          transform: rotate(45deg);
        }
      }
  • 函数语法

    第二种基本支持条件是支持函数

    • selector() 测试是否支持指定的选择器语法

      css 复制代码
        /* 如果支持 :is伪元素,则会应用 :is(.square) 中样式 */
        @supports selector(:is(div)) {
          :is(.square) {
            width: 100px;
            height: 100px;
            background-color: #f34d4d;
            transform: rotate(45deg);
          }
        }
    • font-tech()font-format() 支持以声明式和编程方式访问字体堆栈功能的功能检测。目前兼容性除了 Firefox 几乎都不支持

逻辑运算符

当创建一个取决于多个条件的特性查询时, 这就是需要 逻辑运算符 的配合使用。在使用中碰到优先级问题,则可以使用圆括号调整操作符的优先级。具体如下:

  • and: 用来将两个原始的表达式做逻辑与后生成一个新的表达式,如果两个原始表达式的值都为真,则生成的表达式也为真,例如

    css 复制代码
      /* 如果支持 CSS 自定义属性,且支持 transform: rotate(45deg); 则应用样式 */
      @supports (--rotate: rotate(45deg)) and (transform: rotate(45deg)) { 
        /* css code */
      } 
     
  • or: 用来将两个原始的表达式做逻辑与后生成一个新的表达式,如果两个原始表达式的值其中一个为真,则生成的表达式也为真,例如

    css 复制代码
      /* 如果支持 display: -webkit-flex; 或者 display: flex; 则应用样式 */
      @supports (display: -webkit-flex) or (display: flex) {
        /* css code */
      } 
     
  • not: 将其操作符放在任何表达式之前就能否定一条表达式,提供了用于在不支持功能时应用样式,例如

    css 复制代码
      /* 如果不支持 display: flex; 则应用样式 */
      @supports not (display: flex) { 
        /* css code */
      }
     

JS API (CSS.supports)

语法定义

该方法是静态方法返回一个 Boolean 值,用来在 JS语法 中校验浏览器是否支持一个给定的 CSS 特性。

它有两种不同的传值形式:

  • 第一种用来检验浏览器对于一对"属性 - 属性值"的支持

    js 复制代码
      /**
       *  window.CSS.supports(name, value)
       *    name: 一个包含要检查的 CSS 属性名称的 DOMString
       *    value: 一个包含要检查的 CSS 属性值的 DOMString
       */
       window.CSS.supports("display", "flex");
       
  • 第二种语法需要一个匹配 @supports 支持条件的参数

    js 复制代码
      /**
       *  
       *  window.CSS.supports(condition)
       *    condition: 一个包含了检查条件的 DOMString
       */
       window.CSS.supports("display: flex");
       

更多范例

js 复制代码
  window.CSS.supports("(display: -webkit-flex) and (display: flex)");
  window.CSS.supports("(transform: rotate(45deg))");
  window.CSS.supports("display", "flex");
  window.CSS.supports("--color", "red");
  window.CSS.supports("(--color: red)");
  
相关推荐
软件小伟1 分钟前
Vue3+element-plus 实现中英文切换(Vue-i18n组件的使用)
前端·javascript·vue.js
醉の虾23 分钟前
Vue3 使用v-for 渲染列表数据后更新
前端·javascript·vue.js
张小小大智慧31 分钟前
TypeScript 的发展与基本语法
前端·javascript·typescript
hummhumm41 分钟前
第 22 章 - Go语言 测试与基准测试
java·大数据·开发语言·前端·python·golang·log4j
asleep7011 小时前
第8章利用CSS制作导航菜单
前端·css
hummhumm1 小时前
第 28 章 - Go语言 Web 开发入门
java·开发语言·前端·python·sql·golang·前端框架
幼儿园的小霸王2 小时前
通过socket设置版本更新提示
前端·vue.js·webpack·typescript·前端框架·anti-design-vue
疯狂的沙粒2 小时前
对 TypeScript 中高级类型的理解?应该在哪些方面可以更好的使用!
前端·javascript·typescript
gqkmiss2 小时前
Chrome 浏览器 131 版本开发者工具(DevTools)更新内容
前端·chrome·浏览器·chrome devtools
Summer不秃2 小时前
Flutter之使用mqtt进行连接和信息传输的使用案例
前端·flutter