CSS可以检测元素的子元素数吗?

时间:2012-01-04 01:20:25

标签: css css-selectors

我可能回答了我自己的问题,但我非常好奇。

我知道CSS可以选择父项的单个子项,但如果其父项具有一定数量的子项,则可以支持对容器的子项进行样式化。

例如

container:children(8) .child {
  //style the children this way if there are 8 children
}

我知道这听起来很奇怪,但是我的经理让我检查一下,没有发现任何东西,所以我决定在结束搜索之前转向SO。

8 个答案:

答案 0 :(得分:609)

<强>澄清:

由于原始问题中的先前措辞,一些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%;
}

诀窍是选择第一个孩子,当它也是最后一个孩子时。这有效地根据兄弟姐妹的数量进行选择。

这项技术归功于AndréLuís(已发现)&amp; Lea Verou(精制)。

难道你不喜欢CSS3吗?

CodePen示例:

来源:

答案 1 :(得分:37)

没有。好吧,不是真的。有几个选择器可以让你有点接近,但可能在你的例子中不起作用,并且没有最佳的浏览器兼容性。

:only-child

:only-child是少数真正的计数选择器之一,只有当元素的父元素有一个子元素时才会应用它。使用您理想化的示例,它可能会像children(1)那样。

:nth-child

:nth-child选择器实际上可能会让您到达目的地,具体取决于您真正想要做的事情。如果你想要有8个孩子的所有元素的样式,你运气不好。但是,如果要将样式应用于第8个​​和更晚的元素,请尝试以下方法:

p:nth-child( n + 8 ){
    /* add styles to make it pretty */
}

不幸的是,这些可能不是您正在寻找的解决方案。最后,您可能需要使用一些Javascript魔法来根据计数应用样式 - 即使您要使用其中一种,在使用纯净之前,您需要仔细查看浏览器兼容性CSS解决方案。

W3 CSS3 Spec on pseudo-classes

编辑我对您的问题的看法略有不同 - 还有其他一些方法可以设置父级的样式,而不是孩子。让我按照你的方式抛出一些其他选择器:

:empty:not

此样式元素没有子元素。它本身没有用,但与:not选择器配对时,您只能设置具有子项的元素的样式:

div:not(:empty) {
    /* We know it has stuff in it! */
}

你无法计算纯CSS中有多少孩子可用,但它是另一个有趣的选择器,可以让你做很酷的事情。

答案 2 :(得分:14)

注意:此解决方案将返回具有特定长度的集合的子集,而不是您所询问的父元素。希望它仍然有用。

Andre Luis提出了一种方法:http://lea.verou.me/2011/01/styling-children-based-on-their-number-with-css3/不幸的是,它仅适用于IE9及以上版本。

基本上,您将:nth-​​child()与处理元素位置的其他伪类组合在一起。此方法允许您指定来自具有特定长度的元素集的元素。

例如:nth-child(1):nth-last-child(3)匹配集合中的第一个元素,同时也是集合末尾的第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%;
}
来自Lea Verou的

示例1替代

li:first-child:nth-last-child(3),
li:first-child:nth-last-child(3) ~ li {
    width: 33.3333%;
}


示例2 - 使用三个列表元素定位集合的最后一个元素:

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 - 使用四个列表元素定位集合的第二个元素:

li:nth-child(2):nth-last-child(3) {
    /* I'm the second of four */
}

答案 3 :(得分:9)

使用Matt的解决方案,我使用了以下Compass / SCSS实现。

<SPAN id=ctl00_ContentPlaceHolder1_lblDateCreated2>5/22/2012 8:14:08 PM</SPAN>

这使您可以快速扩展项目数。

答案 4 :(得分:7)

是的,我们可以使用nth-child这样做

div:nth-child(n + 8) {
    background: red;
}

这将使第8个div孩子成为红色。希望这会有所帮助...

另外,如果有人说“嘿,他们不能用css风格完成,请使用JS !!!”立刻怀疑他们。 CSS现在非常灵活

示例:: http://jsfiddle.net/uWrLE/1/

在示例中,前7个孩子是蓝色,然后8个孩子是红色......

答案 5 :(得分:4)

如果您打算在纯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});
    }
  }

答案 6 :(得分:2)

如果您正在寻找一种方法,如果存在多于 N 个元素(例如 2 个或更多),则可以为所有元素设置样式:

li:first-child:nth-last-child(n+2),
li:first-child:nth-last-child(n+2) ~ li {
  background: 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>

答案 7 :(得分:0)

不,CSS中没有这样的东西。但是,您可以使用JavaScript计算子项数并应用样式。