你以为 CSS 的 attr() 只能读文字?今天 Firefox 155 把这件事彻底原生化了

做过前端组件化的都知道,数据驱动的样式有多难搞。一个按钮组件,宽高、颜色、字体大小全都要通过 props 传进来,再转成 class 或 style 加到 DOM 上。要是能直接在 HTML 上声明这些值,让 CSS 自己读,多好。

这件事,attr() 本来就能做。但长期以来它只能用在 content 属性上,其他属性想读 HTML 属性值?只能靠 JS。Firefox 155 今天把这件事彻底原生化了——attr() 现在可以用在任意 CSS 属性里了。

attr() 扩展到任意属性

CSS Values and Units Level 5 规范让 attr() 从 content 的专属变成了通用工具。现在你可以这样写:

/* 读一个带单位的数值属性 */
.card {
  width: attr(data-width px);
  height: attr(data-height px);
}

/* 读纯数字属性 */
.badge {
  font-size: attr(data-size type(<number>));
}

/* 带默认值 */
.avatar {
  width: attr(data-size rem, 2);
  opacity: attr(data-active type(<number>), 1);
}

/* 读字符串属性 */
.card::before {
  content: attr(data-title);
}

/* 在容器查询里用 */
@container style(attr(data-theme) = dark) {
  .card {
    background: #1a1a1a;
  }
}

对应的 HTML:

<div class="card" data-width="200" data-height="150">
  卡片
</div>

<div class="badge" data-size="14">
  徽章
</div>

CSS 引擎直接读 HTML 属性的值,不需要 JS 中转。属性值会按声明的类型(px、rem、number、color 等)解析成对应的 CSS 值,类型对不上就启用回退值。

实际使用场景

组件数据绑定: 把设计系统的 token 写在 HTML data 属性上,CSS 直接消费。修改主题色不用动 CSS,只要改 HTML 属性。

响应式容器查询: attr() 可以塞进容器查询的条件里,用 data 属性做样式开关,替代传统的 class 切换。

无障碍高对比度适配: 根据 data-theme 属性自动切换配色,CSS 读属性值驱动主题切换,比 JS 监听变化再改 class 更可靠。

SVG 颜色控制: 用 namespaced attr 读 SVG 元素的属性,fill: attr(svg|fill color, #000) 这样直接驱动图形颜色。

浏览器支持

Chrome 133+、Firefox 155+ 已稳定支持。Safari 暂未支持,全球覆盖率约 67%。Chrome for Android 152+、Firefox for Android 155+ 也已支持。

渐进增强写法:

.card {
  /* 不支持的浏览器走默认宽度 */
  width: 300px;
  width: attr(data-width px, 300px);
}

和 JS 方案对比

传统 JS 方案:

const card = document.querySelector(.card);
card.style.width = card.dataset.width + px;

CSS-only 方案:

.card {
  width: attr(data-width px);
}

JS 不介入样式计算,属性值变了 CSS 自动响应,还不会被 JS 错误影响。

下一步

下次写可复用组件时,试试把尺寸、颜色等设计变量写在 data 属性里,让 CSS 自己消费。一个原则:数据能放 HTML 就别放 JS,CSS 读得比 JS 改得更可靠。

Firefox 155 之后,attr() 终于不是一个只能读文字的残缺 API 了。

评论区

0 条评论

登录后可评论。

阿柯·前端架构 13 阅读