CSS中使用Unicode字符作为列表项目的符号

129

我需要使用星号符号(★)作为列表项的项目符号。

我已经阅读了CSS3模块:列表,其中描述了如何使用自定义文本作为项目符号,但这对我不起作用。我认为浏览器根本不支持::marker伪元素。

如何在不使用图像的情况下实现它?


你能贴出你正在使用的代码吗?你在测试这个代码时使用的是哪个浏览器? - Jonny Haynes
1
http://stackoverflow.com/questions/3068199/which-character-is-used-to-fill-contents-of-password-text-input/3068265#3068265 有一些 Unicode 子弹符号。虽然它们在 Ubuntu 上没问题,但我在 Windows 机器上无法显示出你所拥有的星形符号或 26AB(中等黑色圆圈)。 - Pete Kirkham
这个答案(针对类似问题)对我有帮助:https://dev59.com/J2sz5IYBdhLWcg3wuKa6#12216973 - Piotr Migdal
14个回答

119

使用文本作为项目符号

使用li:before和转义的十六进制HTML实体(或任何纯文本)。


例子

我的例子将生成带有勾选标志的列表作为项目符号。

ul {
    list-style: none;
    padding: 0px;
}

ul li:before
{
    content: '\2713';
    margin: 0 1em;    /* any design */
}
<ul>
  <li>First item</li>
  <li>Second item</li>
</ul>


浏览器兼容性

虽然本人未进行测试,但自IE8以来应该已得到支持。 至少quirksmodecss-tricks如此表示。

您可以使用条件注释来应用旧的/较慢的解决方案,例如图像或脚本。更好的方法是使用<noscript>与图片一起使用。

HTML

<!--[if lt IE 8]>
    *SCRIPT SOLUTION*
    <noscript>
        *IMAGE SOLUTION*
    </noscript>
<![endif]-->

关于背景图像

虽然背景图像确实容易处理,但是...

  1. background-size 的浏览器支持只从IE9开始。
  2. HTML文本颜色和特殊(疯狂)字体可以减少HTTP请求并完成同样的效果。
  3. 脚本方案可以注入HTML实体,让相同的CSS完成工作。
  4. 一份好的重设CSS代码可能会使 list-style(更合理的选择)更容易。

享受吧。


1
有用的转换工具,用于转义特殊字符 http://rishida.net/tools/conversion/ - iiz
27
如果li元素中的内容换行成多行,那么这种方法将无法正常工作;换行的行将无法正确缩进。 - Richard Ev
5
在:before上加上float: left; margin-left: -12px;来处理这个问题,@RichardEverett - Dudo
1
如果只有一行,它可以工作,但是如果有多行换行,则无法工作。 - VDarricau
我不确定这个方法是否适用于所有情况,但是我使用margin-right: 0.5em; margin-left:-1.5em;获得了最佳效果。看起来星号的宽度恰好为1em,因为现在多行文本完美地对齐了。所以我猜想一般规则应该是:margin-left = - (margin-right + 字符宽度) - eMBee
1
仅适用于单行列表项。多行将会在符号下方而非缩进。 - Clarus Dignus

84

编辑

我不太建议再使用图片了。我会建议采用使用Unicode字符的方式,就像这样:

li:before {
  content: "\2605";
}

旧回答

我会选择使用图像背景,因为它们更加多功能且跨浏览器友好。

这里有一个例子:

<style type="text/css">
  ul {list-style:none;} /* you should use a css reset too... ;) */
  ul li {background:url(images/icon_star.gif) no-repeat 0 5px;}
</style>

<ul>
  <li>List Item 1</li>
  <li>List Item 2</li>
  <li>List Item 3</li>
</ul>

49
“更加高效”是怎么实现的呢?你需要发送额外的HTTP请求来获取图片,而且文件总大小会随着加载图片而增加,而这一切本来都可以通过使用单个Unicode字符来完成。 - Mathias Bynens
2
你说得对,如果你想要的是性能,也许“高效”不是我应该使用的词语,但是使用图像背景比使用文本要灵活得多。 - agbb
3
调整图片大小并不是很好,但角色图像在任何尺寸下都完美,所以我认为角色更具多功能性 :P我认为“向后兼容”或“具有最广泛的浏览器支持”可能是合适的词语。 - JustGoscha
1
<li>文本换行时,这种方法效果不佳:项目符号不会保持不缩进,最终看起来像是一个段落的开头。这个答案解决了这个问题:https://dev59.com/L3A75IYBdhLWcg3wm6Yj#14301918 - Michael Scheper

41

这是 W3C 的解决方案。你可以在 3012 年使用它!

ul { list-style-type: "*"; }
/* Sets the marker to a "star" character */

https://drafts.csswg.org/css-lists/#text-markers

更新:根据评论,这在2021年的所有现代浏览器中都有效。


19
我听说在3012年,Internet Explorer终于能正常工作了! - Mark K Cowan
2
这在Firefox 48中有效,但在Chromium 51或我的手机/平板电脑上无效。我们将不得不使用li:before的解决方案。 - CoderGuy123
2
工作正常。女士们,先生们,欢迎来到未来。 - Mikko Ohtamaa
2
感谢来自未来的答案,但在2020年,这适用于Chrome、Firefox和Edge,但不适用于Safari。 - George
来自2021年的问候。顺便提一下,这在Safari 14.1中是可行的。 - 0Seven
人们应该将这个作为主要答案,然后使用CSS处理器来提高兼容性。 - ADJenks

35

你可以构建它:

#modal-select-your-position li {
/* handle multiline */
    overflow: visible;
    padding-left: 17px;
    position: relative;
}

#modal-select-your-position li:before {
/* your own marker in content */
   content: "—";
   left: 0;
   position: absolute;
}
<ul id="modal-select-your-position">
  <li>First item</li>
  <li>Second item</li>
</ul>


4
这是一个很好的技巧,因为如果不对字符进行绝对定位,那么您最终会发现"Bullet"与其他列表项一起排列。这是非常不像弹出符号的行为。通过这个修复,您可以将"bullet"移到列表项的左侧,就像使用普通弹出符号一样。 - General Redneck
谢谢您!这正是我需要的,让我的子弹再次表现出色。 - nwalke
1
这个使用 '\21B3' 制作的导航树非常棒!谢谢!它比其他答案都要好。我还将我的设计中的 padding-left 改为 1em,这样当你的树级别大小改变时,它会很好地适应。 - ndm13

15

由于在某些设备上(具有Retina显示屏的苹果设备)或放大时可能出现像素化的情况,因此不建议使用图像。通过使用字符,您的列表每次都会看起来很棒。

这是我目前找到的最佳解决方案。它功能强大且跨浏览器(IE 8+)。

ul {
  list-style: none;
  padding-left: 1.2em;
  text-indent: -1.2em;
}

li:before {
  content: "►";
  display: block;
  float: left;
  width: 1.2em;
  color: #ff0000;
}
<ul>
  <li>First item</li>
  <li>Second item</li>
</ul>

重要的是将这个字符放在一个浮动块中,并固定其宽度,以便文本如果太长无法放入单行时仍然保持对齐。 1.2em 是您希望为字符设置的宽度,请根据您的需求进行更改。 不要忘记重置 ul 和 li 元素的填充和边距。
编辑:请注意,在 ul 和 li:before 中使用不同字体时,“1.2em”大小可能会有所不同。最安全的做法是使用像素。

也许可以在li:before中添加“height:1px”或类似的内容?这可以确保浮动不会延伸到下一个<li>,从而导致不良嵌套。 - Alan De Smet
为什么在li:before上使用display:block;?是因为默认情况下它是内联的,无法指定宽度吗? - Alexander Solonik

8

要添加一个星号,请使用Unicode字符22C6

我添加了一个空格,以在li和星号之间留出一点间隔。 空格的代码是A0

li:before {
    content: '\22C6\A0';
}

8
今天,有一个::marker选项。所以,
li::marker {
  content: "\2605";
}

2
这个答案值得点赞,同时将其他所有答案都踩下去 ;) 截至2021年2月,伪元素::marker在浏览器中的覆盖率为86.58% https://caniuse.com/?search=li%3A%3Amarker - munomono

4

以下是222的回答的更完整示例:

ul {
    list-style:none;
    padding: 0 0 0 2em;     /* padding includes space for character and its margin */

    /* IE7 and lower use default */
    *list-style: disc;
    *padding: 0 0 0 1em;
}
ul li:before {
    content: '\25BA';
    font-family: "Courier New", courier, "Lucida Sans Typewriter", "Lucida Typewriter", monospace;
    margin: 0 1em 0 -1em;   /* right margin defines spacing between bullet and text. negative left margin pushes back to the edge of the parent <ul> */

    /* IE7 and lower use default */
    *content: none;
    *margin: 0;
}
ul li {
    text-indent: -1em;      /* negative text indent brings first line back inline with the others */

    /* IE7 and lower use default */
    *text-indent: 0;
}

我已经包含 star-hack 属性来恢复在旧版 IE 中的默认列表样式。如果需要,您可以将其分离并在条件包含中引用,或者使用基于 background-image 的解决方案进行替换。我个人认为,以这种方式实现的特殊符号样式应该能够优雅地降级,以适应那些不支持伪元素选择器的浏览器。
在Firefox、Chrome、Safari和IE8-10中测试,所有浏览器均能正确呈现。

如果您有多行列表项,那么text-indent: -1em;是一个非常重要的属性。如果没有它,第二行及其后续行将与项目符号对齐,而不是与前一行对齐。 - Andris

3
ul {
    list-style-type: none;    
}

ul li:before {
    content:'*'; /* Change this to unicode as needed*/
    width: 1em !important;
    margin-left: -1em;
    display: inline-block;
}

3
如上述这些 两个评论中提到的,现代方法是使用list-style-type::marker。根据您的用例,您还可以将它们组合使用。
其中这些方法比较明显的缺点之一是,您尚不能::marker应用marginpadding,而必须依赖于空格(如本文中所示的示例)或使用下面2.1中提供的演示中概述的偏移方法。

1.使用list-style-type设置自定义标记

li { list-style-type: " "; }
<ul>
  <li>1</li>
  <li>2</li>
  <li>3</li>
</ul>


2. 使用::marker来样式化list-style-type

/* intentional whitespace, may vary cross-browser */
li { list-style-type: "★      "; } 
li::marker { color: red; }
<ul>
  <li>1</li>
  <li>2</li>
  <li>3</li>
</ul>

2.1 间距

尽管在上面的演示中不是立即显而易见的,但标记符号是向列表外移动而不是向内推进。这意味着它可能会超出您的网格范围和/或被另一个元素遮挡。

我创建了一个演示,展示了空白间距问题以及两种潜在的解决方案,具体取决于您需要匹配默认的ul样式还是创建一个位于父容器内部的东西。


3. 仅使用::marker来表示变体:

li.one::marker { content: " "; }
li.two::marker { content: " "; }
li.three::marker { content: " "; }
<ul>
  <li class="one">1</li>
  <li class="two">2</li>
  <li class="three">3</li>
</ul>


其他资源:


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接