Selektor CSS dla pierwszego elementu z klasą

Mam kilka elementów o nazwie klasy red, ale nie mogę wybrać pierwszego elementu z class="red" używając następującej reguły CSS:

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

Co jest nie tak w tym selektorze i jak to poprawić?

Dzięki komentarzom zorientowałem się, że element musi być pierwszym dzieckiem swojego rodzica, które zostanie wybrane, co nie jest przypadkiem, że mam. Mam następującą strukturę, a zasada ta zawodzi, jak wspomniano w komentarze:

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

Jak mogę namierzyć pierwsze dziecko z klasą red?

Author: TylerH, 2010-04-27

18 answers

Jest to jeden z najbardziej znanych przykładów, w jaki sposób autorzy nie rozumieją, jak działa[9]. wprowadzona w CSS2 , pseudoklasa :first-child reprezentuje pierwsze dziecko swojego rodzica . To wszystko. Istnieje bardzo powszechne błędne przekonanie, że pobiera on element potomny, który jako pierwszy spełnia warunki określone przez resztę selektora złożonego. Ze względu na sposób działania selektorów (zobacz tutaj , aby uzyskać wyjaśnienie), nie jest to po prostu prawda.

Selektory na poziomie 3 wprowadzają pseudoklasę :first-of-type , która reprezentuje pierwszy element wśród rodzeństwa swojego typu elementu. ta odpowiedź wyjaśnia, za pomocą ilustracji, różnicę między :first-child A :first-of-type. Jednakże, podobnie jak w przypadku :first-child, nie uwzględnia on żadnych innych warunków ani atrybutów. W HTML Typ elementu jest reprezentowany przez nazwę znacznika. W pytaniu tym typem jest p.

Niestety, nie ma podobnej :first-of-class pseudo-klasy dla dopasowanie pierwszego elementu potomnego danej klasy. Jednym obejściem, które Lea Verou i wymyśliłem dla tego (choć całkowicie niezależnie), jest najpierw zastosowanie pożądanych stylów do wszystkich {66]} Twoich elementów z tą klasą: {]}

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

... następnie "cofnij" style dla elementów z klasą, która pojawia się po pierwszej, używając ogólnego kombinatora rodzeństwa~ w nadrzędnej zasadzie:

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

Teraz tylko pierwszy element z class="red" będzie miała granicę.

Oto ilustracja, w jaki sposób zasady są stosowane:]}
<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. Nie stosuje się reguł, nie renderuje się obramowania.
    Ten element nie ma klasy red, więc jest pomijany.

  2. Stosowana jest tylko pierwsza reguła; renderowana jest czerwona obramowanie.
    Ten element ma klasę red, ale nie jest poprzedzony żadnymi elementami z klasą red w swoim rodzicu. Tak więc druga reguła nie jest stosowana, tylko pierwszy, a element zachowuje swoją granicę.

  3. Obie reguły są stosowane; nie jest renderowana obramowanie.
    Ten element ma klasę red. Jest również poprzedzony przez co najmniej jeden inny element z klasą red. W ten sposób obie reguły są stosowane, a druga border deklaracja Zastępuje pierwszą, tym samym "cofając" ją, że tak powiem.

[[48]} jako bonus, chociaż został wprowadzony w Selectors 3, ogólny kombinator rodzeństwa jest naprawdę ładny dobrze obsługiwane przez IE7 i nowsze, w przeciwieństwie do :first-of-type i :nth-of-type(), które są obsługiwane tylko przez IE9. Jeśli potrzebujesz dobrej obsługi przeglądarki, masz szczęście.

W rzeczywistości fakt, że kombinator rodzeństwa jest jedynym ważnym komponentem w tej technice, i {66]} ma tak niesamowitą obsługę przeglądarki, sprawia, że technika ta jest bardzo wszechstronna - można ją dostosować do filtrowania elementów przez inne rzeczy, poza selektorami klas:{[55]]}

  • Możesz użyć tego do obejścia :first-of-type w IE7 i IE8, po prostu dostarczając selektor typów zamiast selektora klas (ponownie, więcej o jego nieprawidłowym użyciu tutaj w późniejszej sekcji): {]}

    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 */
    }
    
  • Możesz filtrować za pomocą selektorów atrybutów lub innych prostych selektorów zamiast klas.

  • Można również połączyć tę nadrzędną technikę z pseudoelementami , nawet jeśli pseudoelementy technicznie nie są prostymi selektorami.

Zauważ, że aby to aby działać, musisz wcześniej wiedzieć, jakie będą domyślne style dla innych elementów rodzeństwa, aby można było zastąpić pierwszą regułę. Dodatkowo, ponieważ wiąże się to z nadrzędnymi regułami w CSS, nie można osiągnąć tego samego za pomocą pojedynczego selektora używanego z API selektorów lub lokalizatorami CSS Selenium.

Warto wspomnieć, że Selectors 4 wprowadza rozszerzenie do notacji :nth-child() (pierwotnie zupełnie nową pseudo-klasę nazwane :nth-match()), co pozwoli na użycie czegoś podobnego :nth-child(1 of .red) zamiast hipotetycznego .red:first-of-class. Jako stosunkowo niedawna propozycja, nie ma jeszcze wystarczającej liczby interoperacyjnych wdrożeń, aby mogła być używana w zakładach produkcyjnych. Mam nadzieję, że to się wkrótce zmieni. Tymczasem obejście, które zaproponowałem, powinno zadziałać w większości przypadków.

Należy pamiętać, że ta odpowiedź zakłada, że pytanie szuka każdego pierwszego elementu potomnego, który ma daną klasę. Nie ma ani pseudo-Klasa ani nawet ogólne rozwiązanie CSS dla n-tego dopasowania złożonego selektora w całym dokumencie - to, czy rozwiązanie istnieje, zależy w dużej mierze od struktury dokumentu. jQuery zapewnia :eq(), :first, :last i więcej w tym celu, ale zauważ jeszcze raz, że funkcjonują bardzo inaczej niż :nth-child() et al . Przy użyciu API selektorów można użyć document.querySelector(), aby uzyskać pierwsze dopasowanie:

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

Lub użyj document.querySelectorAll() Z indeksatorem, aby wybrać dowolny konkretny dopasowanie:

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

Chociaż rozwiązanie .red:nth-of-type(1) w oryginalnej odpowiedzi zaakceptowanej przezPhilipa Daubmeiera Działa (pierwotnie napisane przez {147]}Martyna {50]}, ale usunięte od tego czasu), nie zachowuje się tak, jak byś tego oczekiwał.

Na przykład, jeśli chcesz tylko wybrać p w oryginalnym znaczniku:

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

... wtedy nie można użyć .red:first-of-type (odpowiednik .red:nth-of-type(1)), ponieważ każdy element jest pierwszym (i jedynym) elementem swojego typu (p i divodpowiednio), więc oba będą dopasowane przez selektor.

Gdy pierwszy element pewnej klasyjest również pierwszym tego typu , pseudoklasa będzie działać, ale dzieje się to tylko przez przypadek. Zachowanie to zostało wykazane w odpowiedzi Filipa. W momencie przyklejenia elementu tego samego typu przed tym elementem selektor się nie powiedzie. Pobieranie zaktualizowanych znaczników:

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

Zastosowanie reguły z {[40] } zadziała, ale gdy dodaj kolejny p Bez klasy:

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

... selektor natychmiast się nie powiedzie, ponieważ pierwszy .red element jest teraz drugi p element.

 1181
Author: BoltClock,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-06-29 10:56:18

Selektor :first-child jest przeznaczony, jak sama nazwa wskazuje, do wybrania pierwszego potomka znacznika nadrzędnego. Dzieci muszą być osadzone w tym samym znaczniku nadrzędnym. Twój dokładny przykład zadziała (po prostu próbowałem tutaj):

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

Może masz zagnieżdżone swoje tagi w różnych znaczników nadrzędnych? Czy Twoje tagi klasy red naprawdę są pierwszymi tagami pod rodzicem?

Zauważ również, że nie dotyczy to tylko pierwszego takiego znacznika w całym dokumencie, ale za każdym razem, gdy nowy rodzic jest owinięte wokół niego, jak:

<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 i third będzie wtedy czerwony.

Update:

Nie wiem dlaczego martyn usunął swoją odpowiedź, ale miał rozwiązanie, selektor :nth-of-type:

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

Napisy do Martyna. Więcej informacji na przykład tutaj . Należy pamiętać, że jest to selektor CSS 3, dlatego nie wszystkie przeglądarki go rozpoznają(np.

 305
Author: Philip Daubmeier,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:34:54

Prawidłowa odpowiedź brzmi:

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

Część I: jeśli element jest pierwszy do swojego rodzica i ma klasę "red", otrzymuje border.
Część II: Jeśli ".czerwony "element nie jest pierwszy do swojego rodzica, ale bezpośrednio po elemencie bez klasy".czerwony", zasługuje również na honor wspomnianej granicy.

Skrzypek albo nie.

Odpowiedź Philipa Daubmeiera, choć zaakceptowana, nie jest poprawna-patrz załączone fiddle.
Odpowiedź BoltClock będzie działać, ale niepotrzebnie definiuje i nadpisuje Style
(szczególnie problem, w którym w przeciwnym razie dziedziczyłoby inną granicę - nie chcesz deklarować innej do border: none)

Edytuj: W przypadku, gdy masz "czerwony" po innym niż czerwony kilka razy, każdy "pierwszy" czerwony otrzyma obramowanie. Aby temu zapobiec, trzeba by użyć odpowiedzi BoltClock. Zobacz

 59
Author: SamGoody,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-11-15 13:26:22

Możesz użyć first-of-type lub nth-of-type(1)

.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>
 13
Author: Moes,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-01-13 00:57:44

Aby pasował do twojego selektora, element musi mieć nazwę klasy red I musi być pierwszym dzieckiem swojego rodzica.

<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>
 8
Author: Chetan Sastry,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-12-16 18:50:41

Ponieważ pozostałe odpowiedzi obejmują to, co jest źle z nim, spróbuję drugiej połowy, jak to naprawić. Niestety, nie wiem, czy masz CSS tylko rozwiązanie tutaj, przynajmniej nie żebym mógł myśleć . Istnieją jednak inne opcje....

  1. Przypisz klasę first do elementu, gdy go wygenerujesz, Tak:

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

    CSS:

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

    Ten CSS pasuje Tylko do elementów zarówno first i red klasy.

  2. Alternatywnie zrób to samo w JavaScript, na przykład oto, czego jQuery użyjesz do tego, używając tego samego CSS jak powyżej:

    $(".red:first").addClass("first");
    
 7
Author: Nick Craver,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-06-25 23:07:00

Zgodnie z Twoim zaktualizowanym problemem

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

A może

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

Wybierze Dom klasy, następnie element span i na koniec wszystkie .czerwone elementy , które są umieszczone bezpośrednio po elementach span.

Numer referencyjny: http://www.w3schools.com/cssref/css_selectors.asp

 5
Author: StinkyCat,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-01-21 11:49:39

Możesz zmienić swój kod na coś takiego, aby działał

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

This does the job for you

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

Tutaj jest odniesienie CSS z SnoopCode o tym.

 3
Author: Prabhakar,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-10-14 10:15:28

Używam poniższego CSS, aby mieć obraz tła dla listy 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
Author: li bing zhao,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-06-18 15:10:14

Możesz użyć nth-of-type(1), ale upewnij się, że strona nie musi obsługiwać IE7 itd., Jeśli tak jest użyj jQuery, aby dodać klasę body, następnie znajdź element za pomocą klasy body IE7, następnie nazwę elementu, a następnie dodaj do niego NTH-child stylizacji.

 2
Author: Jamie Paterson,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-06-03 12:59:17

Try this:

    .class_name > *:first-child {
        border: 1px solid red;
    }
 2
Author: Loy,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-08-04 22:06:52

Mam to w swoim projekcie.

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>
 2
Author: Yener Örer,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-01-31 07:02:47

Powyższe odpowiedzi są zbyt złożone.

.class:first-of-type { }

To wybierze pierwszy typ klasy. MDN Source

 2
Author: Gabriel Fair,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-06-28 13:53:43

Z jakiegoś powodu żadna z powyższych odpowiedzi nie zdawała się dotyczyć przypadku prawdziwego pierwszego i tylko pierwszego dziecka rodzica.

#element_id > .class_name:first-child

Wszystkie powyższe odpowiedzi zawiodą, jeśli chcesz zastosować styl tylko do dziecka pierwszej klasy w tym kodzie.

<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
Author: Yavor Ivanov,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-06-18 15:08:56

Wypróbuj ten prosty i skuteczny

 .home > span + .red{
      border:1px solid red;
    }
 0
Author: Friend,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-07-26 08:19:19

Spróbuj tego rozwiązania:

 .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
Author: Santosh Khalse,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-06-18 15:08:35

Potrzebne tylko pierwszy i tylko jeden akapit zrobić czerwony. Jak?

<!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>
 0
Author: Alexander V. Ulyanov,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-07-15 17:48:05

Uważam, że użycie selektora względnego + do zaznaczania elementów umieszczonych zaraz po, działa tutaj najlepiej (jak sugerowano wcześniej).

W tym przypadku możliwe jest również użycie tego selektora

.home p:first-of-type

Ale to jest selektor elementu, a nie klasa.

Tutaj masz ładną listę selektorów CSS: https://kolosek.com/css-selectors/

 -1
Author: Nesha Zoric,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-04-11 06:47:01