attr()不能读取CSS自定义属性(--),仅支持HTML原生属性(如data-、title);在content外使用仍属实验性,Firefox仅支持content;读取--*须用JavaScript配合getComputedStyle()。

attr() 不能直接读取 CSS 自定义属性(--*)
这是最常被误解的一点:attr() 只能读取 HTML 元素的**原生属性值**(如 data-id、title、alt),完全无法访问通过 style="--color: red" 或 element.style.setProperty('--size', '2rem') 设置的 CSS 自定义属性。浏览器会静默失败,返回空字符串或默认值(取决于属性类型),且不报错。
如果你写了 content: attr(--theme),它不会报错,但结果一定是空 —— 因为 --theme 根本不是 HTML 属性。
想用 attr(),必须把数据存在 HTML 属性里(data-*)
正确做法是把需要驱动样式的元数据显式写在 HTML 中,再用 attr() 拉取。典型场景是生成伪元素内容、动态计数器、或配合 calc() 做简单计算:
-
data-width="80"→width: calc(attr(data-width) * 1px)(注意:CSS 中attr()返回值默认无单位,需手动拼接) -
data-label="删除"→::after { content: attr(data-label) } -
data-priority="high"→ 配合[data-priority="high"] { border-left: 4px solid #d32f2f; }实现样式分流
⚠️ 注意:attr() 在 content 外的大多数 CSS 属性中仍属实验性支持(如 width、margin),Chrome 和 Safari 支持较好,Firefox 目前仅支持 content。
立即学习“前端免费学习笔记(深入)”;
自定义属性(--*)该用什么读?靠 JavaScript + getComputedStyle()
如果数据已存在 CSS 自定义属性中(比如通过 JS 动态设置或 :root 定义),要读取它并用于逻辑判断或 DOM 更新,唯一可靠方式是 JS:
const el = document.querySelector('.card');
const computed = getComputedStyle(el);
const size = computed.getPropertyValue('--card-size').trim(); // 返回 "1.5rem"
const color = computed.getPropertyValue('--card-bg'); // 返回 "rgb(245, 245, 245)"
常见用途包括:
- 根据
--state值切换 class(避免重复写 CSS 状态类) - 将
--scale转为数字后传给 Canvas 或 SVG transform - 监听
style变化(需 MutationObserver,因getComputedStyle是只读快照)
真正想“结合”两者?得靠 JS 桥接,而非纯 CSS
没有纯 CSS 方案能让 attr() 和 --* 互通。但你可以用 JS 把自定义属性值同步到 data- 属性,再交给 attr() 使用:
function syncCssVarToDataAttr(el, cssVar, dataAttr) {
const val = getComputedStyle(el).getPropertyValue(cssVar).trim();
if (val) el.setAttribute(dataAttr, val);
}
// 同步 --mode 到 data-mode
syncCssVarToDataAttr(document.body, '--mode', 'data-mode');
之后就能安全使用:[data-mode="dark"] .header { color: white; } 或 .header::before { content: attr(data-mode); }。
这个桥接步骤容易被忽略——尤其当自定义属性由第三方库(如 Tailwind 的 dark mode toggle)动态修改时,若没主动同步,data- 属性就永远停留在初始值。


















