class属性用于指定元素的类名,主要关联CSS样式或JavaScript操作;可多值空格分隔,命名须以字母开头,后接字母、数字、连字符或下划线。

HTML属性本身没有“优先级”概念,所谓“属性绑定优先级”其实是 DOM 属性写入顺序 + 框架介入时机 + 浏览器解析规则共同作用的结果;真正在冲突中起决定性作用的,是 element.setAttribute、element.className、element.style 这些底层 API 的调用先后,以及框架是否劫持了这些操作。
为什么 class 和 className 会打架
原生 DOM 中,className 是 class 属性的 JS 反射,二者指向同一内存位置。但框架(如 React/Vue)通常不直接操作 className,而是通过 setAttribute('class', ...) 或虚拟 DOM diff 后批量更新。一旦你在 HTML 里写了 class="a b",又在 JS 里执行 el.className = 'c',前者就被彻底覆盖——不是“优先级低”,是被重写。
-
class="a b"是初始值,只在首次解析时生效 -
el.className = 'c'是运行时赋值,直接替换整个字符串 - Vue 的
:class="{a: flag}"或 React 的className={cls}本质也是运行时计算后调用setAttribute,同样会覆盖初始值 - 若想保留初始 class,得手动拼接:
el.className = el.className + ' c',或用classList.add()
style 属性为什么总赢过 CSS 类
因为 style 是内联样式,其特异性权重固定为 1000,而任何外部或内部 CSS 规则(包括 .btn { color: red !important; })都参与选择器匹配,权重最多到 0-1-0(类选择器)或 0-0-1(标签),根本无法与之竞争。浏览器根本不比较“谁更狠”,它直接跳过选择器匹配阶段,把 style 当作最终答案。
- HTML 中写
<div style="color: blue">→ 蓝色必生效 - 哪怕你写了
div { color: red !important; },也无效 - 唯一能覆盖它的,是另一段内联样式:
el.style.color = 'green',或同元素上另一个style属性(后者会覆盖前者) - React/Vue 的
style={{}}本质就是生成内联style,所以它天然压制所有 class 规则
动态绑定属性时,data- 和自定义属性容易踩的坑
HTML5 允许任意以 data- 开头的属性,但浏览器不会自动解析它们的值类型——全当字符串。如果你写 data-count="1",JS 里取出来是 "1",不是数字 1;写 data-active="true",取出来是字符串 "true",不是布尔值 true。
立即学习“前端免费学习笔记(深入)”;
- 不要依赖
getAttribute('data-active') === true,它永远是 false - 正确做法:
el.hasAttribute('data-active')判断是否存在,或JSON.parse(el.getAttribute('data-active'))强转(需确保值合法) - 框架如 Vue 的
v-bind:会自动做类型推导,但原生 JS 不会 - 用
dataset访问更安全:el.dataset.count→"1",el.dataset.active→"true",仍为字符串
真正难排查的,往往不是哪个属性“赢了”,而是某个属性压根没被写进 DOM——比如框架条件渲染未触发、JS 执行时机早于元素挂载、或者 setAttribute 被中间件拦截却没报错。这时候看 el.attributes 数组比看 DevTools 的 Styles 面板更直接。


















