轮播图bem结构必须严格按语义划分为container、track、item、indicator、control五类,各司其职;container仅设宽高与overflow,track负责位移与布局,item仅作锚点不控显隐,indicator与control须同属carousel块,垂直轮播应新建carousel-vertical块而非用修饰符。

轮播图的 BEM 元素不能按“视觉位置”或“DOM 层级”随意拆分,必须按语义职责严格划分:容器、轨道、项目、指示器、控制项这五类节点各司其职,缺一不可,混用或省略会导致 JS 控制失准、样式泄漏、移动端事件委托失效。
carousel__container 和 carousel__track 必须分离,且职责不可互换
很多人把宽高、overflow、transform 全塞进同一个 class,结果动画卡顿、JS 计算 offsetLeft 偏差 2px、切换时闪一下——根本原因是 container 承担了本该由 track 负责的位移逻辑。
-
carousel__container只设width/height、overflow: hidden、position: relative;不写任何transform、scroll或flex相关样式 -
carousel__track必须用display: flex或white-space: nowrap防止子项换行;宽度 = 单张图宽 × 图片数;所有位移(transform: translateX()或scrollLeft)只在这里发生 - 性能提示:
carousel__container可加will-change: transform,但仅当内部carousel__track确实高频触发transform动画时启用,否则反而拖慢渲染
carousel__item 不是“隐藏/显示开关”,而是布局锚点
错误做法是给 carousel__item 写 display: none 或 visibility: hidden 来控制显隐——这会让 CSS 无法参与过渡动画,JS 切换时出现跳帧,且破坏了 flex 容器对齐逻辑。
-
carousel__item只定义基础尺寸(flex: 0 0 100%)、transition、z-index;不管理可见性 - 显隐状态由 JS 控制
carousel__item--active(注意双下划线),CSS 里只写.carousel__item--active { opacity: 1; z-index: 2; } - 禁止用
nth-child(n)查找当前项;稳定写法是document.querySelectorAll('.carousel__item')[index],与 slide 索引完全同步
指示器和控制项必须同属 carousel 块,禁止单独抽象
把 carousel__indicator 和 carousel__control 拆成两个独立块(比如 dot 和 carousel-control),会导致状态不同步、样式作用域断裂、事件委托无法统一绑定到 .carousel 根节点。
- 指示器命名只能是
carousel__indicator,激活态为carousel__indicator--active(不是carousel__indicator-active) - 左右按钮统一用
carousel__control,方向靠修饰符区分:carousel__control--prev/carousel__control--next;禁用状态单独用carousel__control--disabled,不与方向耦合 - 移动端 touch 事件必须委托到
.carousel__indicator和.carousel__control—— 类名不稳定,event.target.closest()就会匹配失败
垂直轮播不是 carousel--vertical,而是新块 carousel-vertical
用修饰符 --vertical 强撑垂直场景,会在 CSS 里堆满 @media + flex-direction: column + transform: translateY() 分支,JS 里也要不断判断 isVertical,最终维护成本翻倍。
- 水平轮播保持
carousel块名,垂直场景另起carousel-vertical块 - 新块拥有完整子结构:
carousel-vertical__indicator、carousel-vertical__track、carousel-vertical__control - 共用基础工具类(如
is-hidden、is-swiping),但结构样式、轴向 transform、分页计算逻辑彻底隔离
最常被忽略的一点:BEM 不是命名游戏,而是接口契约。只要 carousel__indicator 这个 class 名在 HTML 中存在,它就必须能被 JS 通过固定选择器获取、被 CSS 通过固定规则控制、被移动端 touch 事件精准捕获——少一个下划线,或错用一次 nth-child,整个轮播的状态同步链就断了。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











