web-dev-qa-db-fra.com

CSS peut-il détecter le nombre d'enfants qu'un élément a?

Je réponds probablement à ma propre question, mais je suis extrêmement curieux.

Je sais que CSS peut sélectionner les enfants individuels d'un parent, mais existe-t-il une possibilité de dénommer les enfants d'un conteneur, si ce parent a un certain nombre d'enfants?.

par exemple

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

Je sais que cela semble étrange, mais mon responsable m'a demandé de vérifier, n'ayant rien trouvé par moi-même, j'ai décidé de me tourner vers SO avant de mettre fin à la recherche.

277
Brodie

Clarification:

En raison d'un libellé précédent dans la question initiale, quelques SO citoyens ont dit craindre que cette réponse ne soit trompeuse. Notez qu'en CSS3, les styles ne peuvent pas être appliqués à un nœud parent en fonction du nombre d'enfants qu'il a. Toutefois, les styles peuvent être appliqués aux nœuds enfants en fonction du nombre de frères qu'ils possèdent.


Réponse originale:

Incroyablement, cela est maintenant possible uniquement en 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%;
}

L'astuce consiste à sélectionner le premier enfant lorsqu'il s'agit également du nième enfant du dernier. Cela sélectionne effectivement en fonction du nombre de frères et sœurs.

Le mérite de cette technique revient à André Luís (découvert) et à Léa Verou (raffinée).

N'aimez-vous pas simplement CSS3? ????

Exemple CodePen:

Sources:

628
Matthematics

Non, pas vraiment. Quelques sélecteurs peuvent vous rapprocher un peu, mais ne fonctionneront probablement pas dans votre exemple et n’ont pas la meilleure compatibilité de navigateur.

:only-child

Le :only-child est l'un des rares sélecteurs de comptage vrai dans le sens où il n'est appliqué que s'il existe un enfant du parent de l'élément. En utilisant votre exemple idéalisé, il agit comme si children(1) le ferait probablement.

:nth-child

Le sélecteur :nth-child peut en fait vous amener où vous voulez aller en fonction de ce que vous cherchez vraiment à faire. Si vous voulez styler tous les éléments s'il y a 8 enfants, vous n'avez pas de chance. Si, toutefois, vous souhaitez appliquer des styles aux éléments 8 et suivants, essayez ceci:

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

Malheureusement, ce ne sont probablement pas les solutions que vous recherchez. En fin de compte, vous aurez probablement besoin d’utiliser une certaine magie Javascript pour appliquer les styles basés sur le nombre. Même si vous utilisiez l’un de ces styles, vous devrez vous pencher sérieusement sur la compatibilité du navigateur avant de passer à une version pure. Solution CSS.

Spec W3 CSS3 sur pseudo-classes

EDIT J'ai lu votre question un peu différemment - il existe deux autres façons de styler le parent , pas les enfants. Laissez-moi jeter quelques autres sélecteurs à votre façon:

:empty et :not

Cette styles des éléments qui n'ont pas d'enfants. Ce n'est pas très utile en soi, mais une fois associé au sélecteur :not, vous ne pouvez styler que les éléments ayant des enfants:

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

Ici, vous ne pouvez pas compter le nombre d’enfants disponibles avec du CSS pur, mais c’est un autre sélecteur intéressant qui vous permet de faire des choses sympas.

37
derekerdmann

REMARQUE: cette solution renvoie les enfants d'ensembles de certaines longueurs et non l'élément parent comme vous l'avez demandé. Espérons que cela reste utile.

Andre Luis a proposé une méthode: http://lea.verou.me/2011/01/styling-children-based-on-the-number-with-css3/ Malheureusement, cela ne fonctionne que dans IE9 et ci-dessus.

En gros, vous combinez: nth-child () avec d’autres pseudo-classes traitant de la position d’un élément. Cette approche vous permet de spécifier des éléments à partir de des ensembles d’éléments de longueurs spécifiques .

Par exemple, :nth-child(1):nth-last-child(3) correspond au premier élément d'un ensemble tout en étant le troisième élément à partir de la fin de l'ensemble. Cela fait deux choses: garantit que l’ensemble ne contient que trois éléments et que nous avons le premier des trois. Pour spécifier le deuxième élément du jeu de trois éléments, nous utiliserions :nth-child(2):nth-last-child(2).


Exemple 1 - Sélectionnez tous les éléments de la liste si ceux-ci comportent trois éléments:

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%;
}

Exemple 1 alternative de Lea Verou:

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


Exemple 2 - cible le dernier élément du jeu avec trois éléments de liste:

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

Exemple 2 alternative:

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


Exemple 3 - cible le deuxième élément d'un ensemble avec quatre éléments de liste:

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

En travaillant avec la solution de Matt, j'ai utilisé l'implémentation Compass/SCSS suivante.

@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);
    }
  }

Cela vous permet d’augmenter rapidement le nombre d’articles.

9
mwtidd

oui, nous pouvons le faire en utilisant nth enfant comme si

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

Cela fera en sorte que l'enfant de la 8ème division devienne rouge. J'espère que cela t'aides...

De plus, si quelqu'un dit: "Hé, ils ne peuvent pas utiliser de style CSS, utilisez JS !!!" doutez d'eux immédiatement. CSS est extrêmement flexible de nos jours

Exemple :: http://jsfiddle.net/uWrLE/1/

Dans l'exemple, les 7 premiers enfants sont bleus, ensuite 8 sont rouges ...

6
AlanFoster

Si vous voulez le faire en CSS pur (avec scss) mais que vous avez différents éléments/classes dans la même classe parente, vous pouvez utiliser cette version!

  &: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});
    }
  }

Non, il n'y a rien de tel en CSS. Vous pouvez cependant utiliser JavaScript pour calculer le nombre d'enfants et appliquer des styles.

0