我可能是在回答我自己的问题,但我非常好奇。
我知道CSS可以选择父容器的各个子容器,但是如果父容器有一定数量的子容器,是否支持对子容器进行样式化。
例如
container:children(8) { // style the parent this way if there are 8 children }
我知道这听起来很奇怪,但我的经理让我去看看,我自己什么都没有发现,所以我决定在结束搜索之前转向so。
不,在CSS中没有这样的东西。但是,您可以使用JavaScript来计算子元素的数量并应用样式。
是的,我们可以使用nth-child这样做:
nth-child
div:nth-child(n + 8) { background: red; }
这将使第8个div子元素变成red。希望这对你有所帮助……
div
red
另外,如果有人说“嘿,他们不能用css做样式,用JS吧!”马上怀疑他们。CSS现在非常灵活
.container div { background: blue; } .container div:nth-child(n + 8) { background: red; }
<div class="container"> <div>div 1</div> <div>div 2</div> <div>div 3</div> <div>div 4</div> <div>div 5</div> <div>div 6</div> <div>div 7</div> <div>div 8</div> <div>div 9</div> <div>div 10</div> <div>div 11</div> <div>div 12</div> </div>
在这个例子中,前7个孩子是蓝色的,之后的8个孩子是红色的……
(外部的例子)
不。其实不是。有几个选择器可以使您接近,但可能在您的示例中不起作用,并且没有最好的浏览器兼容性。
:only-child
:only-child是少数几个真正的计数选择器之一,因为它只在元素的父元素有一个子元素时才被应用。使用您的理想示例,它的行为就像children(1)可能会做的那样。
children(1)
:nth-child
:nth-child选择器实际上可能会把你带到你想去的地方,这取决于你真正想要做什么。如果有8个子元素,你想对所有元素都设置样式,那你就不走运了。然而,如果你想要对第8个及以后的元素应用样式,试试这个:
p:nth-child( n + 8 ){ /* add styles to make it pretty */ }
不幸的是,这些可能不是你想要的解决方案。最后,您可能需要使用一些Javascript魔法来应用基于计数的样式——即使您要使用其中之一,在使用纯CSS解决方案之前,您也需要仔细考虑浏览器兼容性。
W3 CSS3伪类的Spec
编辑我读你的问题有点不同-有一些其他的方法来设置父的样式,而不是孩子。让我给你一些其他的选择器:
:empty
:not
这将设置没有子元素的样式。它本身并不是很有用,但是当与:not选择器配对时,你只能对有子元素进行样式化:
div:not(:empty) { /* We know it has stuff in it! */ }
你无法计算这里有多少纯CSS的子选项,但它是另一个有趣的选择器,可以让你做很酷的事情。
注意:这个解决方案将返回特定长度的集合的子元素,而不是您要求的父元素。希望它仍然有用。
Andre Luis想出了一个方法:http://lea.verou.me/2011/01/styling-children-based-on-their-number-with-css3/不幸的是,它只适用于IE9及以上版本。
本质上,您将:n -child()与其他处理元素位置的伪类结合在一起。这种方法允许你从具有特定长度的元素集指定元素。
例如,:nth-child(1):nth-last-child(3)匹配集合中的第一个元素,同时也是集合末尾的第三个元素。这做了两件事:保证集合只有三个元素,并且我们有三个元素中的第一个。要指定三个元素集中的第二个元素,可以使用:nth-child(2):nth-last-child(2)。
:nth-child(1):nth-last-child(3)
:nth-child(2):nth-last-child(2)
例1 -如果set有三个元素,则选择所有列表元素:
li:nth-child(1):nth-last-child(3), li:nth-child(2):nth-last-child(2), li:nth-child(3):nth-last-child(1) { width: 33.3333%; }
例1替代方案 from Lea Verou:
li:first-child:nth-last-child(3), li:first-child:nth-last-child(3) ~ li { width: 33.3333%; }
例2 -目标set的最后一个元素有三个list元素:
li:nth-child(3):last-child { /* I'm the last of three */ }
例2替代方案:
li:nth-child(3):nth-last-child(1) { /* I'm the last of three */ }
例3 - set的第二个目标元素,包含四个list元素:
li:nth-child(2):nth-last-child(3) { /* I'm the second of four */ }
澄清:
由于原问题中先前的措辞,一些SO公民担心这个答案可能具有误导性。注意,在CSS3中,样式不能基于父节点所拥有的子类型的数量应用于父节点。但是,样式可以将根据子节点拥有的兄弟姐妹的数量应用于子节点。
最初的回答:
令人难以置信的是,这在CSS3中是完全可能实现的。
/* one item */ li:first-child:nth-last-child(1) { /* -or- li:only-child { */ width: 100%; } /* two items */ li:first-child:nth-last-child(2), li:first-child:nth-last-child(2) ~ li { width: 50%; } /* three items */ li:first-child:nth-last-child(3), li:first-child:nth-last-child(3) ~ li { width: 33.3333%; } /* four items */ li:first-child:nth-last-child(4), li:first-child:nth-last-child(4) ~ li { width: 25%; }
诀窍是选择第一个子代,当它也是倒数第n个子代时。这有效地基于兄弟姐妹的数量进行选择。
这项技术的功劳归André Luís(已发现)&Lea Verou(精致)。
你不是很喜欢CSS3吗?😄
CodePen例子:
来源:
根据Matt的解决方案,我使用了以下Compass/SCSS实现。
@for $i from 1 through 20 { li:first-child:nth-last-child( #{$i} ), li:first-child:nth-last-child( #{$i} ) ~ li { width: calc(100% / #{$i} - 10px); } }
这允许您快速扩展项目的数量。
如果你打算用纯CSS(使用scss),但你在同一个父类中有不同的元素/类,你可以使用这个版本!!
&:first-of-type:nth-last-of-type(1) { max-width: 100%; } @for $i from 2 through 10 { &:first-of-type:nth-last-of-type(#{$i}), &:first-of-type:nth-last-of-type(#{$i}) ~ & { max-width: (100% / #{$i}); } }
如果你正在寻找一种方法来样式所有元素,如果超过N个存在(例如2个或更多):
li:first-child:nth-last-child(n+2), li:first-child:nth-last-child(n+2) ~ li { background-color: red; }
<ul> <li>first</li> </ul> <ul> <li>first</li> <li>second</li> </ul> <ul> <li>first</li> <li>second</li> <li>third</li> </ul>
如果你使用的是类似reactJS的东西,你可以简单地添加一个类,然后设置它的样式。
例如,假设你正在显示一个数组中的项。
app.jsx
<div className={`items-count-is-${items.length}`}> {items.map(item => { return <li>...</li>; })} </div>
例如:CSS: items-count-is-5 {...}
items-count-is-5 {...}
现在我们可以使用:has()选择器来确定项的数量,并将style应用到容器
:has()
.container { height: 50px; margin: 10px; } .container:not(:has(*)) { /* 0 elements */ background: yellow; } .container:has(> :last-child:nth-child(1)) { /* 1 element */ background: red; } .container:has(> :last-child:nth-child(2)) { /* 2 elements */ background: blue; } .container:has(> :last-child:nth-child(3)) { /* 3 elements */ background: green; } /* For N elements .container:has(> :last-child:nth-child(N)) { background: red; } */
<div class="container"> </div> <div class="container"> <div></div> </div> <div class="container"> <div></div> <div></div> </div> <div class="container"> <div></div> <div></div> <div></div> </div>