class属性中多个类名必须用ASCII空格(U+0020)分隔,其他符号或全角空格均导致后续类名失效;CSS中多类连写表示交集匹配,有空格则为后代选择器。

class属性里多个类名必须用单个英文空格分隔
浏览器只认 ASCII 空格(U+0020)作为 class 属性中多个类名的分隔符,其他任何符号都会让后续类名失效。写成 class="btn,primary" 或 class="btn;disabled",实际只生效 btn 这一个;中文全角空格(U+3000)直接被忽略,元素等于没加后几个类。
-
class="btn primary disabled"✅ 正确:三个独立类,可分别被.btn、.primary、.disabled单独匹配 -
class="btn-primary"✅ 合法,但这是**一个**类名,和btn、primary完全无关 -
class="btn primary"✅ 多个连续空格等效于一个,不影响解析 - 别用模板字符串拼接时漏掉空格:
className={`btn${isActive ? ' active' : ''}`容易产出btnactive
CSS选择器中多个类名连写表示“同时拥有”
.btn.primary 和 .primary.btn 效果完全一样,都只匹配 class="btn primary" 的元素;而 .btn .primary(中间有空格)是后代选择器,匹配的是 <div class="btn"><span class="primary"> 这种嵌套结构——语义完全不同,写错就选不到目标元素。
- 交集匹配不依赖顺序:
.card.featured和.featured.card都能命中<div class="card featured"> - 避免过度连写:
.card.header.active.loading虽然语法合法,但维护成本高,建议拆解为状态类 + 基础类组合 - BEM 场景下,
card card--hover card__title是错的——card__title是子元素结构类,不该和 Modifier 混在同一节点
JavaScript操作多 class 必须用 classList,别碰 className
直接赋值 el.className = "a b" 会清空所有已有类;用 el.className += " c" 容易引入重复空格或覆盖风险。classList 是专为此设计的 API,自动去重、静默容错、支持多参数。
-
el.classList.add("active", "highlight")—— 一次加多个,已存在也不报错 -
el.classList.remove("disabled", "pending")—— 不存在的类名不会抛错 -
el.classList.toggle("hidden")—— 更安全地切换开关类,不用先contains()再判断 - 别传带空格的字符串:
add("a b")会被当做一个类名a b,不是两个
服务端模板或 JSX 中拼接 class 容易漏掉 falsy 值导致空格错乱
条件拼接时,false、null、undefined 会被转成字符串 "false" 或空串,但首尾/中间多余空格会让浏览器解析出无效类名,比如生成 class="btn disabled"(两个空格)或 class="btn disabled "(末尾空格)。
立即学习“前端免费学习笔记(深入)”;
- React 推荐用
clsx:className={clsx("btn", { active: isActive, disabled: isDisabled })} - Vue 用对象语法:
:class="{ 'btn': true, 'active': isActive }" - 纯 JS 拼接时手动过滤:
["btn", isActive && "active", isDisabled && "disabled"].filter(Boolean).join(" ") - BEM 场景下,基础 Block 类(如
btn)必须始终存在,Modifier(如btn--loading)才可条件添加



















