-3

我需要 HTML 来生成类似于以下内容的输出:

1.一些标题

1.1 胡说八道

       (a) 呜呜呜

       (b) 胡说八道

1.2 胡说八道

我相信由于需要在字母周围加上括号,我不能为此使用有序列表标签。显然它可以用表格来完成,但我更愿意使用 CSS。但是,我不知道如何做到这一点。

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

更新我试过

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 个
           1.1 单调
           1.2 onedottwo
                  (一)一个
    2 二

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

  1. 在 1 和 2 之后需要有句号,但在 1.1 和 1.2 之后不需要
  2. 1 和 1.1 不应该缩进,它们的文本需要对齐到同一个地方。所以 onedotone 这个词需要正好在 one 这个词的下方。此外,数字和文本之间的间距必须大于一个空格。
  3. (a) 需要与单词 onedottwo 对齐,并且在 (a) 和 A 之间需要有比一个空格更大的间隙。

padding-left不是答案,因为它无助于排列数字后的文字,你得到

1 个
1.1 单调

代替

1. 一
1.1 单调

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

4

1 回答 1

2

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

width通过将 a 设置为li:before伪元素并使其显示为来获得编号和文本之间一致的间距display: inline-blockwidth根据需要多少间距修改。请注意,在修改 时widthmargin-leftpadding-left也必须进行相应修改以保持样式。

CSS Counters 也有相当好的浏览器支持

.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;
}
<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>


对评论的反馈:

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

  2. 您在这里的路径正确,但:before伪元素(具有编号)不在带有class='level1'. 它在.level1 > li,因此重置font-weightfor 选择器.level1 > li:before, .level1 > li *将修复它。正如您已经知道/猜测的那样,.level1 > li *表示 level one 下的每个元素li

于 2014-11-19T04:52:58.197 回答