是唯一语义化标记搜索关键词的原生HTML元素,需成对使用、避免嵌套与大段包裹,动态插入时须转义字符并用textContent+insertAdjacentHTML防XSS,CSS覆盖需提高选择器权重。

怎么用 mark 标签高亮搜索关键词
浏览器原生支持的 mark 是唯一语义化标记搜索结果的 HTML 元素,不是 span 加 class,也不是 em 或 strong。它明确告诉辅助技术“这段是匹配到的关键词”,也方便后续 CSS 精准控制样式(比如只给 mark 加背景色,不影响其他强调逻辑)。
常见错误是手动拼接字符串时漏掉闭合标签,或在富文本中嵌套使用导致结构错乱。注意:它不能替代服务端高亮逻辑,只是前端渲染层的语义容器。
- 必须成对出现:
关键词,不能写成自闭合 - 不要包裹大段内容——
mark语义是“突出显示匹配片段”,不是“整段高亮” - 若关键词含 HTML 字符(如
&、),先做实体转义再塞进mark,否则破坏 DOM 结构
JavaScript 动态插入 mark 时怎么避免 XSS 和标签错位
用 innerHTML 直接拼接用户输入的关键词 + mark 标签,等于主动开后门。真实场景里,搜索词可能带 <script></script> 或 onerror,一渲染就执行。
正确做法是先创建元素,再设文本内容,绕过 HTML 解析阶段:
function highlight(text, keyword) {
const escapedKeyword = keyword.replace(/["'\/]/g, c => `&${{ '': 'gt', '"': 'quot', "'": '#39', '/': '#47' }[c]};`);
return text.replace(new RegExp(`(${escapedKeyword})`, 'gi'), '<mark>$1</mark>');
}
// ⚠️ 错误:直接 innerHTML += highlight(str, userInput)
// ✅ 正确:用 textContent 设原始文本,再用 insertAdjacentHTML 插入已转义的 mark 片段
- 正则匹配前,确保
keyword已转义特殊字符(.、*、?等会破坏正则逻辑) - 多个关键词连续匹配时,
mark不能嵌套——浏览器会自动闭合前一个,导致样式断裂 - 用
textContent+insertAdjacentHTML组合,比纯innerHTML更可控
CSS 控制 mark 样式时为什么 background-color 不生效
部分浏览器(特别是旧版 Safari 和某些 Android WebView)对 mark 的默认样式有强干预,比如硬编码了 background-color: yellow 且用 !important,导致你写的 CSS 被覆盖。
- 必须用更具体的权重覆盖:比如
article mark或main :not(.no-mark) mark - 避免只写
mark { background: #ffeb3b; }——太弱,容易被 UA 样式压制 - 如果要透明底色,记得同时重置
color,否则文字可能因对比度不足看不清 - 不建议用
mark::before/after伪元素——语义上无意义,且部分读屏器不识别
服务端返回已高亮 HTML 时,mark 标签要不要保留
要。只要服务端输出的是合法、闭合、未被转义的 ,前端直接 innerHTML 渲染即可,语义和可访问性都完整。但前提是服务端做了输入过滤和标签白名单校验。
容易踩的坑是:后端用模板引擎拼接时,自动对所有输出做了 HTML 转义,结果页面上显示的是字面量 ,而不是真实标签。
- 检查响应体里是否真有
字符串,而不是转义后的 - 前后端约定:高亮字段单独返回(如
highlighted_title),而非混在富文本里靠正则提取 - 若服务端无法保证安全,宁可在前端用纯文本 + JS 高亮,也不信它吐出的 HTML
最麻烦的其实是多音字、大小写、全半角、Unicode 变体这些——mark 标签本身没能力做模糊匹配,它只负责包裹你给它的那一段精确字符串。这部分得靠搜索服务预处理,前端别硬扛。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











