配了多年属性选择器,今天才知道 [data-status=”active”] 里的写法一直有坑——CSS 今天终于把大小写这件事说清楚了

配了多年属性选择器,今天才知道 [data-status="active"] 里的写法一直有坑——CSS 今天终于把大小写这件事说清楚了

写过 CSS 属性选择器的工程师都踩过这个坑:[data-value="ABC"] 能选中吗?在 HTML 里答案是「看情况」——HTML 属性值对大小写不敏感,data-value="ABC" 和 data-value="abc" 在 HTML 文档里是同一个属性,[data-value="ABC"] 会把两者都选上。以前要精确匹配只能绕道 JS 或者依赖文档类型。今天 CSS 规范把这件事彻底说清楚了:你可以用 s(大小写敏感)和 i(大小写不敏感)两个标识符显式声明匹配行为,不再依赖隐式规则。

以前的坑

HTML 属性选择器 [attr=value] 在 HTML 文档里的行为是大小写不敏感的,因为 HTML 属性值本身就是不区分大小写的。这是规范定义的,不是浏览器 bug。

/* 以为是精确匹配,实际会把 data-role="ADMIN" 和 data-role="admin" 都选中 */
[data-role="admin"] { color: red; }

/* 在 HTML 文档里,这两个声明是等价的 */
[data-role="Admin"] { color: red; }   /* 同样会命中 data-role="ADMIN" */

但在 XML/XHTML 文档里,[attr=value] 是大小写敏感的——这意味着同样的 CSS 选择器在不同文档类型下行为不一致,是潜在的跨文档类型 bug 源。

今天 s 和 i 标识符把规则显式化了

CSS 选择器规范引入了两个标识符,让开发者显式控制大小写行为:

/* 大小写敏感:只有 data-role="admin" 被选中,"ADMIN"/"Admin" 不会命中 */
[data-role="admin" s] {
  color: red;
}

/* 大小写不敏感:data-role="admin"/"ADMIN"/"Admin" 都会被选中(HTML 默认行为显式声明) */
[data-value="ABC" i] {
  border: 1px solid blue;
}

标识符写在属性值后面,用空格分隔:

[attr=value s]  /* s = sensitive,大小写敏感 */
[attr=value i]  /* i = insensitive,大小写不敏感,默认在 HTML 文档里就是 i */

典型使用场景

场景一:精确的权限/角色匹配

<div data-user-role="admin">管理员</div>
<div data-user-role="Admin">管理员(另一个系统)</div>
<div data-user-role="ADMIN">管理员(大写)</div>
/* 只要小写的 admin,不要大写变体 */
[data-user-role="admin" s] {
  background: green;
  color: white;
}

场景二:枚举值枚举(表单状态)

<select name="status">
  <option data-status="active" selected>激活</option>
  <option data-status="Active">激活(备用写法)</option>
  <option data-status="ACTIVE">激活(全大写)</option>
</select>
/* 精准匹配激活状态,不要误中其他大小写变体 */
[data-status="active" s] { font-weight: bold; }

场景三:大小写不敏感的降级方案

/* 当某些系统给你的值是大写时,显式声明不敏感匹配 */
[data-system="github" i] { filter: grayscale(0.3); }
/* 同时精确匹配小写版本 */
[data-system="github"] { filter: grayscale(0.3); }

浏览器支持

浏览器 支持情况
Safari 9+
Chrome 113+
Firefox 113+
Edge 113+

Safari 技术预览 158 的变更说明确认 WebKit 持续支持该特性。所有主流浏览器均已支持,s/i 标识符已成为 CSS 选择器的标准组成部分,可直接使用。

三步落地

  1. 替换隐式写法:把 [data-role="admin"] 改成 [data-role="admin" s],消除 HTML 文档下的大小写隐式匹配
  2. 枚举值加敏感标识:涉及枚举值的属性选择器全部加上 s,防止数据源大小写不一致导致的样式 bug
  3. 降级兜底:不支持的旧浏览器里 s/i 会被忽略(按 HTML 隐式不敏感处理),样式不失效,只是少了精确保障——不兼容率低于 1%,可以忽略
/* 推荐写法:精确匹配,加 s */
[data-status="active" s] {
  background: #e6fffa;
  border: 1px solid #059669;
}

/* 渐进增强:再加一条隐式的,防止数据里有大写变体漏掉 */
[data-status="Active"],
[data-status="ACTIVE"] {
  background: #fef3c7;
  border: 1px solid #d97706;
}

s 和 i 标识符的价值不只是「修 bug」——它把 CSS 选择器的大小写行为从隐式约定变成了显式声明,跨文档类型、跨数据源的一致性从此有据可查。上线后可以跑一遍 [attr=value] 选择器清单,把涉及枚举值的加上 s,一次性消除潜在的大小写雷区。

评论区

0 条评论

登录后可评论。