在网页排版中,无序列表和有序列表默认由浏览器生成圆点、数字等标记。当设计稿要求标记使用特定颜色、字体或图标时,过去通常借助list-style:none再配合::before伪元素来模拟。CSS标准提供的::marker伪元素,让开发者可以直接针对标记盒子本身设置样式,既保留原生列表语义,又获得精细的控制能力。

一、::marker伪元素的基本用法与可用属性
::marker是应用于列表项(<li>)的标记盒子的伪元素。要使其生效,列表项必须处于display:list-item状态,这也是<li>的默认显示类型。通过li::marker选择器,我们可以修改标记的文本颜色、字号、字体等。需要注意的是,并非所有CSS属性都能用于::marker,规范目前仅允许与文本和字体相关的部分属性,例如color、font-size、font-weight、font-family、content等。
下面的示例将无序列表的默认黑点改为蓝色、放大字号,并切换为等宽字体:
ul.custom > li::marker {
color: #2b6cb0;
font-size: 1.4em;
font-family: 'Courier New', monospace;
}
从渲染原理看,::marker所控制的盒子独立于列表项的主体内容盒子,因此修改其样式不会影响文本布局回流。与早年用::before绝对定位模拟符号相比,这种方式不需要额外计算位置,也不会因为换行而产生对齐偏差。不过开发者应当注意,background、border等盒模型属性在多数浏览器中并不支持用于::marker,若需要复杂图形标记,仍要回归::before方案。
二、使用content与counter生成自定义序号和符号
除了修改已有标记外观,::marker的content属性允许我们完全替换标记内容。结合CSS计数器(counter),可以制造出跳过默认样式、由脚本逻辑无关纯CSS驱动的有序标记。例如将有序列表替换为“第N步”的中文描述,或者为无序列表赋予自定义字符。
以下代码演示了用计数器生成带括号数字的有序标记:
ol.step {
counter-reset: step;
list-style: none;
}
ol.step > li {
counter-increment: step;
}
ol.step > li::marker {
content: '(' counter(step) ') ';
color: #c53030;
font-weight: bold;
}
这里先将list-style设为none以隐藏原生数字,再通过counter-increment在每项递增,最后::marker的content引用该计数器。这种写法的优势是标记文本可随字体设置缩放,且屏幕阅读器仍能识别为列表结构。与之对比,若用::before写入序号,部分辅助技术可能将其视为普通文本节点,降低语义完整性。
对于无序列表,也可直接写content: '★ '来替换圆点。但要注意content中若包含特殊字符,需确认文件编码为UTF-8,否则可能出现乱码。另外,当content设置为空字符串时,标记盒子仍然存在但不可见,此时列表项左内边距可能需要手动调整以避免留白过大。
三、兼容性现状与渐进增强实践
尽管::marker已被纳入CSS Pseudo-Elements Level 4,但浏览器支持并不完全统一。Chromium系与Firefox很早就实现了基础能力,而Safari在较新版本才完善content修改支持。在旧版WebView或某些嵌入式浏览器中,针对::marker的样式可能被忽略,列表回退为默认符号。
为应对这种差异,推荐采用渐进增强思路:先写一条基础的list-style-type声明保证所有环境有合理符号,再用@supports检测::marker支持情况,将精细样式包裹其中。示例结构如下:
ul.base {
list-style-type: square;
}
@supports (selector(::marker)) {
ul.base > li::marker {
color: #38a169;
font-size: 1.2em;
}
}
这种写法下,不支持的浏览器仅看到方块符号,支持的浏览器则获得绿色放大标记,不会破坏布局。此外,在需要图标类标记的场景,如果::marker无法实现,应当准备::before模拟方案作为补充,而非强行使用background-image于::marker(因其支持度极低)。综合来看,::marker适合颜色、字体、文本类自定义,复杂图形仍要传统手段,理解边界才能写出稳健的列表样式代码。
CSS::markerlist-style修改时间:2026-08-15 05:06:23