¿Puede CSS detectar el número de hijos que tiene un elemento?


Probablemente estoy respondiendo a mi propia pregunta, pero soy extremadamente curioso.

Sé que CSS puede seleccionar hijos individuales de un padre, pero hay soporte para estilizar los hijos de un contenedor, si su padre tiene una cierta cantidad de hijos.

Por ejemplo

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

Sé que suena raro, pero mi gerente me pidió que lo comprobara, no he encontrado nada por mi cuenta, así que decidí recurrir a LO antes de terminar la búsqueda.

Author: BoltClock, 2012-01-04

7 answers

Aclaración:

Debido a una frase anterior en la pregunta original, algunos ciudadanos han expresado su preocupación de que esta respuesta podría ser engañosa. Tenga en cuenta que, en CSS3, los estilos no se pueden aplicar a un nodo padre basado en el número de hijos que tiene. Sin embargo, los estilos se pueden aplicar a los nodos hijos en función del número de hermanos que tengan.


Respuesta original:

Increíblemente, esto ahora es posible puramente 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%;
}

El truco es seleccionar el primer hijo cuando también es el enésimo del último hijo. Esto selecciona efectivamente en función del número de hermanos.

El crédito por esta técnica es para André Luís (descubierto) y Lea Verou (refinado).

¿No te encanta CSS3?

CodePen Ejemplo:

Fuentes:

 547
Author: Matthematics,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-09-06 20:24:32

No. Bueno, en realidad no. Hay un par de selectores que pueden acercarte un poco, pero probablemente no funcionen en tu ejemplo y no tengan la mejor compatibilidad con navegadores.

:only-child

El :only-child es uno de los pocos selectores de conteo verdadero en el sentido de que solo se aplica cuando hay un hijo del padre del elemento. Usando tu ejemplo idealizado, actúa como children(1) probablemente lo haría.

:nth-child

El selector :nth-child podría llevarte a dónde quieres ir dependiendo de lo que realmente estás buscando hacer. Si quieres peinar todos los elementos si hay 8 niños, no tienes suerte. Sin embargo, si desea aplicar estilos a los elementos 8 y posteriores, pruebe esto:

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

Desafortunadamente, estas probablemente no son las soluciones que estás buscando. Al final, es probable que necesite usar un poco de magia de Javascript para aplicar los estilos basados en el conteo; incluso si tuviera que usar uno de estos, tendría que echar un vistazo a compatibilidad del navegador antes de ir con una solución CSS pura.

W3 CSS3 Spec on pseudo-classes

EDIT He leído su pregunta un poco diferente - hay un par de otras maneras de estilizar el padre, no los hijos. Permítanme lanzar algunos otros selectores a su manera:

:empty y :not

Este estilo de elementos que no tienen hijos. No es tan útil por sí solo, pero cuando se combina con el selector :not, solo puede elementos que tienen hijos:

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

No puedes contar cuántos niños están disponibles con CSS puro aquí, pero es otro selector interesante que te permite hacer cosas geniales.

 34
Author: derekerdmann,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-01-04 02:02:21

NOTA: Esta solución devolverá los hijos de conjuntos de cierta longitud, no el elemento padre como ha pedido. Con suerte, todavía es útil.

A Andre Luis se le ocurrió un método: http://lea.verou.me/2011/01/styling-children-based-on-their-number-with-css3 / Desafortunadamente, solo funciona en IE9 y superiores.

Esencialmente, se combina :nth-child() con otras pseudo clases que tratan con la posición de un elemento. Este enfoque le permite especificar elementos de conjuntos de elementos con longitudes específicas.

Por ejemplo :nth-child(1):nth-last-child(3) coincide con el primer elemento de un conjunto mientras que también es el 3er elemento desde el final del conjunto. Esto hace dos cosas: garantiza que el conjunto solo tiene tres elementos y que tenemos el primero de los tres. Para especificar el segundo elemento del conjunto de tres elementos, usaríamos :nth-child(2):nth-last-child(2).


Ejemplo 1-Seleccionar todos los elementos de la lista si set tiene tres elementos:

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

Ejemplo 1 alternativa de Lea Verou:

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


Ejemplo 2-objetivo último elemento de set con tres elementos de lista:

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

Ejemplo 2 alternativa:

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


Ejemplo 3-objetivo segundo elemento de set con cuatro elementos de lista:

li:nth-child(2):nth-last-child(3) {
    /* I'm the second of four */
}
 13
Author: ifugu,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-09-11 20:40:43

Trabajando fuera de la solución de Matt, usé la siguiente implementación de 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);
    }
  }

Esto le permite expandir rápidamente el número de elementos.

 8
Author: mwtidd,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-08-10 14:57:59

Sí podemos hacer esto usando n-ésimo hijo como así

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

Esto hará que el 8vo hijo div en adelante se vuelva rojo. Espero que esto ayude...

Además, si alguien alguna vez dice " hey, no se puede hacer con estilo usando css, utilice JS!!!"duda de ellos inmediatamente. CSS es extremadamente flexible hoy en día

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

En el ejemplo, los primeros 7 niños son azules, luego los 8 en adelante son rojos...

 6
Author: AlanFoster,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-01-04 01:44:17

Si vas a hacerlo en CSS puro (usando scss) pero tienes diferentes elementos/clases dentro de la misma clase padre puedes usar esta versión!!

  &: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});
    }
  }
 4
Author: Juan Sebastian Contreras Aceve,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-04-12 17:39:22

No, no hay nada como esto en CSS. Sin embargo, puede usar JavaScript para calcular el número de hijos y aplicar estilos.

 0
Author: Niet the Dark Absol,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-01-04 01:21:37