Selector de CSS para el primer elemento con clase

Tengo un montón de elementos con un nombre de clase red , pero parece que no puedo seleccionar el primer elemento con la class="red" con la siguiente regla de CSS:

 .red:first-child { border: 5px solid red; } 
 

¿Qué hay de malo en este selector y cómo lo corrijo?

Gracias a los comentarios, descubrí que el elemento tiene que ser el primer hijo de su padre para ser seleccionado, que no es el caso que tengo. Tengo la siguiente estructura, y esta regla falla como se menciona en los comentarios:

 .home .red:first-child { border: 1px solid red; } 
 
blah

first

second

third

fourth

¿Cómo puedo apuntar al primer niño con clase red ?

Este es uno de los ejemplos más conocidos de autores que no entienden cómo funciona :first-child funciona. Introducido en CSS2 , la pseudoclase de :first-child representa el primer hijo de su padre . Eso es. Existe una idea errónea muy común de que selecciona el elemento secundario que coincide con las condiciones especificadas por el rest del selector compuesto. Debido a la forma en que funcionan los selectores (ver aquí una explicación), eso simplemente no es cierto.

Selectores de nivel 3 introduce una :first-of-type , que representa el primer elemento entre hermanos de su tipo de elemento. Esta respuesta explica, con ilustraciones, la diferencia entre :first-child y :first-of-type . Sin embargo, como con :first-child , no mira ninguna otra condición o atributo. En HTML, el tipo de elemento está representado por el nombre de la etiqueta. En la pregunta, ese tipo es p .

Lamentablemente, no existe una pseudoclase similar a la :first-of-class clase para unir el primer elemento secundario de una clase determinada. Una solución que Lea Verou y yo propusimos para esto (aunque de manera totalmente independiente) es aplicar primero los estilos deseados a todos sus elementos con esa clase:

 /* * Select all .red children of .home, including the first one, * and give them a border. */ .home > .red { border: 1px solid red; } 

… luego “deshace” los estilos para los elementos con la clase que viene después de la primera , usando el combinador hermano general ~ en una regla primordial:

 /* * Select all but the first .red child of .home, * and remove the border from the previous rule. */ .home > .red ~ .red { border: none; } 

Ahora solo el primer elemento con class="red" tendrá un borde.

Aquí hay una ilustración de cómo se aplican las reglas:

 
blah

first

second

third

fourth

  1. No se aplican reglas; no se da borde
    Este elemento no tiene la clase red , por lo que se omite.

  2. Solo se aplica la primera regla; se renderiza un borde rojo.
    Este elemento tiene la clase red , pero no está precedida por ningún elemento con la clase red en su elemento primario. Por lo tanto, la segunda regla no se aplica, solo la primera y el elemento mantiene su borde.

  3. Ambas reglas son aplicadas; no se da borde
    Este elemento tiene la clase red . También está precedido por al menos otro elemento con la clase red . Por lo tanto, se aplican ambas reglas, y la segunda statement de border anula la primera, por lo tanto, “deshacerla”, por así decirlo.

Como beneficio adicional, aunque se introdujo en Selectores 3, el combinador de hermanos general es bastante bien compatible con IE7 y más reciente, a diferencia de :first-of-type y :nth-of-type() que solo son compatibles con IE9 en adelante . Si necesita un buen soporte de navegador, tiene suerte.

De hecho, el hecho de que el combinador hermano sea el único componente importante de esta técnica, y cuenta con un soporte de navegador tan increíble, hace que esta técnica sea muy versátil; puede adaptarse para filtrar elementos por otras cosas, además de selectores de clase:

  • Puede usar esto para evitar :first-of-type en su :first-of-type en IE7 e IE8, simplemente suministrando un selector de tipo en lugar de un selector de clase (de nuevo, más sobre su uso incorrecto aquí en una sección posterior):

     article > p { /* Apply styles to article > p:first-of-type, which may or may not be :first-child */ } article > p ~ p { /* Undo the above styles for every subsequent article > p */ } 
  • Puede filtrar por selectores de atributos o cualquier otro selector simple en lugar de clases.

  • También puede combinar esta técnica primordial con pseudo-elementos aunque los pseudo-elementos técnicamente no sean simples selectores.

Tenga en cuenta que para que esto funcione, necesitará saber de antemano cuáles serán los estilos predeterminados para sus otros elementos hermanos para que pueda anular la primera regla. Además, dado que esto implica la supresión de las reglas en CSS, no puede lograr lo mismo con un solo selector para usar con la API de Selectores o los localizadores de CSS de Selenium .

Vale la pena mencionar que Selectores 4 introduce una extensión a la notación :nth-child() (originalmente una pseudoclase completamente nueva llamada :nth-match() ), que le permitirá usar algo como :nth-child(1 of .red) en lugar de un hipotético .red:first-of-class . Al tratarse de una propuesta relativamente reciente, aún no hay suficientes implementaciones interoperables para poder utilizarlas en los sitios de producción. Espero que esto cambie pronto. Mientras tanto, la solución alternativa que sugerí debería funcionar para la mayoría de los casos.

Tenga en cuenta que esta respuesta asume que la pregunta busca cada primer elemento secundario que tiene una clase determinada. No existe una pseudoclase ni una solución de CSS genérica para la nésima coincidencia de un selector complejo en todo el documento : la existencia de una solución depende en gran medida de la estructura del documento. jQuery proporciona :eq() :first :last y más para este propósito, pero tenga en cuenta que funcionan de manera muy diferente a :nth-child() et al . Usando la API de Selectores, puede usar document.querySelector() para obtener la primera coincidencia:

 var first = document.querySelector('.home > .red'); 

O use document.querySelectorAll() con un indexador para elegir una coincidencia específica:

 var redElements = document.querySelectorAll('.home > .red'); var first = redElements[0]; var second = redElements[1]; // etc 

Aunque la .red:nth-of-type(1) en la respuesta original aceptada por Philip Daubmeier funciona (la cual fue escrita originalmente por Martyn pero eliminada desde entonces), no se comporta de la manera que usted esperaría.

Por ejemplo, si solo desea seleccionar la p en su marcado original:

 

… entonces no puede usar .red:first-of-type (equivalente a .red:nth-of-type(1) ), porque cada elemento es el primero (y único) uno de su tipo ( p y div respectivamente), por lo que ambos serán emparejados por el selector.

Cuando el primer elemento de una cierta clase es también el primero de su tipo , la pseudoclase funcionará, pero esto solo ocurre por coincidencia . Este comportamiento se demuestra en la respuesta de Felipe. En el momento en que inserte un elemento del mismo tipo antes de este elemento, el selector fallará. Tomando el marcado actualizado:

 
blah

first

second

third

fourth

Aplicar una regla con .red:first-of-type funcionará, pero una vez que agregue otra p sin la clase:

 
blah

dummy

first

second

third

fourth

… el selector fallará inmediatamente, porque el primer elemento .red es ahora el segundo elemento p .

El selector :first-child está destinado, como su nombre lo indica, a seleccionar el primer hijo de una etiqueta principal. Los niños deben estar incrustados en la misma etiqueta principal. Su ejemplo exacto funcionará (lo intenté aquí ):

  

first

second

¿Tal vez has nested tus tags en diferentes tags padre? ¿Son tus tags de clase red realmente las primeras tags debajo del padre?

Tenga en cuenta también que esto no solo se aplica a la primera etiqueta de este tipo en todo el documento, sino cada vez que un nuevo padre se adapta a ella, como:

 

first

second

third

fourth

first y third serán rojos luego.

Actualizar:

No sé por qué martyn eliminó su respuesta, pero tenía la solución, el selector :nth-of-type :

      
blah

first

second

third

fourth

Créditos a Martyn . Más infos por ejemplo aquí . Tenga en cuenta que este es un selector de CSS 3, por lo tanto, no todos los navegadores lo reconocerán (por ejemplo, IE8 o anterior).

La respuesta correcta es:

 .red:first-child, :not(.red) + .red { border:5px solid red } 

Parte I: si el elemento es primero para su elemento primario y tiene una clase “roja”, tendrá borde.
Parte II: Si el elemento “.red” no es primero para su elemento primario, sino que está siguiendo inmediatamente un elemento sin clase “.red”, también deberá merecer el honor de dicho borde.

Violín o no sucedió.

La respuesta de Philip Daubmeier, si bien es aceptada, no es correcta, vea el violín adjunto.
La respuesta de BoltClock funcionaría, pero define y sobrescribe innecesariamente los estilos
(particularmente un problema donde de otra manera heredaría un borde diferente – no desea declarar otro al borde: ninguno)

EDITAR: En caso de que tenga “rojo” seguido de no rojo varias veces, cada “primer” rojo obtendrá el borde. Para evitar eso, uno necesitaría usar la respuesta de BoltClock. Ver violín

podrías usar first-of-type o nth-of-type(1)

 .red { color: green; } /* .red:nth-of-type(1) */ .red:first-of-type { color: red; } 
 
blah

first

second

third

fourth

Para que coincida con su selector, el elemento debe tener un nombre de clase de red y debe ser el primer hijo de su padre.

 
Blah

Blah

Como las otras respuestas cubren lo que está mal , intentaré la otra mitad, cómo solucionarlo. Desafortunadamente, no sé si tienes una solución CSS única aquí, al menos no que yo pueda pensar . Aunque hay otras opciones …

  1. Asigna una first clase al elemento cuando lo generes, así:

     

    CSS:

     .first.red { border:5px solid red; } 

    Este CSS solo combina elementos con red clases first y red .

  2. Alternativamente, haga lo mismo en JavaScript, por ejemplo, aquí está lo que jQuery usaría para hacer esto, usando el mismo CSS que el anterior:

     $(".red:first").addClass("first"); 

De acuerdo con tu problema actualizado

 
blah

first

second

third

fourth

qué tal si

 .home span + .red{ border:1px solid red; } 

Esto seleccionará el hogar de la clase , luego el intervalo del elemento y finalmente todos los elementos .red que se colocan inmediatamente después de los elementos del intervalo.

Referencia: http://www.w3schools.com/cssref/css_selectors.asp

Puede cambiar su código a algo así para que funcione

 
blah

first

second

third

fourth

Esto hace el trabajo por ti

 .home span + .red{ border:3px solid green; } 

Aquí hay una referencia de CSS de SnoopCode sobre eso.

Estoy usando debajo de CSS para tener una imagen de fondo para la lista ul li

 #footer .module:nth-of-type(1)>.menu>li:nth-of-type(1){ background-position: center; background-image: url(http://sofes.miximages.com/css/icon-home.png); background-repeat: no-repeat; } 
 

Puede usar nth-of-type (1) pero asegúrese de que el sitio no necesite soportar IE7 etc., si este es el caso use jQuery para agregar body class luego encuentre element mediante IE7 body class luego el nombre del elemento, luego agregue en el estilo n-child a él.

Prueba esto :

  .class_name > *:first-child { border: 1px solid red; } 

Tengo este en mi proyecto.

 div > .b ~ .b:not(:first-child) { background: none; } div > .b { background: red; } 
 

The first paragraph.

The second paragraph.

The third paragraph.

The fourth paragraph.

Por alguna razón, ninguna de las respuestas anteriores parecía estar abordando el caso del primer y único hijo verdadero del padre.

 #element_id > .class_name:first-child 

Todas las respuestas anteriores fallarán si desea aplicar el estilo solo al primer hijo de clase dentro de este código.

  

Pruebe esto simple y efectivo

  .home > span + .red{ border:1px solid red; } 

Prueba esta solución:

  .home p:first-of-type { border:5px solid red; width:100%; display:block; } 
 
blah

first

second

third

fourth

Las respuestas anteriores son muy complejas.

 .class:first-of-type { } 

Esto seleccionará el primer tipo de clase. Fuente MDN

Solo se necesita primero y solo un párrafo se vuelve rojo. ¿Cómo?

  

Needed only first and only one paragraph had red. How?

The first paragraph.

The second paragraph.

The third paragraph.

The fourth paragraph.

Creo que usar el selector relativo + para seleccionar elementos colocados inmediatamente después, funciona aquí de la mejor manera (como se sugirió antes).

También es posible que este caso use este selector

 .home p:first-of-type 

pero este es un selector de elementos, no la clase uno.

Aquí tienes una buena lista de selectores de CSS: https://kolosek.com/css-selectors/