SCSS BEM组件问题:如何在.message--success内选择.message父元素
解决SCSS+BEM中修饰符内部无法选中元素的问题
嘿,我完全懂你碰到的这个坑——这其实是SCSS里&符号的指代逻辑在搞怪!
为什么原来的写法不生效?
当你在.message--success这个修饰符内部写&__title时,&此时指代的是当前层级的选择器也就是.message--success,所以编译后会生成.message--success__title这种选择器,但你的HTML里对应的元素是.message__title,两者完全不匹配,自然不会生效。
你的HTML结构是同一个元素上同时有block类.message和modifier类.message--success,所以正确的选择逻辑应该是:当.message拥有.message--success修饰符时,它的子元素.message__title和.message__content要改变样式。
几种可行的解决方法
方法1:直接写后代选择器(简单直接)
在修饰符内部,直接用block类选择子元素:
.message { display: block; width: 300px; border-radius: 5px; border: 2px solid #000; padding: 10px; &__title { font-size: 18px; line-height: 1; color: #000; margin-bottom: 10px; } &__content { font-size: 15px; color: #000; } &--success { border-color: #3f9442; // 直接用.message__title作为后代选择器 .message__title { color: #3f9442; } .message__content { color: #3f9442; } } }
编译后会生成.message--success .message__title,完美匹配你的HTML结构。
方法2:用变量存储block名称(更易维护)
如果担心后续block名称需要修改,可以先把block名存成变量,这样只需要改一次变量就能同步所有地方:
$block-name: message; .#{$block-name} { display: block; width: 300px; border-radius: 5px; border: 2px solid #000; padding: 10px; &__title { font-size: 18px; line-height: 1; color: #000; margin-bottom: 10px; } &__content { font-size: 15px; color: #000; } &--success { border-color: #3f9442; .#{$block-name}__title { color: #3f9442; } .#{$block-name}__content { color: #3f9442; } } }
方法3:结合&和后代选择器(语义化更强)
利用&指代当前修饰符,再结合后代选择器,写法更清晰:
.message { // 基础样式... &__title { /* ... */ } &__content { /* ... */ } &--success { border-color: #3f9442; // &代表.message--success,所以& .message__title就是修饰符下的子元素 & .message__title { color: #3f9442; } & .message__content { color: #3f9442; } } }
编译结果和方法1完全一致,只是写法上更强调“修饰符下的子元素”这个逻辑。
总结
核心就是搞清楚SCSS中&在不同嵌套层级的指代对象——在修饰符内部时,&是.message--success,而不是.message,所以不能直接用&__title,必须通过后代选择器来关联原block的子元素。
内容的提问来源于stack exchange,提问作者vladys.bo
相关产品推荐
相关产品推荐

