J'ai estimé que c'était un bon endroit pour une réponse canonique que la question est générale et tout à fait clair, mais l'original a accepté de répondre n'est pas tout à fait droit. Je vais expliquer pourquoi l'on a accepté la réponse est erronée, dans une section ultérieure, mais d'abord je vais couvrir comment le faire de la bonne façon.
L' :first-child
pseudo-classe, introduit en CSS2, représente le premier enfant de son parent. C'est tout. Il ya une idée fausse très répandue parmi les développeurs web qu'il choisit selon la valeur de l'élément enfant est le premier match dans les conditions prévues par le reste du composé de sélecteur. En raison de la façon dont les sélecteurs de travail (voir ici pour une explication), c'est tout simplement pas vrai.
Les sélecteurs de niveau 3 introduit un :first-of-type
pseudo-classe, qui représente le premier élément entre les frères et sœurs de son type d'élément. Cependant, comme avec d' :first-child
,, il ne ressemble pas à toutes les autres conditions ou les attributs. En HTML, le type d'élément est représenté par le nom de la balise. Dans la question, qui est de type p
.
Malheureusement, il n'est pas similaire :first-of-class
pseudo-classe pour s'aligner sur le premier élément enfant d'une classe donnée. Une solution de contournement que Lea Verou et je suis venu pour cela (quoique de façon totalement indépendante) est d'appliquer des styles à 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 "annuler" les styles pour les éléments avec la classe qui viennent après le premier, en utilisant le grand frère du combinator ~
dans une règle fondamentale:
/*
* 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:
<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>
Aucune règle n'est appliquée; pas de frontière est rendu.
Cet élément n'a pas la classe red
, il est donc ignorée.
Seule la première règle est appliquée; une bordure rouge est rendu.
Cet élément a la classe red
, mais ce n'est pas précédée par des éléments avec la classe red
de son parent. Ainsi, la deuxième règle n'est pas appliquée, seule la première, et l'élément qui garde sa frontière.
Les deux règles sont appliquées; aucune frontière est rendu.
Cet élément a la classe red
. Il est également précédée par au moins un autre élément avec la classe red
. Ainsi, les deux règles sont appliquées, et le second border
déclaration remplace la première, ce qui "défaire", pour ainsi dire.
Comme un bonus, même si elle a été introduite dans les Sélecteurs 3, le grand frère du combinator est en fait assez bien pris en charge par IE7 et plus récentes, contrairement à :first-of-type
et :nth-of-type()
qui ne sont pris en charge par IE9 en avant. Si vous avez besoin d'une bonne prise en charge du navigateur, vous avez de la chance.
En fait, le fait que le frère du combinator est le seul élément important dans cette technique, et il a tellement prise en charge du navigateur, rend cette technique très polyvalent - 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
dans IE7 et IE8, par la simple fourniture d'un sélecteur de type, au lieu d'un sélecteur de classe (de nouveau, de plus en 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électeur d'attribut ou de toute autre simple sélecteurs au lieu de classes.
Vous pouvez également combiner cette surcharge technique avec les pseudo-éléments , même si les pseudo-éléments techniquement ne sont pas simples à des sélecteurs.
Notez que pour que cela fonctionne, vous aurez besoin de savoir à l'avance ce que les styles par défaut pour vos autres éléments frères de sorte que vous pouvez remplacer la première règle. En outre, puisque cela implique la substitution de règles CSS, vous ne pouvez pas réaliser la même chose avec un sélecteur unique pour une utilisation avec l' API de Sélecteurs, ou le Sélénium'CSS locators.
Il est important de mentionner que les Sélecteurs 4 introduit une extension de l' :nth-child()
notation (à l'origine d'un tout nouveau pseudo-classe appelée :nth-match()
), ce qui vous permettra d'utiliser quelque chose comme :nth-child(1 of .red)
au lieu d'une hypothétique .red:first-of-class
. Étant relativement récente proposition, il n'a pas encore été mise en œuvre. J'espère que cela va bientôt changer. En attendant, la solution de contournement que j'ai proposé de travailler pour la plupart des cas.
Gardez à l'esprit que cette réponse suppose que la question est à la recherche pour chaque premier élément enfant qui a une classe donnée. Il n'est ni une pseudo-classe, ni même un générique CSS solution pour la énième match d'un sélecteur complexe dans l'ensemble du document - si il existe une solution dépend fortement de la structure du document. jQuery fournit :eq()
, :first
, :last
et plus pour cette fin, mais notez encore qu' ils fonctionnent très différemment de l' :nth-child()
et coll. À l'aide de l'API de Sélecteurs, vous pouvez utiliser document.querySelector()
pour le premier match:
var first = document.querySelector('.home > .red');
Ou utiliser document.querySelectorAll()
avec un indexeur de choisir n'importe quel match:
var redElements = document.querySelectorAll('.home > .red');
var first = redElements[0];
var second = redeElements[1];
// etc
Bien que l' .red:nth-of-type(1)
solution à l'origine, a accepté de répondre par Philip Daubmeier œuvres (ce qui a été écrit à l'origine par Martyn mais supprimé depuis), il ne se comporte pas de la façon que vous attendez.
Par exemple, si vous ne voulait sélectionnez l' p
dans votre balisage original:
<p class="red"></p>
<div class="red"></div>
Ensuite, vous ne pouvez pas utiliser .red:first-of-type
(équivalent à .red:nth-of-type(1)
), parce que chaque élément est la première (et la seule) de l'un de ses type (p
et div
respectivement), de sorte que les deux seront appariés par le sélecteur.
Lorsque le premier élément d'une certaine classe est aussi le premier de son type, la pseudo-classe travail, mais cela n'arrive que par hasard. Ce comportement est illustré dans de Philip de réponse. Le moment où vous vous en tenez à un élément du même type avant de cet élément, le sélecteur va échouer. Prendre la mise à jour de balisage:
<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>
L'application de la règle avec l' .red:first-of-type
de travail, mais une fois que vous ajoutez un autre p
sans la classe:
<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>
Le sélecteur immédiatement échouer, parce que le premier .red
élément est désormais le deuxième p
élément.