使用CSS设置编号列表的样式

时间:2014-11-18 15:09:17

标签: css css3 css-counter

我需要HTML来生成类似于:

的输出
1.     Some title

1.1    blah blah

       (a)    blah blah blah

       (b)    blah blah

1.2    blah blah

我相信因为需要在括号内使用括号,所以我不能使用有序列表标签。显然它可以用表格完成,但我更喜欢使用CSS。但是,我不知道如何做到这一点。

如果换行换行到下一行,它们应该在文本下继续,就像有序列表那样。

UPDATE 我试过了

OL {
    counter-reset: numeric
}
OL LI OL LI OL {
    counter-reset: latin
}
LI {
    display: block
}
LI:before {
    content: counters(numeric, ".") " "; 
    counter-increment: numeric
}
OL LI OL LI OL LI:before {
    content: "(" counter(latin, lower-latin) ") "; 
    counter-increment: latin
}

和HTML如:

xxx
<ol>
    <li>one
        <ol>
            <li>onedotone</li>
            <li>onedottwo
                <ol>
                    <li>A</li>
                </ol>
            </li>
        </ol>
    <li>two</li>
</ol>

产生这个

xxx
    1 one
           1.1 onedotone
           1.2 onedottwo
                  (a) A
    2 two

不幸的是,我的要求与原始问题完全一致。所以我的CSS在这些方面失败了。

  1. 需要在1之后和2之后完全停止,而不是在1.1和1.2
  2. 之后
  3. 1和1.1不应缩进,并且两者的文本需要对齐到同一个地方。所以单词onedotone需要正好在单词之下。此外,还需要比数字和文本之间的空格更大的间隙。
  4. (a)需要与onedottwo上的单词对齐,并且需要比(a)和A之间的一个空格更大的间隙。
  5. padding-left不是答案,因为它没有帮助排列数字之后的文字,你得到了

    1 one
    1.1 onedotone
    

    而不是

    1.     one
    1.1    onedotone
    

    这超出了我的CSS功能。除非有人有专业知识指出我正确的方向,否则我担心我将不得不重新使用桌子。

1 个答案:

答案 0 :(得分:2)

以下是使用<ol>(有序列表)和CSS counters如何实现所需结果的示例。它有一点hack-ish感觉因为期望当一条线缠绕时,它不应该从编号下面开始。否则,我觉得这种方法比使用表格手动键入数字(或)要好得多。

通过将width设置为li:before伪元素并将其显示为display: inline-block,可以获得编号与文本之间的一致间距。根据所需的间距修改width。请注意,修改width时,还必须相应地修改margin-leftpadding-left以保持样式。

CSS计数器也合理地good browser support

&#13;
&#13;
.level1, .level2, .level3 {
    list-style-type: none;
}
.level1 {
    counter-reset: level1; /* first level counter - for 1, 2, 3 */
}
.level2 {
    counter-reset: level2; /* second level counter - for 1.1, 1.2 */
}
.level3 {
    counter-reset: level3; /* third level counter - for (a), (b) */
}
li {
    display: block;
}
li:not(:last-child):after, li > ol:before{
    content: " ";
    display: block;
    position: relative;
    height: 20px; /* this is filler where height should be equal to required line height */
    left: 0px; top: 100%;
}
.level1, .level2, .level3 {
    margin: 0;
    padding: 0;
}
.level1 > li, .level3 > li {
    padding-left: 40px;
}
li:before {
    margin-left: -40px;
    /* following 2 props are for consistent spacing between numbering and text */
    width: 40px;
    display: inline-block;
}
.level1 > li{
    font-weight: bold;
}
.level1 > li:before, .level1 > li * {
    font-weight: normal;
}
.level1 > li:before {
    content: counter(level1)"."; /* display current item number + dot */
    counter-increment: level1; /* increment counter everytime a new element of that level is encountered */
}
.level2 > li:before {
    content: counter(level1)"." counter(level2); /* format level 1 counter + dot + level 2 counter */
    counter-increment: level2;
}
.level3 > li:before {
    content: "(" counter(level3, lower-latin)") "; /* format ( + level3 counter + ) */
    counter-increment: level3;
}
&#13;
<ol class='level1'>
    <li>one
        <ol class='level2'>
            <li>one dot one - has some really really lengthy text which wraps around to the next line when it overflows the width.</li>
            <li>one dot two
                <ol class='level3'>
                    <li>A</li>
                    <li>B - has some really really lengthy text which wraps around to the next line when it overflows the width.</li>
                </ol>
            </li>
        </ol>
    </li>
    <li>two - has some really really lengthy text which wraps around to the next line when it overflows the width.</li>
</ol>
&#13;
&#13;
&#13;


对评论的反馈:

  1. {content: "\a"; white-space: pre;}技巧与inline-block元素不太相配。在我们的案例中,内层li标签是inline-block(由于上面第2段中解释的原因),因此该特定技巧不起作用。替代方法是插入空白填充线,其中height行等于所需的line-height,并将其放在li标记下方。 注意所使用的选择器为li:not(:last-child):after,因为我们在最后li之后不需要额外的换行符(如果我们不这样做,我们将会加倍内部li结束后的行间距)。这是一个CSS3选择器,因此可能不适用于较低版本的IE。如果您还需要支持这些版本,那么我们需要进一步调整它(或者更简单的是使用br)。

  2. 您在此处的路径正确,但:before伪元素(具有编号)不在class='level1'的元素上。它位于.level1 > li上,因此重置font-weight选择器.level1 > li:before, .level1 > li *会修复它。正如您已经知道/猜到的那样,.level1 > li *表示第一级li下的每个元素。