内部元素如何为“first-line”设置样式

7

我试图对列表的第一行项目应用CSS样式,但是Chrome、Firefox和Safari似乎都不接受这种样式。

ul:first-line > li {
    display: inline;
    /* my styles here */
}

我是否忽略了指定样式的方法?这是CSS实现上的疏忽还是有意的CSS规范?如果是后者,那么这背后是否有充分的理由呢?

JSFiddle: http://jsfiddle.net/e3zzg/

编辑:
请注意,目前看来无法仅使用CSS实现此目标,但从研究的角度和为后人着想,我很想知道这是为什么。如果您阅读了W3C关于“firstline”伪元素的CSS规范,似乎没有提及内部元素。感谢各位试图提供替代方案的人,但除非确实有CSS解决方案,否则这里的问题是“为什么”,而不是“如何”或“是否可能”。


你可以在页面上使用Javascript吗? - Edorka
是的,我可以使用JS解决这个问题,但那不是我在这里问的。如果不能用CSS解决,我很好奇为什么。 - Godwin
因为CSS不会受到元素当前位置的影响,只是对它们进行设置。希望我的回答能够帮助到您。 - Edorka
4个回答

9

为什么你想要做的事情不能完成

选择器3规范更新一些。以下内容摘自该规范。

"为什么"是因为:first-letter是伪元素,也就是一个“虚假”或“假的”元素。它产生了一个“虚构的标记序列”,这与其他真实元素没有关系。所以您的...

ul:first-line > li 

...遇到了与此选择器字符串相同的问题...

ul:before + li

在选择器(无论是>还是+)只查看“元素”而不是“伪元素”进行选择的情况下,第一个字符串仅针对后面跟随一个:before伪元素的ul的“第一个”li。如果它确实起作用,它将针对在html顺序中跟随ulli(当然,在有效的html布局中永远不会有这样的内容)。

然而,类似于上面第二个字符串的选择器字符串也无法工作,因为实际上,上述字符串的形式是无效的,正如规范中所确认的那样:

每个选择器只能出现一个伪元素,如果存在,则必须出现在代表选择器主体的简单选择器序列之后。

换句话说,伪元素只能位于选择器序列中的最后位置,因为它必须是该选择器分配属性的目标。非有效形式显然就像任何无效选择器一样被忽略。


有趣的是,这种方式有点讲得通。当before伪元素像<li><li:before>1.</li:before>First element</li>这样时很容易理解,但当其中有额外的元素时,我很难以同样的方式看待first-line - Godwin
我猜可以将其想象为<ul><li><ul:first-line>LoremIpsum</ul:first-line></li><li><ul:first-line>dolor</ul:first-line> sit amet</li>... - Godwin
请参考以下类似的概念,但是是相反的:我能用兄弟组合器来定位一个 :after 伪元素吗? - BoltClock
是和不是。这更加复杂,因为 background-color 就像 <ul><ul:first-line><li>...</li><li>etc...</li></ul:first-line></ul>,但它并没有将那些真正的 <li> 视为与其相关。它实际上关联的是发生在那些 li 元素中的 "文本" 的开头和结尾。因此,您可以在 ul:first-line 上设置 color 属性,li 中的 文本 将通过正常继承来获取它,但是您无法使 li 本身的 background 继承,因为 ul:first-line 背景影响的是 文本 而不是 li - ScottS

2

我认为你最好选择:

ul > li:first-child

:first-line 仅适用于文本元素。


2
这只会为第一个元素设置样式,而不是第一行上的每个元素! - Godwin
1
在这种情况下,我认为您需要一种JavaScript解决方案,我不认为CSS会对您有所帮助。 - Fiona - myaccessible.website

0
唯一的选项是通过Javascript为第二行添加一个具体的className并设置它们的背景,以使其与其他行区分开来。要获取当前行,您应该迭代元素并将其距离列表顶部和前面的兄弟节点进行比较。我制作了一个jQuery示例,以便您可以理解:http://jsfiddle.net/JmqxM/
$("ul.numerize-lines").each(function () {
    var list = $(this);
    var currentDistance = 0;
    var currentLine = 0;

    list.find("li").each(function () {
        var item = $(this);
        var offset = .offset();
        var topDistance = offset.top;
        if (topDistance > currentDistance) {
            currentDistance = topDistance;
            currentLine += 1;
        }
        item.addClass("line-" + currentLine);
    });
});

还有CSS:

ul li.line-2{
    background-color: #FFF;
}

我没有分叉这个fiddle,现在它正常了。 - Edorka

0
我相信 :first-line 应该应用于包含文本的元素本身(而不是父元素,就像你所写的那样)。
ul > li:first-line { /*style*/ }

Or if your list items contain

tags or something else like that...

ul > li p:first-line { /*style*/ }


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