标签仅声明语义,高亮效果必须由显式css控制:需强制设置background-color、color、padding、border-radius四属性,并适配深色模式与高对比度模式,动态高亮须遍历文本节点且双重转义关键词。

mark 标签本身不负责排版,它只声明语义;真正控制高亮文字“怎么排”的是 CSS,且必须显式写,不能依赖浏览器默认值。
为什么直接写 <mark>文本</mark> 看起来不对
常见现象:文字被包进 mark 后背景色太紧、边缘生硬、深色模式下看不见、Windows 高对比度下变黑底黑字。这不是 bug,是浏览器默认样式在真实环境中不可交付。
- 原生
mark没padding,文字紧贴背景边缘,视觉上易误读 - 默认黄色(
#ff0)在暗色主题或 Outlook 邮件中完全失效 - CSS 重置规则(如
* { background: transparent })会清掉默认背景,但保留透明导致文字“消失” - 没设
color时,某些环境(如 Safari 阅读模式)会继承父级颜色,与背景对比不足
mark 的最小可用 CSS 必须包含这四条
以下样式不是“可选优化”,而是上线前必须写的底线配置:
mark {
background-color: #ffeb3b;
color: #212121;
padding: 0.1em 0.2em;
border-radius: 2px;
}
-
background-color和color必须同时声明,缺一不可——否则在禁用 UA 样式的环境里文字可能不可见 - 用
padding不用margin:mark是内联元素,垂直margin无效 -
border-radius是刚需,不加会导致高亮块边缘锐利,干扰阅读节奏 - 避免写
background: none,应写background-color: transparent,确保清空背景且不干扰background-image
深色模式和高对比度必须显式适配
仅靠上面四条还不够。用户开启深色主题或 Windows 高对比度设置后,mark 会立刻“隐身”或反色错乱。
- 深色模式补媒体查询:
@media (prefers-color-scheme: dark) { mark { background-color: #ffca28; color: #121212; } } - 高对比度模式需额外声明:
@media (forced-colors: active) { mark { background-color: Highlight; color: HighlightText; } } - 别指望
color: inherit—— 在某些邮件客户端或阅读器中,继承链会断裂,必须写死可读值
富文本中动态插入 mark 时,排版错乱的根源是 DOM 撕裂
如果高亮出现在含 <strong></strong>、<a></a> 或 <code> 的富文本里,用 innerHTML.replace() 直接拼字符串,会导致样式崩坏、标签被撕开、甚至 XSS。
- 错误做法:
el.innerHTML = el.innerHTML.replace(keyword, '<mark>$</mark>') - 正确路径:遍历纯文本节点(
node.nodeType === 3),对textContent做正则匹配,再用document.createElement('mark')插入 - 关键词必须双重转义:正则元字符(
[.*+?^${}()|[\]])和 HTML 特殊字符(&"'`=/)都要处理 - 多关键词高亮时,务必按长度降序排序(
keywords.sort((a, b) => b.length - a.length)),否则短词嵌套进长词,padding和border-radius会错位叠加
最常被忽略的一点:排版效果是否成立,取决于你有没有在所有上下文里验证过——不是只看 Chrome 普通模式,而是必须测 Windows 高对比度、Safari 阅读模式、Outlook 邮件渲染、以及屏幕阅读器播报是否仍能识别 “marked text”。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











