Sélecteur CSS pour le premier élément avec la classe

J’ai un tas d’éléments avec un nom de classe red , mais je n’arrive pas à sélectionner le premier élément avec le class="red" utilisant la règle CSS suivante:

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

Qu’est-ce qui ne va pas dans ce sélecteur et comment le corriger?

Grâce aux commentaires, j’ai compris que l’élément devait être le premier enfant de son parent à être sélectionné, ce qui n’est pas le cas. J’ai la structure suivante, et cette règle échoue comme mentionné dans les commentaires:

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

first

second

third

fourth

Comment puis-je cibler le premier enfant avec la classe red ?

Il s’agit de l’un des exemples les plus connus d’incompréhension de la part des auteurs :first-child comment fonctionne le :first-child . Introduite dans CSS2 , la pseudo-classe :first-child représente le tout premier enfant de son parent . C’est tout. Il existe une idée fausse très répandue selon laquelle l’élément enfant est le premier à correspondre aux conditions spécifiées par le sélecteur composé. En raison de la façon dont les sélecteurs fonctionnent (voir ici pour une explication), ce n’est tout simplement pas vrai.

Le niveau 3 des sélecteurs introduit une pseudo-classe de :first-of-type , qui représente le premier élément parmi les frères et sœurs de son type d’élément. Cette réponse explique, avec des illustrations, la différence entre :first-child et :first-of-type . Cependant, comme avec :first-child , il ne regarde aucune autre condition ou atsortingbut. En HTML, le type d’élément est représenté par le nom de la balise. Dans la question, ce type est p .

Malheureusement, il n’y a pas de similitude :first-of-class pseudo-classe de première classe pour faire correspondre le premier élément enfant d’une classe donnée. Une solution de contournement que Lea Verou et moi-même avons imaginée pour cela (bien qu’indépendamment) est d’appliquer d’abord les styles souhaités à tous vos éléments avec cette classe:

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

… puis “défaire” les styles pour les éléments avec la classe qui vient après le premier , en utilisant le combinateur général de frasortinge ~ dans une règle de substitution:

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

Maintenant, seul le premier élément avec class="red" aura une bordure.

Voici une illustration de la façon dont les règles sont appliquées:

 
blah

first

second

third

fourth

  1. Aucune règle n’est appliquée; aucune bordure n’est rendue.
    Cet élément n’a pas la classe red , donc il est ignoré.

  2. Seule la première règle est appliquée; une bordure rouge est rendue.
    Cet élément a la classe red , mais il n’est précédé d’aucun élément avec la classe red dans son parent. Ainsi, la deuxième règle n’est pas appliquée, seule la première et l’élément conserve sa frontière.

  3. Les deux règles sont appliquées; aucune bordure n’est rendue.
    Cet élément a la classe red . Il est également précédé d’au moins un autre élément avec la classe red . Ainsi, les deux règles sont appliquées et la deuxième déclaration de border remplace la première, annulant ainsi la

En bonus, bien qu’il ait été introduit dans Selectors 3, le combinateur frère / sœur est en fait assez bien pris en charge par IE7 et les versions plus récentes, contrairement à :first-of-type et :nth-of-type() . Si vous avez besoin d’un bon support de navigateur, vous avez de la chance.

En fait, le fait que le combinateur frère est le seul composant important de cette technique, et qu’il supporte un navigateur aussi puissant, rend cette technique très polyvalente – vous pouvez l’adapter à d’autres éléments, en plus des sélecteurs de classes:

  • Vous pouvez l’utiliser pour contourner :first-of-type dans IE7 et IE8, en fournissant simplement un sélecteur de type au lieu d’un sélecteur de classe (encore une fois, plus sur son utilisation incorrecte ici dans une section ultérieure):

     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 */ } 
  • Vous pouvez filtrer par sélecteurs d’atsortingbuts ou tout autre sélecteur simple au lieu de classes.

  • Vous pouvez également combiner cette technique de substitution avec des pseudo-éléments même si les pseudo-éléments ne sont techniquement pas de simples sélecteurs.

Notez que pour que cela fonctionne, vous devez savoir à l’avance quels seront les styles par défaut pour vos autres éléments frères afin de pouvoir remplacer la première règle. De plus, étant donné que cela implique la substitution de règles dans CSS, vous ne pouvez pas obtenir la même chose avec un seul sélecteur à utiliser avec l’ API Selectors ou les localisateurs CSS de Selenium .

Il convient de mentionner que Selectors 4 introduit une extension de la notation :nth-child() (à l’origine une toute nouvelle pseudo-classe appelée :nth-match() ), qui vous permettra d’utiliser quelque chose comme :nth-child(1 of .red) au lieu d’une hypothétique .red:first-of-class . En tant que proposition relativement récente, il n’existe pas suffisamment d’interfonctionnements interopérables pour pouvoir être utilisé sur les sites de production. J’espère que cela changera bientôt. En attendant, la solution de contournement que j’ai proposée devrait fonctionner dans la plupart des cas.

Gardez à l’esprit que cette réponse suppose que la question est de rechercher chaque premier élément enfant ayant une classe donnée. Il n’y a pas de pseudo-classe, ni même de solution CSS générique pour la nième correspondance d’un sélecteur complexe sur l’ensemble du document – le fait qu’une solution existe dépend fortement de la structure du document. jQuery fournit :eq() :first :last et more à cette fin, mais notez à nouveau qu’ils fonctionnent très différemment de :nth-child() et al . En utilisant l’API Selectors, vous pouvez utiliser document.querySelector() pour obtenir la toute première correspondance:

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

Ou utilisez document.querySelectorAll() avec un indexeur pour sélectionner une correspondance spécifique:

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

Bien que la .red:nth-of-type(1) dans la réponse acceptée par Philip Daubmeier (qui a été écrite par Martyn mais supprimée depuis), ne se comporte pas comme vous le souhaitiez.

Par exemple, si vous souhaitez uniquement sélectionner le p dans votre balisage d’origine:

 

… alors vous ne pouvez pas utiliser .red:first-of-type (équivalent à .red:nth-of-type(1) ), car chaque élément est le premier (et le seul) de son type ( p et div respectivement), les deux seront appariés par le sélecteur.

Lorsque le premier élément d’une certaine classe est également le premier de son type , la pseudo-classe fonctionnera, mais cela ne se produit que par coïncidence . Ce comportement est démontré dans la réponse de Philip. Au moment où vous insérez un élément du même type avant cet élément, le sélecteur échouera. Prendre le balisage mis à jour:

 
blah

first

second

third

fourth

Appliquer une règle avec .red:first-of-type fonctionnera, mais une fois que vous aurez ajouté un autre p sans la classe:

 
blah

dummy

first

second

third

fourth

… le sélecteur échouera immédiatement, car le premier élément .red est maintenant le deuxième élément p .

Le sélecteur :first-child est destiné, comme le nom l’indique, à sélectionner le premier enfant d’une balise parent. Les enfants doivent être intégrés dans la même balise parent. Votre exemple exact fonctionnera (Il suffit de l’essayer ici ):

  

first

second

Vous avez peut-être nested vos tags dans différentes balises parent? Vos balises de classe red vraiment les premières balises sous le parent?

Notez également que cela ne s’applique pas uniquement à la première balise de ce type dans le document, mais à chaque fois qu’un nouveau parent l’enveloppe, comme:

 

first

second

third

fourth

first et le third seront rouges alors.

Mettre à jour:

Je ne sais pas pourquoi martyn a supprimé sa réponse, mais il avait la solution, le sélecteur: :nth-of-type :

      
blah

first

second

third

fourth

Crédits à Martyn . Plus d’infos par exemple ici . Sachez qu’il s’agit d’un sélecteur CSS 3, tous les navigateurs ne le reconnaîtront donc pas (par exemple IE8 ou plus ancien).

La bonne réponse est:

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

Partie I: Si l’élément est le premier à son parent et a la classe “rouge”, il doit avoir une frontière.
Partie II: Si l’élément “.red” n’est pas le premier à son parent, mais suit immédiatement un élément sans classe “.red”, il doit également mériter l’honneur de ladite bordure.

Le violon ou ça n’est pas arrivé.

La réponse de Philip Daubmeier, bien qu’acceptée, n’est pas correcte – voir le violon ci-joint.
La réponse de BoltClock fonctionnerait, mais définirait et écraserait inutilement les styles
(particulièrement un problème où il hériterait autrement d’une bordure différente – vous ne voulez pas déclarer d’autre frontière: none)

EDIT: Dans le cas où “rouge” suit plusieurs fois non-rouge, chaque “premier” rouge aura la bordure. Pour éviter cela, il faudrait utiliser la réponse de BoltClock. Voir le violon

vous pouvez utiliser first-of-type ou nth-of-type(1)

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

first

second

third

fourth

Pour correspondre à votre sélecteur, l’élément doit avoir un nom de classe red et doit être le premier enfant de son parent.

 
Blah

Blah

Comme les autres réponses couvrent ce qui ne va pas, je vais essayer de résoudre le problème. Malheureusement, je ne sais pas si vous avez une solution CSS uniquement ici, du moins pas ce que je peux penser . Il y a cependant d’autres options ….

  1. Atsortingbuez une first classe à l’élément lorsque vous le générez, comme ceci:

     

    CSS:

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

    Ce CSS ne correspond qu’à des éléments avec les deux classes red et first .

  2. Vous pouvez également faire la même chose en JavaScript, par exemple, voici ce que jQuery vous permet de faire, en utilisant le même CSS que ci-dessus:

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

Selon votre problème mis à jour

 
blah

first

second

third

fourth

que diriez-vous

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

Cela sélectionnera la classe d’accueil , puis la durée de l’élément et enfin tous les éléments .red placés immédiatement après les éléments span.

Référence: http://www.w3schools.com/cssref/css_selectors.asp

Vous pouvez changer votre code pour quelque chose comme ça pour le faire fonctionner

 
blah

first

second

third

fourth

Cela fait le travail pour vous

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

Voici une référence CSS de SnoopCode à ce sujet.

J’utilise ci-dessous CSS pour avoir une image de fond pour la liste ul li

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

Vous pouvez utiliser nth-of-type (1) mais assurez-vous que le site n’a pas besoin de prendre en charge IE7, si c’est le cas, utilisez jQuery pour append la classe body, puis trouvez l’élément via IE7, puis ajoutez le nom de l’élément. dans le style de nth-enfant à elle.

Essaye ça :

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

Je l’ai eu dans mon projet.

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

The first paragraph.

The second paragraph.

The third paragraph.

The fourth paragraph.

Pour une raison quelconque, aucune des réponses ci-dessus ne semblait concerner le cas du premier et unique premier enfant du parent.

 #element_id > .class_name:first-child 

Toutes les réponses ci-dessus échoueront si vous souhaitez appliquer le style uniquement à l’enfant de première classe de ce code.

  

Essayez ceci simple et efficace

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

Essayez cette solution:

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

first

second

third

fourth

Les réponses ci-dessus sont trop complexes.

 .class:first-of-type { } 

Ceci sélectionnera le premier type de classe. Source MDN

Nécessaire seulement en premier et un seul paragraphe fait en rouge. Comment?

  

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

The first paragraph.

The second paragraph.

The third paragraph.

The fourth paragraph.

Je crois que l’utilisation du sélecteur relatif + pour sélectionner les éléments placés immédiatement après, fonctionne ici le mieux (comme peu suggéré auparavant).

Il est également possible pour ce cas d’utiliser ce sélecteur

 .home p:first-of-type 

mais c’est le sélecteur d’élément pas la classe.

Ici vous avez une belle liste de sélecteurs CSS: https://kolosek.com/css-selectors/