ol的自定义计数器



在ol/li中更改计数器是众所周知的CSS技巧,有很多类似这样的引用。

我使用这个技巧使多个<ol>元素具有相同的计数器。我还希望多行文字有正确的边距。为此,建议像下面的例子一样使用::marker(使用::before使数字成为段落的一部分,而不是在页边空白中(。这在Firefox中运行良好,但仅限于Firefox。不在我的iPhone上,也不在Chrome中(如这里所解释的(。

有没有更好的解决方案适用于所有浏览器?

<!DOCTYPE html>
<html>
<head>
<style>
div.one-counter {
counter-reset: bibitem;
}
div.one-counter ol{
max-width: 200px;
}
div.one-counter ol li {
counter-increment: bibitem;
padding: 0 0 0 .3em;   
}
div.one-counter ol li::marker {
content: counter(bibitem) ".";
font-weight: bold;
}
</style>
</head>
<body>
<div class="one-counter">
<h3>First</h3>
<ol>
<li>  Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse nec augue
vitae tortor dignissim aliquam.</li>
<li>Nulla facilisi. Duis venenatis ipsum at mauris elementum, ac commodo quam tempus. </li>
</ol>
<h3>Second</h3>
<ol>
<li>  Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse nec augue
vitae tortor dignissim aliquam.</li>
<li>Nulla facilisi. Duis venenatis ipsum at mauris elementum, ac commodo quam tempus.</li>
</ol>
</div>
</body>
</html>

MDN web文档中引用的::marker伪元素并非在所有浏览器中都受支持。它目前只是一个工作草案。我建议使用::before元素并调整边距或填充以实现所需的定位。

使用一个列表

  1. 将每个<h3>包裹在<li>中,并将它们放置在<ol>中所需的位置。

  2. 删除所有与<ol><li>相关的CSS

  3. 添加此规则集:.hdr { list-style: none; margin-left: -40px; }

  4. .hdr分配给每个<h3>:<h3 class='hdr'>...

  5. 为其余的<li>分配一个[value=N]N作为编号位置:

    <li value='1'>First Item</li>
    

很少使用[value]<li>属性,因为在动态生成大量<li>和/或<li>的情况下,这将是有问题的。请参阅演示的示例2来解决该问题。

下面的演示有两个例子:

  1. 示例1 是手动分配[value]

  2. 示例2 [value](两行JavaScript(的程序分配


演示

<!DOCTYPE html>
<html>
<head>
<meta charset='utf-8'>
<style>
.hdr {
list-style: none;
margin-left: -40px;
}

/* For demo purposes */ 
code {
font-family: Consolas;
color: green;
background: rgba(0, 0, 0, 0.2);
}
</style>
</head>
<body>
<h1><code>[value]</code> Attribute</h1>
<h2>Example 1</h2>
<p>List A -- <code>ol#A</code> -- <code>[value]</code> assigned manually</p>
<ol id='A'>
<li class='hdr'>
<h3>First</h3>
</li>
<li value='1'> Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse nec augue vitae tortor dignissim aliquam.</li>
<li value='2'>Nulla facilisi. Duis venenatis ipsum at mauris elementum, ac commodo quam tempus. </li>
<li class='hdr'>
<h3>Second</h3>
</li>
<li value='3'> Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse nec augue vitae tortor dignissim aliquam.</li>
<li value='4'>Nulla facilisi. Duis venenatis ipsum at mauris elementum, ac commodo quam tempus.</li>
</ol>

<h2>Example 2</h2>
<p>List B -- <code>ol#B</code> -- <code>[value]</code> assigned programmatically. See <code>&lt;script&gt;</code> block at end of source.</p>
<ol id='B'>
<li class='hdr'>
<h3>First</h3>
</li>
<li> Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse nec augue vitae tortor dignissim aliquam.</li>
<li>Nulla facilisi. Duis venenatis ipsum at mauris elementum, ac commodo quam tempus. </li>
<li class='hdr'>
<h3>Second</h3>
</li>
<li> Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse nec augue vitae tortor dignissim aliquam.</li>
<li>Nulla facilisi. Duis venenatis ipsum at mauris elementum, ac commodo quam tempus.</li>
</ol>
<script>
/*
- Collect all <li> in <ol id='B'> that is 
NOT <li class='hdr'> into a NodeList
- Your selector can be more generic if using only
one list: li:not(.hdr)
*/
const items = document.querySelectorAll('#B li:not(.hdr)');
/*
- Iterate through NodeList and assign [value=index+1]
to each <li>
*/
items.forEach((li, idx) => li.setAttribute('value', idx + 1));
</script>
</body>
</html>

最新更新