概述/简介
什么是 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)");