::marker 伪元素仅在 Chrome 86+/Firefox 89+/Safari 15.4+ 中可用,旧版本静默忽略且无法通过 @supports 检测;需确保 li 为 display: list-item 并用 list-style-type: none 保留介入空间;兼容老环境须回退至 list-style: none + ::before 方案。

Chrome 86+/Firefox 89+/Safari 15.4+ 才真正可用
低于这些版本的浏览器会静默忽略整个 ::marker 规则,DevTools 里都看不到该伪元素面板。比如 Safari 15.3(对应 iOS 15.2)、Chrome 85、Firefox 79 —— 写了也白写,不报错、不警告、不 fallback。
微信内置浏览器(X5 内核)和部分 Android WebView 仍基于旧版 Chromium,同样不支持。不能靠 @supports (::marker) 检测:Safari 15.3 及更早版本连这个语法都不识别,@supports 会直接跳过整块规则。
验证是否生效最简单的方法是打开 DevTools → 选中 li → 看 Styles 面板里 ::marker 是否被划掉(strikethrough)。如果被划掉,要么不支持,要么被更高优先级规则覆盖。
ul 和 ol 的支持程度不一样
::marker 在 ol 中表现更稳定,content 支持 counter(list-item)、Unicode 字符、emoji 等;而 ul 下部分浏览器(尤其是旧版 Safari)对 content 值限制更严,可能直接 fallback 到默认圆点。
立即学习“前端免费学习笔记(深入)”;
常见翻车点:
-
ul li::marker { content: "→ " }在 Safari 15.3 渲染为空白,不是箭头也不是圆点 -
content: url(arrow.svg)在所有浏览器中均被忽略 ——::marker不支持url()或attr() -
ul上写了list-style: none,会彻底干掉 marker 渲染通道;必须改用list-style-type: none才保留::marker介入空间
display: list-item 是硬性前提
::marker 只作用于计算后 display 值为 list-item 的元素。一旦被破坏,样式立即失效:
- 父容器是
display: flex或display: grid,且未显式重置li的display -
li被设为display: block、display: inline或display: contents - CSS-in-JS 库或框架(如 Emotion、Styled Components)动态注入样式,意外覆盖了
li的默认display
检查方法:在 DevTools 的 Computed 面板里确认 li 的 display 最终值确实是 list-item,而不是继承或计算后的其他值。
兼容老环境必须用 list-style: none + ::before
只要项目需支持 iOS 16 或 Android WebView 旧版本,::marker 就不能当唯一方案。兜底写法要同时解决三件事:对齐、缩进、语义保留。
关键实操点:
-
li必须设list-style: none,否则原生符号和::before会并存 -
li::before推荐用position: absolute; left: -1.5em; top: 50%; transform: translateY(-50%),比float: left更可靠(尤其在 Flex/Grid 容器中) -
li要补padding-inline-start: 1.5em,值需与::before的left对齐,避免文字顶到图标上 - 别用
background-image模拟图标 ——line-height变化时定位偏移不可控
真正麻烦的不是怎么写新样式,而是怎么让 ::marker 和 ::before 共存且不冲突。很多团队用 PostCSS 插件自动注入回退规则,但要注意避免重复插入导致图标双显。


















