CSS教程

CSS特性检测@supports

CSS特性检测@supports:条件应用样式规则

本文将详细介绍CSS特性检测工具@supports的用法,帮助开发者根据浏览器对CSS特性的支持情况条件性地应用样式规则。

1. 什么是CSS特性检测@supports

@supports是CSS3引入的条件规则,称为特性查询(Feature Query)。它允许开发者测试浏览器是否支持特定的CSS属性或值,并根据测试结果应用相应的样式规则。

与传统的浏览器嗅测或JavaScript特性检测库不同,@supports原生CSS功能,不需要额外的JavaScript代码,性能更好,使用更简单。

2. @supports的基本语法

@supports的基本语法如下:

@supports (property: value) {
  /* 当浏览器支持该属性-值对时应用的CSS规则 */
}

下面是一个简单的示例,检测浏览器是否支持display: flex

@supports (display: flex) {
  .container {
    display: flex;
  }
}

在这个例子中,只有当浏览器支持display: flex时,才会将.container元素的显示模式设置为flex。

3. @supports的逻辑运算符

@supports支持三种逻辑运算符:notandor,可以构建更复杂的检测条件。

3.1 not运算符

not运算符用于检测浏览器是否不支持某个CSS特性:

@supports not (display: flex) {
  .container {
    display: table;
  }
}

此代码会在浏览器不支持display: flex时应用表格布局。

3.2 and运算符

and运算符用于检测浏览器是否同时支持多个CSS特性:

@supports (display: flex) and (transform: rotate(30deg)) {
  .container {
    display: flex;
    transform: rotate(30deg);
  }
}

此代码仅在浏览器同时支持display: flextransform: rotate(30deg)时应用样式。

3.3 or运算符

or运算符用于检测浏览器是否支持至少一个CSS特性:

@supports (display: flex) or (display: -webkit-flex) {
  .container {
    display: flex;
    display: -webkit-flex;
  }
}

此代码在浏览器支持标准display: flex或带前缀的display: -webkit-flex时都会应用样式。

3.4 复合条件

可以组合多个逻辑运算符构建复杂条件,使用括号明确优先级:

@supports ((display: flex) or (display: -webkit-flex)) and (position: sticky) {
  .container {
    display: flex;
    position: sticky;
  }
}

此代码检测浏览器支持(弹性布局或带前缀的弹性布局)并且同时支持粘性定位时应用样式。

4. 实际应用示例

4.1 检测Grid布局支持

/* 默认浮动布局作为回退方案 */
.container {
  float: left;
  width: 30%;
  margin: 0 1.5%;
}

/* 当支持Grid时应用Grid布局 */
@supports (display: grid) {
  .container {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
    grid-gap: 20px;
    float: none;
    width: auto;
    margin: 0;
  }
}

4.2 检测自定义属性支持

/* 默认颜色值 */
.theme-component {
  color: #3498db;
  background-color: #f0f0f0;
}

/* 当支持CSS自定义属性时使用变量 */
@supports (--css: variables) {
  .theme-component {
    --primary-color: #3498db;
    --background-color: #f0f0f0;
    color: var(--primary-color);
    background-color: var(--background-color);
  }
}

4.3 实现等高布局

<!DOCTYPE html>
<html lang="zh-CN">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>等高布局示例</title>
  <style>
    .child {
      width: 100px;
      margin: 0 10px;
      display: inline-block;
      vertical-align: middle;
      background-color: pink;
    }

    /* 当支持fill-available时实现等高布局 */
    @supports (height: fill-available) or (height: -webkit-fill-available) {
      .child {
        height: -webkit-fill-available;
        height: fill-available;
      }
    }
  </style>
</head>
<body>
  <div style="width:400px;height: 100px;border: 1px solid #000;">
    <div class="child">div1</div>
    <div class="child">div2</div>
    <div class="child">div3<br />div3</div>
  </div>
</body>
</html>

5. JavaScript中的CSS特性检测

除了CSS方法,还可以通过JavaScript接口进行CSS特性检测:

5.1 CSS.supports()方法

CSS.supports()方法提供两种使用方式:

方式一:传递两个参数(属性名和属性值)

// 检查是否支持display: flex
if (window.CSS && window.CSS.supports) {
  const zzw_supportsFlex = CSS.supports('display', 'flex');
  console.log('Flexbox支持情况:', zzw_supportsFlex);
}

方式二:传递单个条件字符串

// 检查复杂条件
if (window.CSS && window.CSS.supports) {
  const zzw_supportsComplex = CSS.supports('(display: grid) or (display: flex)');
  console.log('布局特性支持情况:', zzw_supportsComplex);
}

5.2 封装检测函数

// 封装特性检测函数
function zzw_checkCSSSupport(property, value) {
  if (!window.CSS || !window.CSS.supports) {
    return false;
  }

  if (value) {
    return CSS.supports(property, value);
  } else {
    return CSS.supports(property);
  }
}

// 使用示例
const zzw_flexSupport = zzw_checkCSSSupport('display', 'flex');
const zzw_gridSupport = zzw_checkCSSSupport('display', 'grid');
const zzw_complexSupport = zzw_checkCSSSupport('(transform-style: preserve) or (-webkit-transform-style: preserve)');

if (zzw_flexSupport) {
  document.documentElement.classList.add('zzw-flex-supported');
} else {
  document.documentElement.classList.add('zzw-flex-not-supported');
}

6. 使用场景与最佳实践

6.1 适用场景

  1. 渐进增强:为支持新特性的浏览器提供增强体验,同时为不支持浏览器提供基本体验
  2. 浏览器兼容性处理:针对不同浏览器应用不同样式规则
  3. 前缀检测:检测浏览器是否需要供应商前缀

6.2 最佳实践

  1. 合理使用回退方案:始终为不支持的情况提供合适的回退样式
  2. 避免过度使用:不是所有CSS属性都需要特性检测,浏览器会自动忽略不支持的属性
  3. 注意测试顺序:当使用not运算符时,注意测试顺序可能影响结果
  4. 组合条件优化:使用括号明确复杂条件的优先级

6.3 实用示例:带回退的网格布局

<!DOCTYPE html>
<html lang="zh-CN">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>网格布局回退示例</title>
  <style>
    .container {
      /* 浮动布局作为基础回退 */
      overflow: hidden;
    }

    .item {
      float: left;
      width: 30%;
      margin: 0 1.5%;
      background: #eee;
      padding: 20px;
      box-sizing: border-box;
    }

    /* 当支持Flexbox时使用Flexbox */
    @supports (display: flex) {
      .container {
        display: flex;
        flex-wrap: wrap;
        justify-content: space-between;
      }

      .item {
        float: none;
        width: 30%;
        margin: 0 0 20px 0;
      }
    }

    /* 当支持Grid时使用Grid(最优方案) */
    @supports (display: grid) {
      .container {
        display: grid;
        grid-template-columns: repeat(3, 1fr);
        gap: 20px;
      }

      .item {
        width: auto;
        margin: 0;
      }
    }
  </style>
</head>
<body>
  <div class="container">
    <div class="item">项目1</div>
    <div class="item">项目2</div>
    <div class="item">项目3</div>
  </div>
</body>
</html>

7. 浏览器兼容性

@supports规则在现代浏览器中已得到良好支持:

  • Chrome 28+
  • Firefox 22+
  • Safari 9+
  • Edge 12+
  • Opera 12.1+

对于不支持@supports的浏览器(如IE),它们会直接忽略@supports块内的所有样式,因此务必提供合适的回退方案。

总结

本篇教程介绍了CSS特性检测工具@supports的完整使用方法。通过学习基本语法、逻辑运算符、实际应用示例和JavaScript API,开发者可以更精确地控制样式在不同浏览器中的表现,实现渐进增强的网页设计。

核心知识点总结

知识点内容说明
基本语法@supports (property: value) { /* styles */ }
not运算符检测浏览器是否不支持某个CSS特性
and运算符检测浏览器是否同时支持多个CSS特性
or运算符检测浏览器是否至少支持一个CSS特性
复合条件使用括号组合多个逻辑运算符,明确优先级
JavaScript API使用CSS.supports()方法进行JS特性检测
应用场景渐进增强、浏览器兼容性处理、前缀检测
回退方案始终为不支持的情况提供合适的回退样式
浏览器支持现代浏览器普遍支持,需为旧浏览器提供回退