2012-06-08 34 views
7

Al usar CSS, ¿hay alguna forma de seleccionar el descendiente más cercano de un elemento que coincida con un cierto selector?CSS para seleccionar el descendiente más cercano?

<div class="foo"> <!-- if we're inside this --> 
    <div> 
    <br /> 
    <div class="bar"> <!-- match this --> 
     <div class="bar"> <!-- but not this --> 
     <div class="bar"> <!-- or this --> 
     </div> 
     </div> 
    </div> 
    <div class="bar"> <!-- I don't really care whether we match this --> 
    </div> 
    </div> 
</div> 

Es decir, algo que se seleccione la primera .bar dentro de cualquier .foo (independientemente del número de elementos secundarios o hermanos están en el medio), pero no el segundo o tercer .bar.

+1

Si tiene una segunda '.bar' que es una hermana a la que desea seleccionar, ¿desea que también se seleccione? – Paulpro

+0

Idealmente no, pero eso también sería aceptable. –

+0

¿Habrá solo una 'barra', con todas las demás' barras' contenidas en ella? – animuson

Respuesta

13

Aquí es mi respuesta hacktastic: http://jsfiddle.net/thirtydot/gqJdP/2/

/*repeat for as many levels as there could be*/ 
.foo > .bar, 
.foo > :not(.bar) > .bar, 
.foo > :not(.bar) > :not(.bar) > .bar { 
    border-color: blue; 
} 
.bar { 
    border: 1px solid red; 
    padding: 10px; 
} 

Citando a mí mismo de un comentario:

Mi sugerencia es viable, aunque de mal gusto, si puede colocar un límite superior en el número posible de los padres entre .foo y .bar que desea hacer coincidir. Incluso si tuviera que repetir el selector (digamos) 10 veces, no es tan malo.

+2

Fan-hackin'-tastic! Odiaría usar esto en mi propio CSS jaja :) – Paulpro

+1

Este también está asumiendo que el .bar es un niño directo ... –

+0

@StephRose: No del todo. Examine el selector cuidadosamente. Supongo que es un hijo directo de '.foo', o un hijo directo de algo que no es' .bar' que es un hijo directo de '.foo', o * *. – thirtydot

2

No, no hay manera de hacer lo que está pidiendo completamente usando solo CSS. Puede seleccionar nth-child o nth-of-type, pero no the-nth-item-matching-this-selector.

como "prueba", revisar la lista de selectores CSS3 disponibles (que cubre todas las capacidades de CSS1 y CSS 2.1):
http://www.w3.org/TR/selectors/

Usted tendrá que usar JavaScript (en el cliente) o servidor manipulación lateral (por ejemplo anotar el primer elemento de ese tipo con una clase especial).


Editar: Basado en su edición, que puede hacer:

.foo .bar  { font-weight:bold; color:red } 
.foo .bar .bar { font-weight:normal; color:black } 

es decir, lo que necesita de forma explícita "deshacer" el estilo aplicado sobre los antepasados ​​que se heredan. Esto es "frágil" — si cambia un estilo en un antecesor, debe asegurarse de cambiar también el valor en la regla correspondiente "anular" — pero será efectiva.

Y, si @thirtydot publica su truco como respuesta, todos podemos aceptar eso también.

Aunque probablemente no ayude, tenga en cuenta también que puede lograr este objetivo with XPath.

+0

Se supone que debemos obtener 'nth-matching' en CSS4 (siempre que sea), pero no veo cómo eso ayudaría en este caso. – animuson

+0

@animuson Con 'nth-matching' solo sería' .foo .bar: nth-matching (1) ', ¿no? – Phrogz

+0

Buena sugerencia para deshacer. –

-3

Esto sólo debe recibir el primer elemento secundario de .foo:

.foo > .bar 

Y no seleccione ninguna más abajo en la cadena.

+1

-1 Como se muestra en el código de ejemplo, la barra. ** no es necesariamente un elemento secundario directo. – Phrogz

+0

Es cierto. No viste eso. No es que los divs deberían estar dentro de las etiquetas p de todos modos. –

+0

@StephRose: Sí, tienes razón sobre eso. Lo arreglé en la demostración en mi respuesta. – thirtydot