: Nth-child () veya: nth-of-type () 'ı rastgele bir seçici ile birleştirebilir miyim?


117

Keyfi bir seçiciyle eşleşen (veya eşleşmeyen) her n'inci çocuğu seçmenin bir yolu var mı ? Örneğin, her bir tek tablo satırını seçmek istiyorum, ancak satırların bir alt kümesi içinde:

table.myClass tr.row:nth-child(odd) {
  ...
}
<table class="myClass">
  <tr>
    <td>Row
  <tr class="row"> <!-- I want this -->
    <td>Row
  <tr class="row">
    <td>Row
  <tr class="row"> <!-- And this -->
    <td>Row
</table>

Ama :nth-child()sadece tüm saymak gibi görünüyor trBir ile bitirmek böylece bakılmaksızın, "satır" sınıfının konum olsun veya olmasın unsurlarını bile "satır" elemanının yerine aradığım iki. Aynı şey için de geçerlidir :nth-of-type().

Birisi nedenini açıklayabilir mi?

Yanıtlar:


144

Bu, nasıl :nth-child()ve :nth-of-type()çalıştığının yanlış anlaşılmasından kaynaklanan çok yaygın bir sorundur . Ne yazık ki, şu anda henüz seçici tabanlı bir çözüm yoktur, çünkü Seçiciler, tek sayılı, çift sayılı veya herhangi bir an+byerde a != 1ve gibi bir modele dayalı olarak rastgele bir seçici ile eşleşen n'inci çocuğu eşleştirmenin bir yolunu sağlamamaktadır b != 0. Bu, seçicileri, olumsuzlamaları ve basit seçicilerin daha karmaşık kombinasyonlarını ilişkilendirmek için yalnızca sınıf seçicilerinin ötesine geçer.

:nth-child()Sözde sınıf arasında sayar tüm aynı ebeveyn altında kardeşlerinin. Yalnızca seçicinin geri kalanıyla eşleşen kardeşleri saymaz. Benzer şekilde, :nth-of-type()sözde sınıf , seçicinin geri kalanına değil, HTML'deki etiket adına atıfta bulunan aynı öğe türünü paylaşan kardeşleri sayar.

Bu aynı zamanda, aynı ebeveynin tüm eğer çocukların sadece çocuklardır bir tablo vücutta durumunda örneğin, aynı eleman türünden olduğu anlamına gelir trunsurları veya sadece çocuklar edilir bir liste elemanı lielemanları, daha sonra :nth-child()ve :nth-of-type()aynı şekilde davranacaktır, yani her değeri için an+b, :nth-child(an+b)ve :nth-of-type(an+b)elementlerin aynı seti eşleşir.

Aslında, örneğin sözde sınıflar da dahil olmak üzere, belirli bir bileşiğin seçici tüm basit seçiciler, :nth-child()ve :not()bağımsız olarak birbirlerinden çok bakarak daha alt- seçici geri kalanı ile eşleşen elementlerin.

Bu aynı zamanda, her bir tek tek bileşik seçici 1 içindeki basit seçiciler arasında bir düzen kavramı olmadığı anlamına gelir; bu, örneğin aşağıdaki iki seçicinin eşdeğer olduğu anlamına gelir:

table.myClass tr.row:nth-child(odd)
table.myClass tr:nth-child(odd).row

İngilizceye çevrildiğinde her ikisi de şu anlama gelir:

trAşağıdaki bağımsız koşulların tümü ile eşleşen herhangi bir öğeyi seçin :

  • ebeveyninin tek sayılı bir çocuğu;
  • "row" sınıfına sahiptir; ve
  • table"myClass" sınıfına sahip bir elemanın soyundan gelir.

(Burada sırasız bir liste kullandığımı fark edeceksiniz, sadece eve götürmek için)

Şu anda saf bir CSS çözümü olmadığından, öğeleri filtrelemek ve buna göre stilleri veya ekstra sınıf adlarını uygulamak için bir komut dosyası kullanmanız gerekecektir. Örneğin, aşağıdaki jQuery kullanan yaygın bir çözümdür ( trtablo içindeki öğelerle doldurulmuş yalnızca bir satır grubu olduğu varsayılırsa ):

$('table.myClass').each(function() {
  // Note that, confusingly, jQuery's filter pseudos are 0-indexed
  // while CSS :nth-child() is 1-indexed
  $('tr.row:even').addClass('odd');
});

İlgili CSS ile:

table.myClass tr.row.odd {
  ...
}

Selenium gibi otomatik test araçlarını kullanıyorsanız veya lxml gibi araçlarla HTML'yi işliyorsanız, bu araçların birçoğu alternatif olarak XPath'e izin verir:

//table[contains(concat(' ', @class, ' '), ' myClass ')]//tr[contains(concat(' ', @class, ' '), ' row ')][position() mod 2)=1]

Farklı teknolojileri kullanan diğer çözümler okuyucuya alıştırma olarak bırakılır; bu sadece açıklama için kısa, uydurma bir örnektir.


Değeri ne olursa olsun, belirli bir seçiciyle eşleşen her n'inci çocuğu seçmenin özel amacı için Seçiciler düzey 4'e eklenecek gösterime bir genişletme:nth-child() önerisi vardır . 2

Eşleşmelerin filtreleneceği seçici :nth-child(), yine mevcut seçici sözdizimi tarafından dikte edilen bir sırayla seçicilerin birbirinden bağımsız olarak nasıl çalıştığına bağlı olarak bir argüman olarak sağlanır . Yani sizin durumunuzda şöyle görünecektir:

table.myClass tr:nth-child(odd of .row)

(Zeki bir okuyucu :nth-child(odd of tr.row), basit seçiciler trve :nth-child()birbirlerinden bağımsız olarak çalıştıkları için, bunun yerine olması gerektiğini hemen fark edecektir . Bu, seçicileri kabul eden işlevsel sözde sınıflarla ilgili sorunlardan biridir, bir kutu solucan bu cevabın ortasında açık değil. Bunun yerine, çoğu sitenin şu varsayımla devam edeceğim:tr bir masa gövdesinde birbirinin kardeşleri gibi öğelerden varsayacağım, bu her iki seçeneği de işlevsel olarak eşdeğer kılacaktır.)

Tabii ki, yepyeni bir spesifikasyonda yepyeni bir teklif olduğu için, bu muhtemelen yolda birkaç yıla kadar uygulanmayacaktır. Bu arada, yukarıdaki gibi bir komut dosyası kullanmak zorunda kalacaksınız.


1 Bir tür veya evrensel seçici belirtirseniz, önce gelmelidir. Ancak bu, seçicilerin temelde çalışma şeklini değiştirmez; sözdizimsel bir tuhaflıktan başka bir şey değil.

2 Bu başlangıçta önerildi :nth-match(), ancak yine de yalnızca kardeşlerine göre bir öğeyi saydığından ve verilen seçiciyle eşleşen diğer tüm öğelere göre sayılmadığından, 2014'ten beri :nth-child()bunun yerine var olanın bir uzantısı olarak yeniden tasarlandı .


3
"(burada sırasız bir liste kullandığımı fark edeceksiniz, sadece eve götürmek için)" Keşke daha fazla insan sıralı ve sırasız mermi kullanımları konusunda bu kadar bilinçli olsalardı. Cevabınız için teşekkür ederim.
Kırmızı Bezelye

1
@ The Red Pea: En büyük HTML pet peeveslerimden biri: "En yüksekten en düşüğe / en düşüğe / en yükseğe:" ve ardından sırasız bir liste. Yani hadi cidden mi?
BoltClock

6

Pek sayılmaz..

belgelerden alıntı

:nth-childSözde sınıfı, bir + b-1 olan bir elemanı ile eşleşir belge ağacındaki daha önce kardeşleri belirli bir pozitif ya da n sıfır değeri, ve bir üst elemanına sahiptir.

Kendi başına bir seçicidir ve sınıflarla birleşmez. Kuralınızda, her iki seçiciyi aynı anda tatmin etmesi gerekir, bu nedenle, :nth-child(even)eğer .rowsınıfa sahiplerse tablo satırlarını gösterecektir .


0

nth-of-typeaynı tip elemanın nth-childindeksine göre çalışır, ancak elemanların ne tip kardeşler olduğuna bakılmaksızın sadece indekse göre çalışır.

Örneğin

<div class="one">...</div>
<div class="two">...</div>
<div class="three">...</div>
<div class="four">...</div>
<div class="five">...</div>
<div class="rest">...</div>
<div class="rest">...</div>
<div class="rest">...</div>
<div class="rest">...</div>
<div class="rest">...</div>

Yukarıdaki html'de rest sınıfına sahip tüm öğeleri gizlemek istediğimizi varsayalım.

Bu durumda nth-childve nth-of-typetüm elemanlar aynı tipte olduğu gibi tam olarak aynı şekilde çalışacaktır, <div>bu yüzden css olmalıdır

.rest:nth-child(6), .rest:nth-child(7), .rest:nth-child(8), .rest:nth-child(9), .rest:nth-child(10){
    display:none;
}

VEYA

.rest:nth-of-type(6), .rest:nth-of-type(7), .rest:nth-of-type(8), .rest:nth-of-type(9), .rest:nth-of-type(10){
    display:none;
}

Şimdi nth-childve arasındaki farkın ne olduğunu merak ediyor olmalısın.nth-of-type bu yüzden fark bu

Html'nin

<div class="one">...</div>
<div class="two">...</div>
<div class="three">...</div>
<div class="four">...</div>
<div class="five">...</div>
<p class="rest">...</p>
<p class="rest">...</p>
<p class="rest">...</p>
<p class="rest">...</p>
<p class="rest">...</p>

Yukarıdaki html'de .restöğe türü diğerlerinden farklıdır .restparagraflar ve diğerleri div'dir, bu durumda kullanıyorsanız nth-childböyle yazmalısınız

.rest:nth-child(6), .rest:nth-child(7), .rest:nth-child(8), .rest:nth-child(9), .rest:nth-child(10){
    display:none;
}

ancak n'inci türü css kullanıyorsanız bu olabilir

.rest:nth-of-type(1), .rest:nth-of-type(2), .rest:nth-of-type(3), .rest:nth-of-type(4), .rest:nth-of-type(5){
    display:none;
}

Türü olarak .resteleman olduğu <p>işte nth-of-typetipini tespit edilir .restve sonra 1., 2., 3., 4., 5. element üzerinde css uygulanan <p>.


Bu, <tr>etiketler için ne kadar yararlı ?
Alexis Wilke

0

Bunu xpath ile yapabilirsiniz. gibi bir şey //tr[contains(@class, 'row') and position() mod 2 = 0]işe yarayabilir. Sınıfları daha kesin bir şekilde eşleştirmenin ayrıntılarını genişleten başka SO soruları da var.


0

İşte cevabın

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>TEST</title>

  <style>

    .block {
      background: #fc0;
      margin-bottom: 10px;
      padding: 10px;
    }
    /* .large > .large-item:nth-of-type(n+5) {
      background: #f00;
    } */

    .large-item ~ .large-item ~ .large-item ~ .large-item ~ .large-item {
      background: #f00;
    }

  </style>
</head>
<body>

<h1>Should be the 6th Hello Block that start red</h1>
<div class="small large">
  <div class="block small-item">Hello block 1</div>
  <div class="block small-item large-item">Hello block 2</div>
  <div class="block small-item large-item">Hello block 3</div>
  <div class="block small-item large-item">Hello block 4</div>
  <div class="block small-item large-item">Hello block 5</div>
  <div class="block small-item large-item">Hello block 6</div>
  <div class="block small-item large-item">Hello block 7</div>
  <div class="block small-item large-item">Hello block 8</div>
</div>

</body>
</html>

0

Nth-child kullanma ve gizli etiketleri atlama ile ilgili tüm sorular, bunun kopyaları olarak yeniden yönlendiriliyor gibi görünüyor, bu yüzden bunu burada bırakacağım. Bu bloga rastladım https://blog.blackbam.at/2015/04/09/css-nth-child-selector-ignore-hidden-element/ nth-child'ın gizli öğeleri göz ardı etmesini sağlamak için akıllı bir css yaklaşımı kullanan, aşağıdaki gibi:

Aşağıdaki CSS, hangi öğenin cpw sınıfına sahip olduğuna bakılmaksızın her ikinci görünür öğeye bir marj hakkı ekler.

.cpw {
    display:none;
}

.video_prewrap {
    margin-right:20px;
}

.video_prewrap:nth-child(2n) {
    margin-right:0;
}

.cpw ~ .video_prewrap:nth-child(2n) {
    margin-right:20px;
}

.cpw ~ .video_prewrap:nth-child(2n-1) {
    margin-right:0;
}

Umarım bu, gizli öğeler sorularını görmezden gelmek için dupe izini takip eden birine yardımcı olur!


1
Buna oy vermek isterim ama çalışan bir demoya ihtiyacı var.
Moob

Hatırladığım kadarıyla, bu aslında başlangıçta göründüğü kadar sağlam değildi - şimdi en çok oylanan yorumla devam edeceğim, bu mümkün değil.
IrishDubGuy

0

Tüm seçici için aynı ana sınıfa sahipseniz, O zaman bu sınıfı kullanırsınız document.querySelector("main .box-value:nth-child(3) select.priorityOption"); Çünkü bu durumda document.querySelector("main .box-value select.priorityOption:nth-child(3)");Çalışmıyor. Teşekkür ederim

<div class="card table">
    <div class="box">
        <div class="box-value">
            <select class="priorityOption">
                <option value="">--</option>
                <option value="">LOREM</option>
                <option value="">LOREM</option>
            </select>
        </div>

        <div class="box-value">
            <select class="priorityOption">
                <option value="">--</option>
                <option value="">LOREM</option>
                <option value="">LOREM</option>
            </select>
        </div>

        <div class="box-value">
            <select class="priorityOption">
                <option value="">--</option>
                <option value="">LOREM</option>
                <option value="">LOREM</option>
            </select>
        </div>
    </div>
</div>
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.