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 la class="red"
règle CSS suivante:
.red:first-child {
border: 5px solid red;
}
<p class="red"></p>
<div class="red"></div>
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 pour moi. J'ai la structure suivante, et cette règle échoue comme mentionné dans les commentaires:
.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>
Comment puis-je cibler le premier enfant avec la classe red
?
css
css-selectors
Rajat
la source
la source
:first-of-type
ça marche.Réponses:
Il s'agit de l'un des exemples les plus connus d'auteurs mal compris le
:first-child
fonctionnement.Introduite en CSS2 , la:first-child
pseudo-classe représente le tout premier enfant de son parent . C'est ça. Il y a une idée fausse très répandue selon laquelle il ramasse l'élément enfant qui est le premier à correspondre aux conditions spécifiées par le reste du sélecteur composé. En raison du fonctionnement des sélecteurs (voir ici pour une explication), ce n'est tout simplement pas vrai.Les sélecteurs de niveau 3 introduisent une
:first-of-type
pseudo-classe , 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 attribut. En HTML, le type d'élément est représenté par le nom de la balise. Dans la question, ce type estp
.Malheureusement, il n'y a pas de
:first-of-class
pseudo-classe similaire pour faire correspondre le premier élément enfant d'une classe donnée. Une solution de contournement Lea Verou et moi avons trouvée pour cela (bien que de manière totalement indépendante) consiste à appliquer d'abord les styles souhaités à tous vos éléments avec cette classe:... puis "annuler" les styles des éléments avec la classe qui vient après le premier , en utilisant le combinateur frère général
~
dans une règle prioritaire: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:
Aucune règle n'est appliquée; aucune bordure n'est rendue.
Cet élément n'a pas de classe
red
, il est donc ignoré.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 classered
dans son parent. Ainsi la deuxième règle n'est pas appliquée, seulement la première, et l'élément garde sa frontière.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 de la classered
. Ainsi, les deux règles sont appliquées et la deuxièmeborder
déclaration l'emporte sur la première, la "défaisant" pour ainsi dire.En prime, bien qu'il ait été introduit dans Selectors 3, le combinateur général de frères et sœurs est en fait assez bien pris en charge par IE7 et plus récent, contrairement à
:first-of-type
et:nth-of-type()
qui ne sont pris en charge que par IE9. Si vous avez besoin d'une bonne prise en charge du navigateur, vous avez de la chance.En fait, le fait que le combinateur frère soit le seul composant important dans cette technique, et qu'il ait une telle prise en charge du navigateur, rend cette technique très polyvalente - vous pouvez l'adapter pour filtrer les éléments par d'autres choses, en plus des sélecteurs de classe:
Vous pouvez l'utiliser pour contourner
:first-of-type
IE7 et IE8, en fournissant simplement un sélecteur de type au lieu d'un sélecteur de classe (encore une fois, plus d'informations sur son utilisation incorrecte ici dans une section ultérieure):Vous pouvez filtrer par sélecteurs d'attributs ou tout autre sélecteur simple au lieu de classes.
Vous pouvez également combiner cette technique prioritaire 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 devrez 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, comme cela implique de remplacer les règles en 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
:nth-child()
notation (à l'origine une pseudo-classe entièrement nouvelle 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
. Étant une proposition relativement récente, il n'y a pas encore suffisamment d'implémentations interopérables pour qu'elle soit utilisable sur les sites de production. Espérons que cela changera bientôt. En attendant, la solution de contournement que j'ai suggérée devrait fonctionner pour la plupart des cas.Gardez à l'esprit que cette réponse suppose que la question recherche chaque premier élément enfant ayant une classe donnée. Il n'y a ni pseudo-classe ni même une solution CSS générique pour la nième correspondance d'un sélecteur complexe à travers le document entier - si une solution existe dépend fortement de la structure du document. jQuery fournit
:eq()
,:first
,:last
et plus à cet effet, mais notez encore que ils fonctionnent très différemment:nth-child()
et al . En utilisant l'API Selectors, vous pouvez soit utiliserdocument.querySelector()
pour obtenir la toute première correspondance:Ou utilisez
document.querySelectorAll()
avec un indexeur pour choisir une correspondance spécifique:Bien que la
.red:nth-of-type(1)
solution dans la réponse initialement acceptée par les travaux de Philip Daubmeier (qui a été Martyn mais supprimée depuis), elle ne se comporte pas comme vous vous y attendriez.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
etdiv
respectivement), donc deux seront mis en correspondance 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 collerez un élément du même type avant cet élément, le sélecteur échouera. Prendre le balisage mis à jour:
L'application d'une règle avec
.red:first-of-type
fonctionnera, mais une fois que vous en aurez ajouté une autrep
sans la classe:... le sélecteur échouera immédiatement, car le premier
.red
élément est maintenant le deuxièmep
élément.la source
:last-of-class
? Sélectionnez le dernier élément d'une classe.general sibling selector ~
fonctionne comme un:not(:first-of-*)
pour un type spécifique, je suppose qu'il devrait appliquer la règle à chaque élément correspondant, mais il n'est appliqué que pour la première correspondance, même s'il y a 3 correspondances possibles ou plus.:nth-child(1 of .foo)
extension a déjà été implémentée sur Safari 9.1+. (Je n'ai pas vérifié cependant)Le
:first-child
sélecteur est destiné, comme son 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 (venez de l'essayer ici ):Peut-être que vous avez imbriqué vos tags dans différents tags parents? Vos balises de classe sont-elles
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 tout le document, mais à chaque fois qu'un nouveau parent est enroulé autour de lui, comme:
first
etthird
sera alors rouge.Mise à jour:
Je ne sais pas pourquoi martyn a supprimé sa réponse, mais il avait la solution, le
:nth-of-type
sélecteur:Crédits à Martyn . Plus d'infos par exemple ici . Sachez qu'il s'agit d'un sélecteur CSS 3, donc tous les navigateurs ne le reconnaîtront pas (par exemple IE8 ou plus ancien).
la source
:nth-of-type
souffre du léger problème de ne pas fonctionner du tout dans une version actuelle d'IE..red:nth-of-type(1)
sélectionnera tout élément qui (a) est le premier enfant de son type d'élément, et (b) a la classe "rouge". Donc, si dans l'exemple, le premier <p> n'avait pas la classe "rouge", il ne serait pas sélectionné. Alternativement, si le <span> et le premier <p> avaient tous les deux la classe "rouge", ils seraient tous les deux sélectionnés. jsfiddle.net/fvAxn:first-of-type
est équivalent à:nth-of-type(1)
, donc bien sûr cela fonctionne aussi. Il peut également échouer de la même manière pour la même raison que celle indiquée dans ma réponse.:nth-of-type
signifie "élément / tag" quand il dit "type". Il ne prend donc en compte que l'élément, pas les choses comme les classes.La bonne réponse est:
Partie I: Si l'élément est le premier à son parent et a la classe "rouge", il doit avoir une bordure.
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 mérite également l'honneur de ladite bordure.
Violon ou ça n'est pas arrivé.
La réponse de Philip Daubmeier, bien qu'acceptée, n'est pas correcte - voir violon ci-joint.
La réponse de BoltClock fonctionnerait, mais définit et écrase inutilement les styles
(en particulier un problème où il hériterait autrement d'une bordure différente - vous ne voulez pas en déclarer d'autre à border: aucun)
EDIT: Dans le cas où vous avez "rouge" suivant plusieurs fois non rouge, chaque "premier" rouge obtiendra la bordure. Pour éviter cela, il faudrait utiliser la réponse de BoltClock. Voir violon
la source
.red
suit un:not(.red)
ne fait pas toujours le premier.red
parmi ses frères et sœurs. Et si la frontière doit être héritée, il s'agit simplement de déclarerborder: inherit
plutôt queborder: none
dans la règle de remplacement.first-child
àlast-child
, mais je vois après avoir testé que cela ne fait pas toujours l'affaire.vous pourriez utiliser
first-of-type
ounth-of-type(1)
la source
<p></p>
entre lespan
et votre premierp
élément avec lared
classe. Regardez ce JSFiddle .Les réponses ci-dessus sont trop complexes.
Cela sélectionnera le premier type de classe. Source MDN
la source
first-type
a été renomméfirst-of-type
<span>
, et quelques-uns ont la classehighlight
. Le.highlight:first-of-type
sélecteur sélectionnera la première instance du "type" avec la classe sélectionnée, dans cet exemple la première<span>
, et non la première instance de la classehighlight
. Ce n'est que si cette première instance de span a également le surlignage de classe que le style sera implémenté. ( codepen.io/andrewRmillar/pen/poJKJdJ )Pour correspondre à votre sélecteur, l'élément doit avoir un nom de classe
red
et doit être le premier enfant de son parent.la source
Étant donné que les autres réponses couvrent ce qui ne va pas, je vais essayer l'autre moitié, comment y remédier. Malheureusement, je ne sais pas si vous avez une seule solution CSS ici, du moins pas à laquelle je peux penser . Il existe cependant d'autres options ...
Attribuez une
first
classe à l'élément lorsque vous le générez, comme ceci:CSS:
Ce CSS ne fait correspondre les éléments qu'aux deux
first
et auxred
classes.Alternativement, faites la même chose en JavaScript, par exemple, voici ce que jQuery vous utiliseriez pour cela, en utilisant le même CSS que ci-dessus:
la source
:first-of-class
, je suggère également d'ajouter une classe supplémentaire au premier élément. Semble la solution la plus simple pour l'instant.J'ai eu celui-ci dans mon projet.
la source
Selon votre problème mis à jour
que diriez-vous
Cela sélectionnera la classe home , puis la durée de l'élément et enfin tous les éléments .red qui sont placés immédiatement après les éléments de la portée.
Référence: http://www.w3schools.com/cssref/css_selectors.asp
la source
Vous pouvez utiliser nth-of-type (1) mais assurez-vous que le site n'a pas besoin de prendre en charge IE7, etc., si tel est le cas, utilisez jQuery pour ajouter la classe de corps, puis recherchez l'élément via la classe de corps IE7, puis le nom de l'élément, puis ajoutez dans le style nième enfant.
la source
Vous pouvez changer votre code en quelque chose comme ça pour le faire fonctionner
Cela fait le travail pour vous
Voici une référence CSS de SnoopCode à ce sujet.
la source
J'utilise ci-dessous CSS pour avoir une image de fond pour la liste ul li
la source
Essaye ça :
la source
Pour une raison quelconque, aucune des réponses ci-dessus ne semble aborder le cas du véritable premier et seul premier enfant du parent.
Toutes les réponses ci-dessus échoueront si vous souhaitez appliquer le style uniquement à l'enfant de première classe dans ce code.
la source
:first-child
pseudo-classe est trompeuse car elle ajoute.class_name
avant de ne pas changer la façon dont elle fonctionne et la fait simplement agir comme un filtre. Si vous avez déjà un div,<div class="class_name">First content that need to be styled</div>
votre sélecteur ne correspondra pas, car ce n'est pas le premier enfant.Essayez ceci simple et efficace
la source
Je crois que l'utilisation du sélecteur relatif
+
pour sélectionner les éléments placés immédiatement après fonctionne le mieux ici (comme peu l'ont suggéré auparavant).Il est également possible pour ce cas d'utiliser ce sélecteur
mais ce n'est pas le sélecteur d'élément.
Ici, vous avez une belle liste de sélecteurs CSS: https://kolosek.com/css-selectors/
la source
Essayez cette solution:
Lien CodePen
la source