modal--visible 必须加在 modal 块的根元素上,用于统一控制整个弹窗状态;子元素显隐应通过 CSS 选择器联动实现,避免分散状态导致视觉断裂。

modal--visible 该加在哪个 DOM 节点上
必须加在 modal 块的根元素上,不能加在 modal__overlay 或 modal__content 上。因为 --visible 表达的是整个弹窗组件的状态,不是某个子结构的局部表现。
常见错误是把状态分散到多个节点:modal__overlay--visible 和 modal__content--entering 同时存在,JS 需同步控制两个类,稍有延迟就会出现遮罩已显、内容未动的视觉断裂。
正确做法是只操作根节点:user-modal--visible,然后用 CSS 选择器联动子元素:
.user-modal--visible .user-modal__overlay { opacity: 1; visibility: visible; }
.user-modal--visible .user-modal__content { transform: translateY(0); }
这样动画节奏统一,状态边界清晰,也方便 React/Vue 中用单一 state 控制。
立即学习“前端免费学习笔记(深入)”;
modal__overlay--visible 是合法修饰符吗
是合法的,但仅限于作为 modal__overlay 这个 Element 的修饰符使用——它描述的是遮罩层自身的显隐状态,不改变 modal 块的整体语义。
关键约束有三点:
-
modal__overlay必须是modal的直属子元素,不能嵌套在modal__content里(如modal__content__overlay是非法结构) -
modal__overlay--visible的样式定义中不能包含 transition,否则隐藏时会跳变;transition 必须写在基础类modal__overlay里 - 若多个组件共用遮罩逻辑(如
drawer__overlay--visible),应复用同一套 CSS 规则,避免重复声明
button--primary 和 modal--visible 能否叠加使用
可以,但必须明确它们作用对象不同:button--primary 修饰的是 button 块,modal--visible 修饰的是 modal 块,二者无嵌套或依赖关系,属于跨组件并行状态。
真正容易出错的是在同一块上叠加冲突修饰符,比如:
-
modal--visible modal--loading:如果两个修饰符都控制opacity或visibility,CSS 规则权重可能互相覆盖 -
modal--visible modal--hidden:语义矛盾,文档需明确禁止这种组合 -
modal--visible和modal__content--hidden并存:违反 BEM 状态一致性原则,内容区隐藏应由父状态驱动,而非独立控制
修饰符叠加的前提是它们修改的 CSS 属性正交(如 --visible 控制显隐,--draggable 控制光标和拖拽行为),且规则不依赖选择器权重顺序。
为什么不能写 modal__overlay--blur 或 modal--glass
--blur 和 --glass 不是状态或变体,而是视觉效果叠加,不符合修饰符「表达同一组件的不同状态或变体」的核心定义。
正确做法是把毛玻璃效果封装为通用修饰符 --glass,并限定作用对象为 Block 级别:
-
modal--glass✅ 合法:表示整个弹窗容器启用毛玻璃背景 -
modal__overlay--glass❌ 错误:遮罩层加模糊会干扰点击穿透,且违背「背景模糊」的设计意图 -
modal__content--glass❌ 错误:内容区模糊会降低文字可读性,且无法与 backdrop-filter 的层叠上下文对齐
更关键的是,--glass 必须配套 isolation: isolate 和 background-color: rgba() 才能稳定生效,这些约束无法通过 Element 级修饰符可靠传递。


















