我在阅读Google 的 web.dev 博客上的“创意列表样式”,并注意到文章部分中的一个代码示例中有些奇怪::marker
。内置列表标记是项目符号、序数和字母。::marker
伪元素允许我们为这些标记设置样式或将其替换为自定义字符或图像。
::marker {
content: url('/marker.svg') ' ';
}
引起我注意的示例使用 SVG 图标作为列表项的自定义标记。但函数" "
旁边的 CSS 值中也有一个空格字符 ( ) url()
。这个空格的用途似乎是在自定义标记后插入一个间隙。
当我看到这段代码时,我立即想知道是否有更好的方法来创建间隙。在 中添加空格content
感觉更像是一种变通方法,而不是最佳解决方案。CSS 提供了margin
和padding
其他标准方法来在页面上分隔元素。在这种情况下,这些属性都不能用吗?
首先,我尝试用适当的边距替换空格字符:
::marker {
content: url('/marker.svg');
margin-right: 1ch;
}
这不起作用。事实证明,它::marker
仅支持一小部分主要与文本相关的 CSS 属性。例如,您可以更改标记的font-size
和,并通过设置为字符串或 URL 来定义自定义标记,如上所示。但是和属性不受支持,因此设置它们没有效果。真令人失望。color
content
margin
padding
空格字符真的是在自定义标记后插入间隙的唯一方法吗?我需要找出答案。在研究这个主题时,我发现了一些有趣的东西,我想在本文中分享。
添加填充和边距
首先,让我们确认margin
和元素padding
上要做什么。为此,我创建了一个测试页面。拖动相关滑块并观察列表标记两侧间距的影响。提示:随意使用“重置”按钮将所有控件重置为其初始值。<ul>
<li>
注意:浏览器默认对和元素应用逻辑属性padding-inline-left
。逻辑属性相当于具有从左到右内联方向的书写系统中的物理属性。在本文中,为了简单起见,我将使用物理属性40px
。<ol>
<ul>
padding-inline-start
padding-left
如您所见,padding-left
on<li>
会增加列表标记后的间隙。其他三个属性控制标记左侧的间距,换句话说,就是列表项的缩进。
请注意,即使列表项的padding-left
值为,标记后仍存在最小间隙。此间隙不能通过或0px
减小。最小间隙的确切长度取决于浏览器。margin
padding
总而言之,列表项的内容定位在与标记之间有浏览器特定的最小距离,并且可以通过padding-left
在 中添加 来进一步增加此间隙<li>
。
接下来,让我们看看将标记定位在列表项内时会发生什么。
在列表项内移动标记
该list-style-position
属性接受两个关键字:outside
,这是默认值,以及inside
,用于在列表项内移动标记。后者对于创建具有全宽列表项的设计很有用。
如果标记现在位于列表项内,这是否意味着onpadding-left
不再<li>
增加标记后的间隙?让我们来一探究竟。在我的测试页面上,list-style-position: inside
通过复选框打开 on。此更改对四个padding
和属性有何影响?margin
如您所见,padding-left
现在增加了标记左侧<li>
的间距。这意味着我们失去了增加标记后间隙的能力。在这种情况下,能够添加到本身会很有用,但这并不奏效,正如我们上面所确定的那样。margin-right
::marker
此外, Chromium 中有一个错误,在切换到定位后,会导致标记后的间隙增加三倍inside
。默认情况下,间隙的长度约为文本大小的三分之一。因此,在默认的 下font-size
,16px
间隙约为5.5px
。切换到 后,间隙在 Chrome 中inside
会完全增大。此错误会影响、和标记,但不会影响序数标记。16px
disc
circle
square
下图显示了 macOS 上三个主流浏览器对位于外部和内部的列表标记的默认渲染。为了方便起见,我已将所有列表项与其标记水平对齐,以便于比较间隙大小的差异。
总而言之,切换到list-style-position: inside
会带来两个问题。我们无法再通过 来增加间隙padding-left
,<li>
并且不同浏览器之间的间隙大小不一致。
最后,让我们看看用自定义标记替换默认列表标记时会发生什么。
切换到自定义标记
定义自定义标记有两种方法:
list-style-type
和list-style-image
属性content
::marker
伪元素上的属性
属性的功能content
更强大,比如,它允许我们使用函数counter()
访问列表项的序数(隐式list-item
计数器),并用自定义字符串修饰它。
不幸的是,Safari 尚不支持content
on 属性::marker
(WebKit 错误)。因此,我将使用 属性list-style-type
来定义自定义标记。您仍然可以使用::marker
选择器来设置通过 声明的自定义标记的样式。Safari支持 的list-style-type
这一方面。::marker
任何 Unicode 字符都可以作为自定义列表标记,但只有一小部分字符实际上在其官方名称中包含“项目符号”,因此我想在这里编译它们以供参考。
特点 | 姓名 | 代码点 | CSS 关键字 |
---|---|---|---|
• | 子弹 | U+2022 | disc |
‣ | 三角子弹 | U+2023 | |
̶ | 连字符项目符号 | U+2043 | |
⁌ | 黑色向左子弹 | U+204C | |
⁍ | 黑色向右子弹 | U+204D | |
◘ | 逆子弹 | U+25D8 | |
◦ | 白色子弹 | U+25E6 | circle |
☙ | 反转花心子弹 | U+2619 | |
❥ | 旋转重黑心子弹 | U+2765 | |
❧ | 旋转花心子弹 | U+2767 | |
⦾ | 带圆圈的白色项目符号 | U+29BE | |
⦿ | 带圆圈的子弹 | U+29BF |
注意: CSSsquare
关键字在 Unicode 中没有对应的“项目符号”字符。最接近的字符是黑色小方块 (▪️) 表情符号 ( U+25AA
)。
现在让我们看看当我们用list-style-type: "•"
(U+2022
项目符号)替换默认列表标记时会发生什么。这与默认项目符号相同,因此不应该有任何重大的渲染差异。在我的测试页面上,打开该list-style-type
选项并观察标记的任何变化。
如您所见,有两个重大变化:
- 标记后不再存在最小间隙。
- 子弹变小了,就像是在较小的 下渲染的一样
font-size
。
根据CSS 计数器样式 3 级,默认列表标记 ( disc
) 应“类似于 • U+2022
BULLET”。浏览器似乎会增大默认项目符号的大小,以使其更易读。Firefox 甚至-moz-bullet-font
为标记使用了一种特殊字体 。
尺寸小的问题可以用 CSS 修复吗?在我的测试页面上,打开标记样式,并观察更改标记的font-size
、line-height
和时会发生什么情况。font-family
如您所见,增加font-size
会导致自定义标记垂直错位,而这无法通过减少来纠正line-height
。vertical-align
可以轻松修复此问题的属性不受支持::marker
。
但是你有没有注意到,改变font-family
会导致标记变大?尝试将其设置为Tahoma
。这可能是解决小尺寸问题的一个足够好的方法,尽管我还没有测试哪种字体在主流浏览器和操作系统上运行效果最好。
您可能还注意到,当您将标记放置在列表项内时,Chromium 错误不再发生。这意味着自定义标记可以作为此错误的解决方法。这让我想到了主要问题,也是我开始研究这个主题的原因。如果您定义自定义标记并将其放置在列表项内,则标记后没有间隙,也无法通过标准方式插入间隙。
- 自定义标记后没有最小间隙。
::marker
不支持padding
或margin
。padding-left
由于标记的位置为 ,因此<li>
不会增加间隙inside
。
概括
以下是我在文章中提到的所有关键事实的摘要:
padding-inline-start
浏览器对和元素应用默认的40px
。<ul>
<ol>
- 内置列表标记 (
disc
、decimal
等) 后有最小间隙。自定义标记 (字符串或 URL) 后无最小间隙。 padding-left
可以通过在中添加 来增加间隙的长度<ul>
,但前提是标记位于列表项之外(默认模式)。- 自定义字符串标记的默认大小比内置标记小。更改
font-family
可以::marker
增加其大小。
结论
回顾文章开头的代码示例,我想我现在明白了为什么值中有一个空格字符content
。没有更好的方法可以在 SVG 标记后插入间隙。这是一种必要的解决方法,因为无论多少个margin
和padding
都无法在位于列表项内的自定义标记后创建间隙。margin-right
on::marker
可以轻松做到这一点,但不支持这样做。
在::marker
添加对更多属性的支持之前,Web 开发人员通常别无选择,只能隐藏标记并使用::before
伪元素模拟它。我最近不得不自己这样做,因为我无法更改标记的background-color
。希望我们不必等待太久才能看到更强大的::marker
伪元素。