列表项标记位置不一致,具体取决于子项的显示属性

Inconsistent list item marker positioning depending on child's display property

提问人:Fabrício Matté 提问时间:7/4/2014 更新时间:7/4/2014 访问量:1008

问:

考虑此标记:

<ul>
    <li>
        <div id="container">
            <button>toggle display</button>
            <div>text</div>
            <div>text</div>
        </div>
    </li>
</ul>

假设元素的计算 CSS 值为 ,列表项标记(项目符号)呈现在内容的第一行旁边(在 的左侧)。#containerdisplayblock<button>

现在,如果将 的 CSS 属性更改为 ,则列表项标记将呈现在最后一行文本旁边。请参阅此测试用例。(在 Chrome 35 和 Firefox 30 中测试)。#containerdisplayinline-block

在这两种情况下,是否可以在同一位置呈现项目标记?(最好在与容器一起呈现的地方)display: block

经过一番摆弄后,项目标记位置似乎受到元素的影响。例如,元素中的设置会使标记呈现在元素左上角附近,但由于该属性不适用于元素,因此标记位置仍然存在差异。inline-blockvertical-alignvertical-align: top#containerinline-blockvertical-alignblock

有没有一种解决方案可以使子弹在完全相同的位置呈现,而与 的属性无关?#containerdisplay

我更喜欢仅 CSS 的解决方案,但编辑标记也是可以接受的。

css html 列表

评论

0赞 James Montagne 7/4/2014
您可以考虑使用创建自己的项目符号,以便为您提供更多控制权。:before
0赞 Fabrício Matté 7/4/2014
@JamesMontagne好主意,谢谢。我想我甚至可以用于数字/字母。但是,似乎我正在找到一个更简单的解决方案,将块元素包装在内联块中似乎可以解决问题(小提琴)。子弹现在与外部对齐,但至少它与我最初要求的一致。@counter<ol>display:inline-block
1赞 Kabie 7/4/2014
display:inline-table看起来还不错?
0赞 Fabrício Matté 7/4/2014
@Kabie哦,我正在试验,但后来注意到它具有与(看起来不那么黑客)相同的效果——很抱歉在之前的评论中发布了过时的小提琴修订版。是的,我想这很好。在将其作为答案发布之前,我会做一些更详细的测试。inline-tableinline-blockinline-table
0赞 Fabrício Matté 7/4/2014
@Kabie现在我发现我完全误解了你的评论,呵呵。感谢您将其作为答案发布。;)

答:

0赞 TribalChief 7/4/2014 #1

这是肮脏的方法:

li {
    list-style-type: none;
}
li::before {
    content: "\25CF";
    margin-left: -20px;
    position: absolute; # thanks to DRD
}

评论

0赞 Fabrício Matté 7/4/2014
看起来不错,谢谢。但是,在我的生产环境中,有序列表(带有数字和字母计数器)存在相同的问题,因此此解决方案不太适用。但感谢您的努力,将来可能会对其他人有所帮助。<ol>
0赞 TribalChief 7/4/2014
这才是最重要的!;-D
0赞 DRD 7/4/2014
@Thauwa。添加以下规则集: 并查看项目符号会发生什么情况。对于你的工作方法,应该相对定位,也应该绝对定位。然后,它将按预期工作。body {height: 10000px;}li:before
0赞 TribalChief 7/4/2014
@DRD,定位是否必要?没有它对我来说看起来不错。我错过了什么?li
0赞 DRD 7/4/2014
明白了。既然你正在使用它,它就会工作得很好。如果您要使用坐标(即 ),那么它就会中断,因为 将使用 的坐标系进行定位。事实上,你是对的,它没有 .margin-leftleft: -20px:beforebodyposition: relativeli
0赞 DRD 7/4/2014 #2

首先,我不明白为什么子弹会归零在内联块内的最后一个块上。但是,如果您将内联块中的块更改为 ,那么这似乎可以解决问题:http://jsfiddle.net/3BYKp/1/table

#container > div {
    display: table;
}

评论

0赞 Fabrício Matté 7/4/2014
我相信,它们会因为内联框的基线而改变。无论如何,感谢您的回答,尽管当任意内容跟随按钮(小提琴)时它会中断,尽管可以通过始终将该内容包装在 .唯一的问题是当按钮(小提琴)之前有内容时,但我没有在问题中提到这一点,我已经有了一个替代解决方案,所以感谢您的努力。div=]
1赞 Fabrício Matté 7/4/2014 #3

一个可能的解决方案是用一个元素包装:#containerinline-block

.container-outer {
    display: inline-block;
    width: 100%;
    vertical-align: top;
}

小提琴

这样,子弹相对于这个新的外部元件定位,其显示不会改变,从而达到所需的一致性。inline-block

唯一的缺点是项目符号与元素的顶部对齐(由于显示和 ),而不是与元素一样的第一行内容,但这几乎不明显。inline-blockvertical-align: topblock

1赞 Kabie 7/4/2014 #4

根据 http://www.w3.org/TR/CSS21/visudet.html

“内联表”的基线是表第一行的基线。

“内联块”的基线是其在正常流中最后一个行框的基线,除非它没有流入线框,或者其“溢出”属性具有“可见”以外的计算值,在这种情况下,基线是下边距边。

另请参阅以下两个演示:

http://www.brunildo.org/test/inline-block.html

http://www.brunildo.org/test/inline-block2.html

它似乎具有相同的基线。所以使用而不是可以解决这个问题。blockinline-tableinline-tableinline-block

评论

0赞 Fabrício Matté 7/4/2014
你救了我的命!谢谢,这是最终的解决方案。