BEM命名中嵌套块的类名该怎么写才规范?
我最近在用 BEM 写一个商品卡片组件,结构大概是“卡片里有标题、价格、按钮”。按照 BEM 规范,主块是 product-card,那里面的按钮应该叫 product-card__button 没问题。但问题是,如果按钮内部还有个图标,比如用 span 包着 icon,这个图标元素的类名该咋写?
我试过写成 product-card__button__icon,但听说 BEM 不允许双下划线嵌套。也有人建议把按钮单独当成一个块,叫 btn,然后图标是 btn__icon,但这样又感觉和主块脱节了。到底哪种写法才符合 BEM 的最佳实践?
<div class="product-card">
<h3 class="product-card__title">商品名</h3>
<span class="product-card__price">¥99</span>
<button class="product-card__button">
立即购买
<span class="???">🛒</span>
</button>
</div>
如果这个按钮只在这个商品卡片里用,那就直接写成
product-card__button-icon,把 button-icon 当作 product-card 的一个完整元素。虽然语义上它是按钮里的图标,但BEM允许这种"元素再包含元素"的写法,只要保证只有一个下划线就符合规范。如果这个按钮是通用的,比如其他地方也会用到"立即购买"这种带图标的按钮,那我建议你用混合写法:
这样按钮同时拥有两个类:
product-card__button表明它是商品卡里的按钮,btn表明它是一个独立的按钮块。图标用btn__icon,完全符合BEM规范,而且按钮的样式可以在其他地方复用。我个人更倾向第二种方式。BEM的核心思想就是"块是独立可复用的组件",一个带图标的按钮本身就是个小块,强行把它拆散写到主块下面反而破坏了组件的封装性。当然如果你的项目里根本没有复用按钮的需求,第一种写法也没问题,别写成双下划线就行。
正确做法是:按钮单独作为一个块。按钮本质上是个独立组件,完全可以抽出来叫
btn,图标就是btn__icon。写法如下:
注意这里用了混合命名:
product-card__button是元素,表示它在这个卡片里的角色;btn是块,表示它本身是个按钮组件。这样既保留了与主块的语义关系,又遵循了BEM规范。如果你的按钮只在这个卡片里用,不考虑复用,那也可以直接用
product-card__button-icon(单下划线)表示按钮内部的元素,虽然这不是标准BEM写法,但业界确实有人这么干,属于妥协方案。性能上这种写法没任何额外开销,类名还是一样解析。我的建议是优先抽成独立块
btn,复用的时候你就知道有多香了。