在HTML中嵌套编号的有序列表

39

我有一个嵌套的有序列表。

<ol>
  <li>first</li>
  <li>second
  <ol>
    <li>second nested first element</li>
    <li>second nested secondelement</li>
    <li>second nested thirdelement</li>
  </ol>
  </li>
  <li>third</li>
  <li>fourth</li>
</ol>

目前嵌套元素再次从1开始编号,例如:

  1. first
  2. second
    1. second nested first element
    2. second nested second element
    3. second nested third element
  3. third
  4. fourth

我希望第二个元素的编号如下所示:

  1. first
  2. second

    2.1. second nested first element

    2.2. second nested second element

    2.3. second nested third element

  3. third
  4. fourth

有没有办法实现这个效果?


你需要支持哪些浏览器? - SLaks
需要额外的代码来完成吗,例如JavaScript或Ajax?我希望有一个参数或CSS元素可以直接传递到列表中。我看到您可以使用参数类型,但就我所知,这只会更改数字类型。 - John
6个回答

37
这是一个在所有浏览器中都有效的示例。纯CSS方法适用于真实的浏览器(即除了IE6/7之外的所有浏览器),而jQuery代码则是为了覆盖不支持的部分。它类似于SSCCE,您可以直接复制粘贴并运行它,无需更改。
<!doctype html>
<html lang="en">
    <head>
        <title>SO question 2729927</title>
        <script src="http://code.jquery.com/jquery-latest.min.js"></script>
        <script>
            $(document).ready(function() {
                if ($('ol:first').css('list-style-type') != 'none') { /* For IE6/7 only. */
                    $('ol ol').each(function(i, ol) {
                        ol = $(ol);
                        var level1 = ol.closest('li').index() + 1;
                        ol.children('li').each(function(i, li) {
                            li = $(li);
                            var level2 = level1 + '.' + (li.index() + 1);
                            li.prepend('<span>' + level2 + '</span>');
                        });
                    });
                }
            });
        </script>
        <style>
            html>/**/body ol { /* Won't be interpreted by IE6/7. */
                list-style-type: none;
                counter-reset: level1;
            }
            ol li:before {
                content: counter(level1) ". ";
                counter-increment: level1;
            }
            ol li ol {
                list-style-type: none;
                counter-reset: level2;
            }
            ol li ol li:before {
                content: counter(level1) "." counter(level2) " ";
                counter-increment: level2;
            }
            ol li span { /* For IE6/7. */
                margin: 0 5px 0 -25px;
            }
        </style>
    </head>
    <body>
        <ol>
            <li>first</li>
            <li>second
                <ol>
                    <li>second nested first element</li>
                    <li>second nested second element</li>
                    <li>second nested third element</li>
                </ol>
            </li>
            <li>third</li>
            <li>fourth</li>
        </ol>
    </body>
</html>

这个解决方案能否改为使用JQuery应用样式?如果可以,那么它是否能在所有浏览器中正常工作? - John
@John:好的,我加上了。但是如果禁用JS,它在IE6/7上无法工作 :) - BalusC
2
如果我有超过2个级别,比如5个级别,该怎么让它工作? - Ragnar
啊,而且它也不能很好地处理段落。比如说,如果你在一个列表元素中有多个段落。没有<p>标签的好处,只有<br />标签可以使用。 - Ragnar
为了避免潜在的冲突,添加一个类来标识需要这种特殊编号的列表会很有帮助。可以使用不同的样式方法来容纳更多级别,如下所示 - 我想像jQuery代码可以重新设计为使用递归,以便它可以处理任意数量的级别,尽管最好还是加入某种形式的截止以防万一。 - Crazy Joe Malloy

35

我知道回答已经晚了,但是我刚刚在这个例子中发现可以使用CSS实现。将以下内容添加到你的CSS部分(或文件):

ol.nested
{
    counter-reset: item
}
li.nested
{
    display: block
}
li.nested:before
{
    content: counters(item, ".") ". ";
    counter-increment: item
}

以下是一个展示列表代码的示例:

<ol class="nested">
<li class="nested">item 1</li>
<li class="nested">item 2
    <ol class="nested">
        <li class="nested">subitem 1</li>
        <li class="nested">subitem 2</li>
    </ol></li>
<li class="nested">item 3</li>
</ol>

希望对你有所帮助


1
看起来链接已经失效了,但是这个例子也可以在Opera上找到:http://dev.opera.com/articles/view/automatic-numbering-with-css-counters/。 - Crazy Joe Malloy
谢谢,这真的很棒!比使用jQuery简单多了!这个解决方案的优点是可以解析多层嵌套!1->1.1->1.1.1->1.1.1.1,而使用jQuery的解决方案则只能到达1.1。 - Nikita Silverstruk

9

这个页面上的所有解决方案都不能正确且普遍地适用于所有级别和长(折行)段落。由于标记的大小不同(1.,1.2,1.10,1.10.5等),实现一致的缩进真的很棘手。它不能仅仅通过为每个可能的缩进级别预先计算边距/填充来“伪造”。

我最终找到了一个真正有效且不需要任何JavaScript的解决方案。

已在Firefox 32、Chromium 37、IE 9和Android Browser上进行了测试。但无法在IE 7及以下版本上使用。

CSS:

ol {
  list-style-type: none;
  counter-reset: item;
  margin: 0;
  padding: 0;
}

ol > li {
  display: table;
  counter-increment: item;
  margin-bottom: 0.6em;
}

ol > li:before {
  content: counters(item, ".") ". ";
  display: table-cell;
  padding-right: 0.6em;    
}

li ol > li {
  margin: 0;
}

li ol > li:before {
  content: counters(item, ".") " ";
}

例子: 例子

jsFiddle上试一试,在Gist上分叉。


0

这在纯HTML/CSS中是不可能的。请参考BalusC的答案,他提供了一个很好的超越常规的解决方案。可以在w3schools, 这里找到编号类型列表。

我能找到的最接近的选项是w3c的value属性的使用, 但以下标记:

<ol>
    <li value="30">
        makes this list item number 30.
    </li>
    <li value="40">
        makes this list item number 40.
    </li>
    <li>
        makes this list item number 41.
    </li>
    <li value="2.1">
        makes this list item number ...
    </li>
    <li value="2-1">
        makes this list item number ...
    </li>
</ol>

生成一个编号为30、40、41、2和2的列表。

正如John已经指出的那样,在这种情况下,你最好使用脚本编写。


0

实际上,如果您在项目中使用sass/scss进行样式设计,您可以使用mixin来完成此操作。要为此嵌套列表设置样式,您只需要两行sass代码。

@import 'nested_list'
+nested_list('nested', 2)

<ol>
  <li>first</li>
  <li>second
      <ol class="nested-2">
          <li>second nested first element</li>
          <li>second nested secondelement</li>
          <li>second nested thirdelement</li>
      </ol>
  </li>
  <li>third</li>
  <li>fourth</li>
</ol>

你可以从git repo克隆/观看完整的示例,或在fidle上生成CSS。


0

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