css-selectors selectores - Selector de CSS para el primer elemento con clase




estilo regla (16)

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

.red:first-child {
    border: 5px solid red;
}
<p class="red"></p>
<div class="red"></div>

¿Qué está mal 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, lo 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;
}
<div class="home">
    <span>blah</span>
    <p class="red">first</p>
    <p class="red">second</p>
    <p class="red">third</p>
    <p class="red">fourth</p>
</div>

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


Answers

Prueba esto simple y eficaz

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

Puedes cambiar tu código a algo como esto para que funcione

<div class="home">
  <span>blah</span>
  <p class="red">first</p>
  <p class="red">second</p>
  <p class="red">third</p>
  <p class="red">fourth</p>
</div>

Esto hace el trabajo por ti

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

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


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

<!DOCTYPE html><html><head><style>

article p:nth-child(1){background: red}
article p:first-child{background: red}

</style></head><body>

<p style="color:blue">Needed only first and only one paragraph had red. How?</p>

<article>
<p>The first paragraph.</p>
<div><p>The second paragraph.</p></div>
<p>The third paragraph.</p>
<div><p>The fourth paragraph.</p></div>
</article>

</body></html>


Estoy usando CSS abajo 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://monagentvoyagessuperprix.j3.voyagesendirect.com/images/stories/images_monagentvoyagessuperprix/layout/icon-home.png);
  background-repeat: no-repeat;
}
<footer id="footer">
  <div class="module">
    <ul class="menu ">
      <li class="level1 item308 active current"></li>
      <li> </li>
    </ul> 
  </div>
  <div class="module">
    <ul class="menu "><li></li>
      <li></li> 
    </ul>
  </div>
  <div class="module">
    <ul class="menu ">
      <li></li>
      <li></li>
    </ul>
  </div>
</footer>


Prueba esto :

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

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

#element_id > .class_name:first-child

Todas las respuestas anteriores fallarán si desea aplicar el estilo solo al niño de primera clase dentro de este código.

<aside id="element_id">
  Content
  <div class="class_name">First content that need to be styled</div>
  <div class="class_name">
    Second content that don't need to be styled
    <div>
      <div>
        <div class="class_name">deep content - no style</div>
        <div class="class_name">deep content - no style</div>
        <div>
          <div class="class_name">deep content - no style</div>
        </div>
      </div>
    </div>
  </div>
</aside>

Este es uno de los ejemplos más conocidos de autores que malinterpretan cómo funciona el :first-child . Introducido en CSS2 , la pseudoclase de :first-child representa el primer hijo de su padre . Eso es. Hay una idea errónea muy común de que recoge cualquier elemento secundario que sea el primero en cumplir las condiciones especificadas por el resto del selector compuesto. Debido a la forma en que funcionan los selectores (consulte here una explicación), eso simplemente no es cierto.

Los selectores de nivel 3 introducen una :first-of-type pseudo-clase de primera clase , que representa el primer elemento entre los hermanos de su tipo de elemento. Esta respuesta explica, con ilustraciones, la diferencia entre :first-child y :first-of-type . Sin embargo, al igual que con :first-child , no se ve en 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 .

Desafortunadamente, no hay una :first-of-class similar para hacer coincidir el primer elemento secundario de una clase dada. Una solución que Lea Verou y yo creamos 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 "deshaga" los estilos para los elementos con la clase que viene después del primero , usando el combinador general de hermanos ~ en una regla de reemplazo:

/* 
 * 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:

<div class="home">
  <span>blah</span>         <!-- [1] -->
  <p class="red">first</p>  <!-- [2] -->
  <p class="red">second</p> <!-- [3] -->
  <p class="red">third</p>  <!-- [3] -->
  <p class="red">fourth</p> <!-- [3] -->
</div>
  1. No se aplican reglas; no se muestra ningún borde.
    Este elemento no tiene la clase red , por lo que se omite.

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

  3. Se aplican ambas reglas; no se muestra ningún 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 declaración de border anula la primera, por lo que la "deshace", por así decirlo.

Como beneficio adicional, aunque se introdujo en Selectors 3, el combinador general de hermanos en realidad está bastante bien soportado por IE7 y más nuevo, a diferencia de :first-of-type y :nth-of-type() que solo son compatibles con IE9 en adelante. . Si necesitas un buen soporte de navegador, estás de suerte.

De hecho, el hecho de que el combinador de hermanos sea el único componente importante en esta técnica, y tiene un soporte de navegador tan sorprendente, hace que esta técnica sea muy versátil: puede adaptarla para filtrar elementos por otras cosas, además de los selectores de clase:

  • Puede usar esto para solucionar el problema :first-of-type en :first-of-type en IE7 e IE8, simplemente suministrando un selector de tipo en lugar de un selector de clase (nuevamente, 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 de anulación con pseudo-elements aunque los pseudo-elementos técnicamente no sean simples selectores.

Tenga en cuenta que para que esto funcione, deberá 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 reglas de anulación en CSS, no se 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 los Selectores 4 introducen una extensión a la notación :nth-child() (originalmente una pseudo-clase 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 . Siendo una propuesta relativamente reciente, todavía no hay suficientes implementaciones interoperables para que pueda ser utilizada en sitios de producción. Esperemos que esto cambie pronto. Mientras tanto, la solución que he sugerido debería funcionar para la mayoría de los casos.

Tenga en cuenta que esta respuesta asume que la pregunta está buscando cada primer elemento secundario que tenga una clase determinada. No existe ni una pseudoclase ni una solución genérica de CSS para la novena coincidencia de un selector complejo en todo el documento : si existe una solución depende en gran medida de la estructura del documento. jQuery proporciona :eq() :first :last y more 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 cualquier 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 (que fue escrita originalmente por Martyn pero eliminada desde entonces), no se comporta de la forma que esperaría.

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

<p class="red"></p>
<div class="red"></div>

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

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

<div class="home">
  <span>blah</span>
  <p class="red">first</p>
  <p class="red">second</p>
  <p class="red">third</p>
  <p class="red">fourth</p>
</div>

La aplicación de una regla con .red:first-of-type funcionará, pero una vez que agregues otra p sin la clase:

<div class="home">
  <span>blah</span>
  <p>dummy</p>
  <p class="red">first</p>
  <p class="red">second</p>
  <p class="red">third</p>
  <p class="red">fourth</p>
</div>

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


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

.red {
  color: green;  
}

/* .red:nth-of-type(1) */
.red:first-of-type {
  color: red;  
}
<div class="home">
  <span>blah</span>
  <p class="red">first</p>
  <p class="red">second</p>
  <p class="red">third</p>
  <p class="red">fourth</p>
</div>


Creo que usar el selector relativo + para seleccionar los elementos ubicados inmediatamente después, funciona mejor aquí (como pocos sugirieron antes).

También es posible para este caso utilizar este selector.

.home p:first-of-type

pero este es el selector de elementos no el de clase uno.

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


Ya que las otras respuestas cubren lo que está mal con él, probaré la otra mitad, cómo solucionarlo. Desafortunadamente, no sé que tenga una solución CSS única aquí, al menos no en la que pueda pensar . Hay algunas otras opciones aunque ...

  1. Asigne una first clase al elemento cuando lo genere, como esto:

    <p class="red first"></p>
    <div class="red"></div>
    

    CSS:

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

    Este CSS solo hace coincidir los elementos con red clases first y red .

  2. Alternativamente, haga lo mismo en JavaScript, por ejemplo, esto es lo que jQuery usaría para hacer esto, utilizando el mismo CSS que el anterior:

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

Las respuestas anteriores son demasiado complejas.

.class:first-of-type { }

Esto seleccionará el primer tipo de clase. Fuente MDN


Pruebe esta solución:

 .home p:first-of-type {
  border:5px solid red;
  width:100%;
  display:block;
}
<div class="home">
  <span>blah</span>
  <p class="red">first</p>
  <p class="red">second</p>
  <p class="red">third</p>
  <p class="red">fourth</p>
</div>

CodePen link


La respuesta correcta es:

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

Parte I: Si el elemento es el primero que su padre y tiene la clase "roja", obtendrá borde.
Parte II: Si el elemento ".red" no es el primero que su padre, pero sigue inmediatamente un elemento sin clase ".red", también merecerá el honor de dicho borde.

Violín o no sucedió.

La respuesta de Philip Daubmeier, aunque aceptada, no es correcta; vea el violín adjunto.
La respuesta de BoltClock funcionaría, pero innecesariamente define y sobrescribe los estilos
(en particular, un problema en el que, de lo contrario, heredaría un borde diferente; no desea declarar otro límite: ninguno)

EDITAR: En el caso de que tenga "rojo" después de no rojo varias veces, cada "primero" rojo obtendrá el borde. Para evitar eso, uno tendría que usar la respuesta de BoltClock. Ver fiddle


El selector " :first-child está destinado, como dice el nombre, a seleccionar el primer elemento secundario de una etiqueta principal. Los hijos deben estar incrustados en la misma etiqueta principal. Tu ejemplo exacto funcionará (solo lo probé here ):

<body>
    <p class="red">first</p>
    <div class="red">second</div>
</body>

¿Tal vez ha anidado sus etiquetas en diferentes etiquetas principales? ¿Son tus etiquetas de clase red realmente las primeras etiquetas 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 que cada vez que se enrolla un nuevo padre, como:

<div>
    <p class="red">first</p>
    <div class="red">second</div>
</div>
<div>
    <p class="red">third</p>
    <div class="red">fourth</div>
</div>

first y third serán rojos luego.

Actualizar:

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

<html>
<head>
<style type="text/css">
.red:nth-of-type(1)
{
    border:5px solid red;
} 
</style>
</head>

<body>
    <div class="home">
        <span>blah</span>
        <p class="red">first</p>
        <p class="red">second</p>
        <p class="red">third</p>
        <p class="red">fourth</p>
    </div>
</body>
</html>

Créditos a Martyn . Más informaciones por ejemplo here . Tenga en cuenta que este es un selector CSS 3, por lo tanto, no todos los navegadores lo reconocerán (por ejemplo, IE8 o más antiguo).


Podría usar nth-of-type (1), pero asegúrese de que el sitio no tenga que ser compatible con IE7, etc. Si este es el caso, use jQuery para agregar una clase de cuerpo, luego busque el elemento a través de la clase de cuerpo de IE7, luego el nombre del elemento y luego en el estilo nth-child para ello.


Puede ser irrelevante, tal vez no, pero hace algún tiempo, creé una función jQuery que hace lo mismo, pero horizontalmente.

Lo llamé "Strippex" para 'banda' + 'texto', demo: http://cdpn.io/FcIBg

No estoy diciendo que esta sea la solución de ningún problema, pero ya intenté aplicar css a la mitad de un personaje, pero horizontalmente, entonces la idea es la misma, la realización puede ser horrible, pero funciona.

Ah, y lo más importante, ¡me divertí mucho al crearlo!







css css-selectors