1176 votes

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

J'ai un tas d'éléments avec un nom de classe red:

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

Je n'arrive pas à sélectionner le premier élément avec l' class="red" à l'aide de la règle CSS suivante:

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

Ce qui est mauvais dans ce sélecteur et comment puis-je la corriger?

Mise à JOUR:

Merci pour les commentaires, j'ai compris que l'élément est le premier enfant de son parent d'être sélectionné, ce qui n'est pas le cas que j'ai. - Je avoir la structure suivante:

<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>

et cette règle échoue comme mentionné dans les commentaires:

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

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

1714voto

BoltClock Points 249668

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>
  1. 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.

  2. 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.

  3. 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.

371voto

Philip Daubmeier Points 6559

L' :first-child sélecteur est destiné, comme son nom l'indique, pour sélectionner le premier enfant d'un parent de la balise. Les enfants doivent être embarqués dans la même balise parent. Votre exemple de travail (Juste essayé ici):

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

Vous avez peut-être imbriquées vos mots-clés dans les différents parent tags? Vos étiquettes de la classe red le premier des balises sous la mère?

Notez également que ce ne pas seulement s'appliquer à la première balise dans l'ensemble du document, mais à chaque fois un nouveau parent est enroulé autour d'elle, comme:

<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 et third sera rouge ensuite.

Mise à jour:

Je ne sais pas pourquoi martyn supprimé de sa réponse, mais il avait la solution, l' :nth-of-type selector:

<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>

Les crédits de Martyn. Plus d'infos par exemple ici. Sachez que c'est un sélecteur CSS 3, donc pas tous les navigateurs le reconnaître (par exemple, IE8 ou plus).

90voto

SamGoody Points 4406

La réponse correcte est:

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

Partie I: Si l'élément est d'abord à ses parents et a de la classe "rouge", il doit obtenir de la frontière.
Partie II: Si ".rouge" de l'élément n'est pas d'abord à ses parents, mais est immédiatement à la suite d'un élément sans classe ".rouge", il est aussi méritent l'honneur de ladite frontière.

Violon ou il n'est pas arrivé.

Philip Daubmeier de réponse, tout accepté, n'est pas correcte - voir ci-joint le violon.
BoltClock réponse, mais inutilement définit et écrase les styles
(en particulier d'un problème où elle aurait par ailleurs hériter d'une autre de la frontière, vous ne voulez pas de déclarer d'autres de la frontière:aucun)

EDIT: Dans le cas où vous avez "rouge" à la suite de la non-rouge à plusieurs reprises, chaque "première" rouge obtiendrez la frontière. Pour éviter cela, on aurait besoin d'utiliser BoltClock de réponse. Voir tripoter

10voto

Chetan Sastry Points 14742

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

10voto

Nick Craver Points 313913

Étant donné que les autres réponses couvrir ce qui est mauvais avec elle, je vais essayer l'autre moitié, comment résoudre le problème. Malheureusement, je ne sais pas que vous avez un CSS seule solution ici, au moins, pas ce que je peux penser. Il ya quelques autres options....

  1. Attribuer un first classe de l'élément lorsque vous générez, comme ceci:

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

    CSS:

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

    Cette CSS correspond à des éléments avec les deux first et red les classes.

  2. Sinon, faire la même chose en JavaScript, par exemple voici ce que jQuery vous utilisez pour ce faire, en utilisant le même CSS que ci-dessus:

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

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X