导航栏根元素应使用语义化Block名.admin-nav,而非泛化名.nav或.menu;其子元素按BEM规范命名:图标.admin-nav__icon、文字.admin-nav__label、徽标.admin-nav__badge及状态修饰.admin-nav__badge--unread;多级菜单用.admin-nav__submenu(非新Block),展开状态由.admin-nav__item--expanded控制;权限控制通过动态渲染或.admin-nav__item--disabled实现,避免反向类名。

导航栏根元素该用什么BEM结构?
后台管理系统的导航栏通常不是孤立组件,而是嵌套在 .app-layout 或 .admin-shell 中的子模块。直接写 .nav 会和全局样式冲突,也缺乏语义上下文。正确做法是把导航栏视为「后台壳」的一部分,根类名应为 .admin-nav(Block),而非 .nav。
- 必须避免使用泛化 Block 名,如
.menu、.sidebar—— 它们无法表达「这是后台左侧垂直导航」这一具体职责 - 如果系统支持多主题或嵌入式子应用,建议加命名空间前缀,例如
.crm-admin-nav - 不要为了“复用”强行抽象成
.ui-nav:后台导航的折叠逻辑、权限图标、路由高亮规则都高度定制,抽象反而增加维护成本
如何给带图标+文字+徽标的导航项写Element类名?
一个典型导航项包含图标、文字、右上角数字徽标(如消息未读数),且需支持展开/收起状态。BEM 要求每个视觉/行为单元对应一个明确的 Element,不能靠后代选择器拼凑。
- 图标部分用
.admin-nav<strong>icon</strong>,不写.admin-navitem-icon(__item是冗余层级) - 文字部分用
.admin-nav<strong>label</strong>,不用.admin-navtext(label更准确表达其作为菜单项标识的语义) - 徽标用
.admin-nav<strong>badge</strong>,并配合 Modifier 表达状态:.admin-navbadge--unread - 折叠时隐藏文字但保留图标,应通过 Modifier 控制:
.admin-nav--collapsed .admin-nav<strong>label</strong>,而不是新增.admin-navlabel--hidden(Modifier 应作用于状态,而非样式结果)
示例结构:
<li class="admin-nav__item">
<a href="/dashboard" class="admin-nav__link">
<span class="admin-nav__icon"></span>
<span class="admin-nav__label">仪表盘</span>
<span class="admin-nav__badge admin-nav__badge--unread">3</span>
</a>
</li>怎么处理多级菜单的嵌套与展开状态?
后台导航常见二级甚至三级菜单,且需要 JS 控制展开/收起。BEM 不鼓励用 .admin-nav__submenu 这种深层嵌套 Block,而应延续同一 Block 的 Element 层级。
立即学习“前端免费学习笔记(深入)”;
- 子菜单仍属于
.admin-nav的一部分,用.admin-nav__submenu(Element),不是新 Block - 展开状态统一由父级
.admin-nav<strong>item</strong>上的 Modifier 控制:.admin-navitem--expanded - 对应的子菜单显示逻辑写成:
.admin-nav<strong>item--expanded .admin-nav</strong>submenu,而非单独定义.admin-nav__submenu--visible - 避免在子菜单内部再定义
.admin-nav<strong>submenu</strong>item:这违反 BEM 原则(Element 不能再有子 Element),应保持为.admin-nav__item(同级复用)
注意:CSS 里不要写 .admin-nav<strong>item .admin-nav</strong>item 这种后代选择器——它破坏了 BEM 的可预测性,所有交互状态必须显式体现在类名中。
权限控制导致的动态类名该怎么组织?
后台导航项常根据用户权限动态渲染,比如「审计日志」只对管理员可见。这类逻辑不应侵入 CSS 类名设计,但会影响类名输出的稳定性。
- 权限隐藏的项,服务端或组件层直接不渲染 DOM,而不是加
.admin-nav__item--hidden-by-perm - 若必须保留在 DOM 中(例如前端权限校验),可用
.admin-nav__item--disabled+aria-hidden="true",但需确保 JS 不再绑定点击事件 - 绝对不要用
.admin-nav__item--has-permission这类反向类名:CSS 不该承担权限判断逻辑,它只响应已确定的状态
容易被忽略的一点:当导航项数量多(>20 项)且频繁切换权限时,用 BEM 类名拼接字符串生成 HTML 容易出错。建议封装一个 renderNavItem() 工具函数,统一注入 block、element、mods 参数,避免手写类名漏掉连字符或大小写错误。


















