富文本容器不能直接套bem类名,必须将bem作用域前置到父级wrapper上,通过封装函数生成合法类名、映射标签约束、属性钩子桥接第三方库,并仅在wrapper上使用修饰符。

富文本容器本身不能直接套BEM类名
因为微信小程序等环境会剥离或重写HTML结构,你写的 .article-content__text 很可能被解析器丢弃,或只保留内联样式和白名单标签。BEM依赖的是「开发者可控的类名注入」,而富文本渲染走的是HTML→WXML节点树转换流程,中间没有CSS类名落地环节。
常见错误现象:document.querySelector('.article-content__text') 查不到节点;DevTools里看到的全是 rich-text 或 view 标签,没有你定义的BEM类。
- 必须把BEM作用域前置到富文本容器的父级 wrapper 上,例如
<view class="article-content"><rich-text nodes="{{nodes}}"></rich-text></view> - 所有样式规则都基于
.article-content这个 block 展开,比如.article-content__heading不能指望富文本内容里自带这个类,而是靠 JS 解析后手动注入 - 禁止在
<rich-text></rich-text>的nodes数组里硬塞class: 'article-content__paragraph'—— 小程序会过滤掉非白名单属性,这类 class 不生效
解析HTML时用BEM生成节点类名要防手拼漏洞
动态拼接类名是高危操作,尤其在富文本这种结构不可控场景下。一个空格、少个下划线、大小写错位,都会导致样式失效且难以定位。
危险写法:className: `article-content__${tag} ${isBlock ? 'article-content__block' : ''}`(漏空格、tag 值为 IMG 大写、article-content__block 实际并不存在)
- 必须封装生成函数,例如:
const cn = (e, m) => `article-content${e ? '__' + e : ''}${m ? '--' + m : ''}`,调用cn('paragraph', 'centered')→article-content__paragraph--centered - 对原始HTML标签做映射表约束,只允许
h1→heading、p→paragraph、img→image,拒绝未声明的 tag - 所有生成的类名必须通过
stylelint-selector-bem-pattern校验,CI 中跑npx stylelint "**/*.css"拦截.article-content__p这类非法写法
第三方解析库输出的类名不满足BEM怎么办
像 wxParse、mp-html 默认输出的类名如 wxp-p、html-img 是非BEM结构,直接覆盖会破坏隔离性,也违背团队规范。
正确做法不是改库源码,而是在 wrapper 层做语义桥接:
- 给
<rich-text></rich-text>外层加class="article-content",再用属性选择器局部接管:.article-content > .wxp-p { composes: article-content__paragraph from './article-content.module.css'; }(CSS Modules 场景) - 若用普通 CSS,写
.article-content .wxp-p→ 立即触发 warning:后代选择器破坏BEM封装性;应改为用:where(.article-content) .wxp-p降权,或换用data-bem="paragraph"自定义属性做钩子 - 绝对不要全局替换第三方类名,例如把所有
.html-img改成.article-content__image—— 这会导致其他页面的富文本样式意外联动
BEM修饰符用于主题切换时别碰富文本内部状态
富文本内容本身不具备“主题感知”能力,.article-content--dark .article-content__text 可以生效,但 .article-content__text--dark 如果是解析时动态加的,就容易和用户粘贴进来的 <span style="color:#333"></span> 冲突。
- 修饰符只挂载在 wrapper 上,例如
<view class="article-content article-content--dark"></view>,所有子元素通过继承或上下文响应 - 禁止给富文本节点加状态类如
--error、--loading—— 这些属于逻辑状态,应由业务组件控制,不是富文本容器职责 - 如果需要高亮某段文字,用
data-highlight="true"这类语义属性,配合.article-content [data-highlight]选择器,避免污染BEM命名空间
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











