it-swarm.com.de

CSS-Selektor für erstes Element mit Klasse

Ich habe eine Reihe von Elementen mit einem Klassennamen red, aber ich kann das erste Element mit dem class="red" nicht so aussuchen, dass es die folgende CSS-Regel verwendet:

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

Was ist falsch an dieser Auswahl und wie korrigiere ich sie?

Dank der Kommentare habe ich herausgefunden, dass das Element das erste Kind eines Elternteils sein muss, um ausgewählt zu werden. Dies ist nicht der Fall, den ich habe. Ich habe die folgende Struktur, und diese Regel schlägt fehl, wie in den Kommentaren erwähnt:

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

Wie kann ich das erste Kind mit der Klasse red anvisieren?

773
Rajat

Dies ist eines der bekanntesten Beispiele für Autoren, die die Funktionsweise von :first-child falsch verstehen. Eingeführt in CSS2 , die Pseudoklasse :first-child repräsentiert das allererste Kind seines Elternteils . Das ist es. Es gibt ein weit verbreitetes Missverständnis, dass jedes untergeordnete Element, das als erstes den im Rest des zusammengesetzten Selektors angegebenen Bedingungen entspricht, erfasst wird. Aufgrund der Funktionsweise von Selektoren (siehe hier für eine Erklärung) ist das einfach nicht wahr.

Selectors Level 3 führt eine :first-of-type-Pseudoklasse ein , die das erste Element unter den Geschwistern seines Elementtyps darstellt. Diese Antwort erklärt anhand von Abbildungen den Unterschied zwischen :first-child und :first-of-type. Wie bei :first-child werden jedoch keine anderen Bedingungen oder Attribute berücksichtigt. In HTML wird der Elementtyp durch den Tagnamen dargestellt. In der Frage ist dieser Typ p.

Leider gibt es keine ähnliche :first-of-class-Pseudoklasse für den Abgleich des ersten untergeordneten Elements einer bestimmten Klasse. Eine Möglichkeit, die Lea Vero und ich (wenn auch völlig unabhängig) gefunden haben, besteht darin, zunächst Ihre gewünschten Stile auf alle Elemente mit dieser Klasse anzuwenden :

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

... dann "rückgängig machen" Sie die Stile für Elemente mit der Klasse, die nach dem ersten stehen, indem Sie den allgemeinen Geschwisterkombinator ~ in einer übergeordneten Regel verwenden :

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

Jetzt wird nur das erste Element mit class="red" umrandet.

Hier ist eine Illustration, wie die Regeln angewendet werden:

<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. Es werden keine Regeln angewendet. Es wird kein Rand gerendert.
    Dieses Element hat nicht die Klasse red, daher wird es übersprungen.

  2. Nur die erste Regel wird angewendet; ein roter Rand wird gerendert.
    Dieses Element hat die Klasse red, aber es werden keine Elemente mit der Klasse red im übergeordneten Element vorangestellt. Somit wird nicht die zweite Regel angewendet, sondern nur die erste, und das Element behält seinen Rand bei.

  3. Beide Regeln werden angewendet; Es wird kein Rand gerendert.
    Dieses Element hat die Klasse red. Es wird auch mindestens ein anderes Element mit der Klasse red vorangestellt. Somit werden beide Regeln angewendet, und die zweite border -Deklaration überschreibt die erste, wodurch sie sozusagen "rückgängig gemacht" wird.

Als Bonus wird der allgemeine Geschwisterkombinator, obwohl er in Selectors 3 eingeführt wurde, von IE7 und neueren Versionen ziemlich gut unterstützt, im Gegensatz zu :first-of-type und :nth-of-type(), die erst ab IE9 unterstützt werden. Wenn Sie gute Browserunterstützung benötigen, haben Sie Glück.

Die Tatsache, dass der Geschwisterkombinator die einzige wichtige Komponente in dieser Technik ist, und eine so erstaunliche Browserunterstützung bietet, macht diese Technik sehr vielseitig - Sie können sie zum Filtern anpassen Elemente von anderen Dingen, außer Klassenselektoren:

  • Sie können dies verwenden, um :first-of-type in IE7 und IE8 zu umgehen, indem Sie einfach einen Typenselektor anstelle eines Klassenselektors angeben (mehr zu seiner falschen Verwendung hier in einem späteren Abschnitt):

    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 */
    }
    
  • Sie können nach Attributselektoren oder anderen einfachen Selektoren anstelle von Klassen filtern.

  • Sie können diese übergeordnete Technik auch mit Pseudo-Elementen kombinieren, obwohl Pseudo-Elemente technisch gesehen keine einfachen Selektoren sind.

Beachten Sie, dass Sie die Standardstile für Ihre anderen Geschwisterelemente im Voraus kennen müssen, damit Sie die erste Regel außer Kraft setzen können. Da hierbei Regeln in CSS überschrieben werden, können Sie nicht dasselbe mit einem einzelnen Selektor für die Verwendung mit den CSS-Locators Selectors API oder Selenium erreichen.

Es ist erwähnenswert, dass Selectors 4 eine Erweiterung der :nth-child()-Notation (ursprünglich eine völlig neue Pseudoklasse mit dem Namen :nth-match()) einführt, mit der Sie etwas wie :nth-child(1 of .red) anstelle eines hypothetischen .red:first-of-class verwenden können. Da es sich um ein relativ neues Angebot handelt, gibt es noch nicht genügend interoperable Implementierungen, um es in Produktionsstätten einsetzen zu können. Hoffentlich ändert sich das bald. In der Zwischenzeit sollte die von mir vorgeschlagene Problemumgehung in den meisten Fällen funktionieren.

Beachten Sie, dass diese Antwort davon ausgeht, dass die Frage nach jedem ersten untergeordneten Element sucht, das eine bestimmte Klasse hat. Es gibt weder eine Pseudoklasse noch eine generische CSS-Lösung für die n-te Übereinstimmung eines komplexen Selektors über das gesamte Dokument - ob es eine Lösung gibt, hängt stark von der Dokumentstruktur ab. jQuery bietet zu diesem Zweck :eq(), :first, :last und mehr. Beachten Sie jedoch erneut, dass sie funktionieren sehr unterschiedlich zu :nth-child() et al. . Mit der Selectors-API können Sie entweder document.querySelector() verwenden, um die allererste Übereinstimmung zu erhalten:

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

Oder verwenden Sie document.querySelectorAll() mit einem Indexer, um eine bestimmte Übereinstimmung auszuwählen:

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

Obwohl die .red:nth-of-type(1)-Lösung in der ursprünglich akzeptierten Antwort von Philip Daubmeier funktioniert (die ursprünglich von Martyn geschrieben, aber seitdem gelöscht wurde), verhält sie sich nicht so, wie Sie es erwarten würden zu.

Wenn Sie beispielsweise nur p in Ihrem ursprünglichen Markup auswählen möchten:

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

... dann können Sie .red:first-of-type (entspricht .red:nth-of-type(1)) nicht verwenden, da jedes Element der erste (und einzige) seiner Art ist (p bzw. div), also beide werden vom Selektor abgeglichen.

Wenn das erste Element einer bestimmten Klasse auch das erste Element ihres Typs ist, funktioniert die Pseudoklasse, aber dies geschieht nur zufällig . Dieses Verhalten wird in der Antwort von Philip demonstriert. Sobald Sie ein Element desselben Typs vor diesem Element einfügen, schlägt die Auswahl fehl. Das aktualisierte Markup übernehmen:

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

Das Anwenden einer Regel mit .red:first-of-type funktioniert, aber sobald Sie eine weitere p ohne die Klasse hinzufügen:

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

... der Selektor schlägt sofort fehl, da das erste .red-Element jetzt das zweite p-Element ist.

1317
BoltClock

Der :first-child-Selektor soll, wie der Name sagt, das erste Kind eines übergeordneten Tags auswählen. Die untergeordneten Elemente müssen in dasselbe übergeordnete Tag eingebettet sein. Ihr genaues Beispiel wird funktionieren (habe es einfach versucht hier ):

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

Vielleicht haben Sie Ihre Tags in verschiedenen übergeordneten Tags verschachtelt? Sind Ihre Tags der Klasse red wirklich die ersten Tags unter dem übergeordneten Element?

Beachten Sie auch, dass dies nicht nur auf das erste solche Tag im gesamten Dokument zutrifft, sondern immer, wenn ein neues übergeordnetes Element um dieses Element gewickelt wird, z.

<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 und third sind dann rot.

Update:

Ich weiß nicht, warum Martyn seine Antwort gelöscht hat, aber er hatte die Lösung, den :nth-of-type-Selektor:

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

Kredite an Martyn . Weitere Infos zum Beispiel hier . Beachten Sie, dass es sich hierbei um einen CSS 3-Selektor handelt. Daher wird er nicht von allen Browsern (z. B. IE8 oder älter) erkannt.

309

Die richtige Antwort ist:

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

Teil I: Wenn das Element zuerst zu seinem übergeordneten Element gehört und die Klasse "rot" hat, erhält es einen Rand.
Teil II: Wenn das ".red" -Element nicht vor dem übergeordneten Element steht, sondern unmittelbar auf ein Element ohne die Klasse ".red" folgt, verdient es auch die Ehre der Grenze.

Fiddle oder es ist nicht passiert.

Philip Daubmeiers Antwort ist zwar akzeptiert, aber nicht korrekt - siehe beigefügte Geige.
Die Antwort von BoltClock würde funktionieren, definiert aber unnötig Stile und überschreibt sie
(insbesondere bei einem Problem, bei dem andernfalls eine andere Grenze erben würde - Sie möchten keine andere als Grenze deklarieren: keine)

BEARBEITEN: Falls Sie nach mehrmaligem Nicht-Rot "Rot" haben, erhält jedes "Erste" Rot den Rand. Um dies zu verhindern, müsste man die Antwort von BoltClock verwenden. Siehe Geige

64
SamGoody

sie könnten first-of-type oder nth-of-type(1) verwenden.

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

14
Moes

Um mit Ihrem Selektor übereinzustimmen, muss das Element den Klassennamen red haben und das erste untergeordnete Element des übergeordneten Elements sein.

<div>
    <span class="red"> <!-- MATCH -->
</div>

<div>
    <span>Blah</span>
    <p class="red"> <!-- NO MATCH -->
</div>

<div>
    <span>Blah</span>
    <div><p class="red"></div> <!-- MATCH -->
</div>
9
Chetan Sastry

Da die anderen Antworten das, was falsch damit abdeckt, versuchen, werde ich die andere Hälfte versuchen, wie ich es reparieren kann. Ich weiß leider nicht, dass Sie hier nur eine Lösung mit CSS haben, zumindest nicht die ich mir vorstellen kann. Es gibt jedoch einige andere Optionen ....

  1. Weisen Sie dem Element beim Generieren eine first-Klasse zu:

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

    CSS:

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

    Dieses CSS passt nur zu Elementen mit beidenfirst- und red-Klassen. 

  2. Alternativ können Sie dasselbe in JavaScript tun. Zum Beispiel, was Sie mit jQuery tun würden, indem Sie dasselbe CSS wie oben verwenden:

    $(".red:first").addClass("first");
    
8
Nick Craver

Entsprechend Ihrem aktualisierten Problem

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

wie wäre es mit 

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

Dies wählt class home, dann das Element span und schließlich alle .red-Elemente, die unmittelbar hinter span-Elementen stehen. 

Referenz: http://www.w3schools.com/cssref/css_selectors.asp

5
StinkyCat

Die obigen Antworten sind zu komplex. 

.class:first-of-type { }

Dadurch wird die erste Klasse ausgewählt. MDN-Quelle

4
Gabriel Fair

Ich verwende unterhalb von CSS ein Hintergrundbild für die Liste 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>

3
li bing zhao

Ich habe dieses in meinem Projekt bekommen.

div > .b ~ .b:not(:first-child) {
	background: none;
}
div > .b {
    background: red;
}
<div>
      <p class="a">The first paragraph.</p>
      <p class="a">The second paragraph.</p>
      <p class="b">The third paragraph.</p>
      <p class="b">The fourth paragraph.</p>
  </div>

3
Yener Örer

Sie können nth-of-type (1) verwenden. Stellen Sie jedoch sicher, dass die Site IE7 nicht unterstützen muss. Wenn dies der Fall ist, verwenden Sie jQuery, um body class hinzuzufügen. Suchen Sie dann Element über IE7 body class, dann den Elementnamen und dann add im n-ten Kind dazu.

3
Jamie Paterson

Sie können Ihren Code so ändern, dass er funktioniert

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

Dies erledigt die Arbeit für Sie

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

Hier ist eine CSS-Referenz von SnoopCode darüber.

3
Prabhakar

Versuche dies :

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

Versuchen Sie es einfach und effektiv

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

Aus irgendeinem Grund schien keine der obigen Antworten den Fall von the real first und only first child des Elternteils zu betreffen.

#element_id > .class_name:first-child

Alle obigen Antworten schlagen fehl, wenn Sie den Stil nur auf das Kind der ersten Klasse in diesem Code anwenden möchten.

<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>
1
Yavor Ivanov

Versuchen Sie diese Lösung:

 .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

0
Santosh Khalse

Benötigt nur der erste und nur ein Absatz rot. Wie?

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