Chrome/Firefox 不支持 attr(data-xxx),仅 Safari 16.4+ 支持且需显式类型;兼容方案是用 attr() 中转至 CSS 变量再通过 var() 引用。

content: attr(data-xxx) 为什么显示空白或字面量
直接写 content: attr(data-label) 却看到空白、或甚至文字 “attr(data-label)” —— 这不是 bug,是规范行为。Chrome/Firefox 目前(2026 年)**不支持**对 data- 属性的 attr() 读取;它们只认 HTML 内置属性(如 title、alt)。Safari 16.4+ 才开始支持 attr(data-label string),且必须显式声明类型(string、url 等)。
常见误写:
-
content: attr(data-price)→ Chrome/Firefox 静默返回空字符串 -
content: attr("data-price")→ 引号让浏览器当字面量,输出就是"data-price" -
content: attr(price)对应data-price="199"✅(但仅 Safari 支持,且需加类型)
真正兼容的写法:data-* → CSS 变量 → var()
绕过 attr() 限制的稳定路径,是把 data- 值“中转”进 CSS 自定义变量,再用 var() 在 content 中引用。这需要 HTML 和 CSS 协同,但兼容所有现代浏览器(包括 Safari/Chrome/Firefox)。
HTML 示例:
立即学习“前端免费学习笔记(深入)”;
<button data-tip="删除">操作</button> <span data-count="42"></span>
CSS 示例:
button::after {
content: var(--tip, "…");
}
span::after {
content: var(--count, "0") " 条";
}
<p>/<em> 中转层:从 data- 属性映射到 --var </em>/
button {
--tip: attr(data-tip string);
}
span {
--count: attr(data-count string);
}注意:--tip 和 --count 是普通 CSS 变量,可被 var() 安全读取;而 attr() 只出现在中转声明里(非伪元素),此时它只是赋值工具,不参与渲染逻辑。
attr() 在伪元素里只能用于 content,且永远是字符串
就算你成功让 attr(data-label) 返回了值,它也只能用在 ::before 或 ::after 的 content 属性中,其他地方无效:
-
div { color: attr(data-color); }→ 浏览器忽略,无报错 -
div::before { width: attr(data-width) px; }→ 语法错误,attr()不返回带单位的数值 -
content: attr(data-size) "px";→ 输出是"16 px"(含空格),不是"16px"
数值、颜色、布尔值都得靠 JS 或 CSS 变量 + 条件类来驱动,attr() 只负责“吐字符串”。
data- 属性名大小写和连字符必须严格匹配
CSS 选择器和 attr() 对属性名是 ASCII 逐字符比对,大小写敏感、连字符不可省略:
- HTML 写
data-user-id="123"→ CSS 必须用attr(user-id),不能写attr(userid)或attr(UserId) -
data-tooltip-text对应attr(tooltip-text),不是attr(tooltipText) - JS 的
dataset.userId是驼峰转换结果,和 CSS 的attr()参数无关
最容易被忽略的是:动态插入元素后,若只改 dataset 而没调用 setAttribute('data-user-id', '123'),attr() 就不会更新——CSS 只响应 attribute 变更,不监听 property。



















