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

Bro*_*die 285 css css-selectors

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

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

例如

container:children(8) .child {
  //style the children this way if there are 8 children
}
Run Code Online (Sandbox Code Playgroud)

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

Mat*_*ics 651

澄清:

由于原始问题中的先前措辞,一些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%;
}
Run Code Online (Sandbox Code Playgroud)

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

这项技术归功于AndréLuís(已发现)和Lea Verou(精制).

你不喜欢CSS3吗?

CodePen示例:

资料来源:

  • 这太棒了,谢谢.有趣的使用nth-last-child,+1也可以选择你的来源!谢谢! (14认同)
  • 非常便利.我写了一个使用这种技术的SASS mixin:http://codepen.io/anon/pen/pJeLdE?edit = 110 (7认同)
  • 请注意,您可以使用`:only-child`代替`:first-child:nth-​​last-child(1)`. (7认同)
  • 只是要指出,随着许多浏览器中植入新的“:has()”选择器,CSS 现在可以选择父级。 (4认同)
  • 可能很高兴为不习惯多个伪选择器的人添加为什么这样有效(就像我直到现在;).这里发生的是,它选择同时从开始/顶部开始的子x和从结尾开始的子y的子.因此,如果确实有x + y个孩子,这只会选择一些东西. (3认同)
  • 如果它可以在Codepen中工作,但不能在我的项目中工作,那绝对是我的错。我的错。这个答案是正确的!是的,我说! (2认同)

der*_*ann 39

不,嗯,不是真的.有几个选择器可以让你有点接近,但可能不会在你的例子中工作,并没有最好的浏览器兼容性.

:only-child

:only-child是少数真正的计数选择器之一,它只在元素的父元素有一个子元素时应用.使用你理想化的例子,它children(1)可能就像.

:nth-child

:nth-child这里你要根据你真正希望做的去选择实际上可能得到你.如果你想要有8个孩子的所有元素的样式,你运气不好.但是,如果要将样式应用于第8个​​和更高版本的元素,请尝试以下操作:

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

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

关于伪类的W3 CSS3规范

编辑我有点不同地阅读你的问题 - 还有其他几种方式来塑造父母,而不是孩子.让我按你的方式抛出一些其他选择器:

:empty:not

这个样式元素没有子元素.它本身并没有那么有用,但是当与:not选择器配对时,您只能设置具有子项的元素的样式:

div:not(:empty) {
    /* We know it has stuff in it! */
}
Run Code Online (Sandbox Code Playgroud)

你不能在这里计算纯CSS有多少孩子可用,但它是另一个有趣的选择器,让你做很酷的事情.


Tem*_*fif 35

现在我们可以使用:has()选择器来识别项目数量并将样式应用于容器以及子项目https://css-tip.com/number-elements-has-selector/

下面给大家一个准确的统计:

.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;
}
*/
Run Code Online (Sandbox Code Playgroud)
<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>
Run Code Online (Sandbox Code Playgroud)

但您也可以进行范围选择:

.container {
  height: 50px;
  margin: 10px;
}

.container:has(> :nth-child(3)) { /* 3 elements or more */
  background: blue;
}
/* .container:has(> :nth-child(X)) : X elements or more */

.container:has(> :last-child:nth-child(-n + 3)) { /* between 1 and 3 elements */
  border: 5px solid red;
}
/* .container:has(> :last-child:nth-child(-n + X)): between 1 and X elements */

.container:has(> :nth-last-child(3):nth-child(-n + 3)) { /* between 3 and 5 elements */
  width: 80%;
}
/* .container:has(> :nth-last-child(X):nth-child(-n + (Y - X + 1))): between X and Y elements */
Run Code Online (Sandbox Code Playgroud)
<div class="container">
  <div></div>
</div>
<div class="container">
  <div></div>
  <div></div>
</div>
<div class="container">
  <div></div>
  <div></div>
  <div></div>
</div>
<div class="container">
  <div></div>
  <div></div>
  <div></div>
  <div></div>
</div>
<div class="container">
  <div></div>
  <div></div>
  <div></div>
  <div></div>
  <div></div>
</div>
<div class="container">
  <div></div>
  <div></div>
  <div></div>
  <div></div>
  <div></div>
  <div></div>
</div>
Run Code Online (Sandbox Code Playgroud)

  • 目前还处于非常早期的阶段。它不应该在生产级别使用 https://caniuse.com/css-has (2认同)

ifu*_*ugu 16

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

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%;
}
Run Code Online (Sandbox Code Playgroud)

Lea Verou的示例1替代方案:

li:first-child:nth-last-child(3),
li:first-child:nth-last-child(3) ~ li {
    width: 33.3333%;
}
Run Code Online (Sandbox Code Playgroud)


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

li:nth-child(3):last-child {
    /* I'm the last of three */
}
Run Code Online (Sandbox Code Playgroud)

示例2替代方案:

li:nth-child(3):nth-last-child(1) {
    /* I'm the last of three */
}
Run Code Online (Sandbox Code Playgroud)


示例3 - 具有四个列表元素的set的第二个元素:

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

  • 再次强调,这是兄弟姐妹的数量,而不是孩子的数量 (2认同)

小智 9

使用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);
    }
  }
Run Code Online (Sandbox Code Playgroud)

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

  • 而不是这个,你可以轻松使用Flexbox ... (4认同)

Ala*_*ter 6

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

div:nth-child(n + 8) {
    background: red;
}
Run Code Online (Sandbox Code Playgroud)

这将使第8个div孩子成为红色.希望这可以帮助...

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

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

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

  • 我不认为这正是Brodie所要求的 - 这将在给定数量之后设置_children_的样式,但不能根据其子项的数量选择祖先/包含元素. (2认同)

小智 6

如果您打算在纯 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});
    }
  }
Run Code Online (Sandbox Code Playgroud)


fre*_*ett 5

如果您正在寻找一种方法来设置所有元素的样式(如果存在超过 N 个元素(例如 2 个或更多)):

li:first-child:nth-last-child(n+2),
li:first-child:nth-last-child(n+2) ~ li {
  background-color: red;
}
Run Code Online (Sandbox Code Playgroud)
<ul>
  <li>first</li>
</ul>

<ul>
  <li>first</li>
  <li>second</li>
</ul>

<ul>
  <li>first</li>
  <li>second</li>
  <li>third</li>
</ul>
Run Code Online (Sandbox Code Playgroud)