Bu, yazarların nasıl :first-child
çalıştığını yanlış anlayan en bilinen örneklerden biridir . CSS2'de sunulan :first-child
sözde sınıf , ebeveyninin ilk çocuğunu temsil eder . Bu kadar. Bileşik seçicinin geri kalanı tarafından belirtilen koşullara uyan ilk alt öğe hangisi olursa olsun, çok yaygın bir yanlış anlama vardır. Seçicilerin çalışma şekli nedeniyle ( açıklama için buraya bakın ), bu doğru değil.
3. seviye:first-of-type
seçiciler, öğe türünün kardeşleri arasındaki ilk öğeyi temsil eden sözde bir sınıf sunar . Bu cevap , resimlerle :first-child
ve arasındaki farkı açıklar :first-of-type
. Bununla birlikte, olduğu gibi :first-child
, başka koşullara veya niteliklere bakmaz. HTML'de, öğe türü etiket adıyla temsil edilir. Soruda, bu tür p
.
Ne yazık ki, :first-of-class
belirli bir sınıfın ilk alt öğesini eşleştirmek için benzer bir sözde sınıf yoktur . Lea Verou ve ben bunun için (tamamen bağımsız da olsa) ortaya çıkardığımız bir çözüm, ilk önce istediğiniz stilleri bu sınıftaki tüm öğelerinize uygulamaktır :
/*
* Select all .red children of .home, including the first one,
* and give them a border.
*/
.home > .red {
border: 1px solid red;
}
... sonra , genel kardeş birleştiriciyi geçersiz kılma kuralını kullanarak , birinci sınıftan sonra gelen sınıftaki öğelerin stillerini "geri alın" :~
/*
* Select all but the first .red child of .home,
* and remove the border from the previous rule.
*/
.home > .red ~ .red {
border: none;
}
Şimdi sadece ilk öğenin class="red"
kenarlığı olacaktır.
Kuralların nasıl uygulandığına dair bir örnek:
<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>
Hiçbir kural uygulanmaz; kenarlık oluşturulmaz.
Bu öğenin sınıfı yoktur red
, bu nedenle atlanır.
Yalnızca ilk kural uygulanır; kırmızı kenarlık oluşturulur.
Bu öğe sınıfa sahiptir red
, ancak red
üst öğesinde sınıf bulunan herhangi bir öğe yoktur . Böylece ikinci kural uygulanmaz, yalnızca ilk kural uygulanır ve öğe sınırını korur.
Her iki kural da uygulanır; kenarlık oluşturulmaz.
Bu öğenin sınıfı vardır red
. Ayrıca, sınıfla birlikte en az bir başka öğe daha gelir red
. Böylece her iki kural da uygulanır ve ikinci border
deklarasyon ilki geçersiz kılar, böylece tabiri caizse "geri alır".
Bonus olarak, Seçiciler 3'te kullanılmasına rağmen, genel kardeş birleştirici aslında aksine IE7 ve daha yeni tarafından desteklenmektedir ve aksine IE9 :first-of-type
ve üstü :nth-of-type()
tarafından desteklenmektedir. İyi bir tarayıcı desteğine ihtiyacınız varsa, şanslısınız demektir.
Aslında, kardeş birleştiricinin bu teknikteki tek önemli bileşen olması ve inanılmaz bir tarayıcı desteğine sahip olması, bu tekniği çok yönlü hale getirir - sınıf seçicilerinin yanı sıra öğeleri başka şeylere göre filtrelemek için uyarlayabilirsiniz:
Bunu, :first-of-type
sınıf seçici yerine bir tür seçici sağlayarak IE7 ve IE8'de çalışmak için kullanabilirsiniz (yine, daha sonraki bir bölümde yanlış kullanımıyla ilgili daha fazla bilgi):
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 */
}
Nitelik seçicilerine veya sınıflar yerine diğer basit seçicilere göre filtreleyebilirsiniz .
Bu geçersiz kılma tekniğini, sözde öğeler teknik olarak basit seçiciler olmasa da sözde öğelerle birleştirebilirsiniz .
Bunun çalışması için, diğer kardeş öğeleriniz için varsayılan stillerin ne olacağını önceden bilmeniz gerektiğini unutmayın, böylece ilk kuralı geçersiz kılabilirsiniz. Ayrıca, bu CSS'deki kuralların geçersiz kılınmasını içerdiğinden, Selectors API veya Selenium'un CSS konum belirleyicileri ile kullanmak için tek bir seçiciyle aynı şeyi başaramazsınız .
Seçiciler 4 , :nth-child()
gösterime bir uzantı ekledi (başlangıçta tamamen yeni bir sözde sınıf :nth-match()
), bu da :nth-child(1 of .red)
varsayım yerine bir şey kullanmanıza izin verecektir .red:first-of-class
. Nispeten yeni bir teklif olarak, henüz üretim tesislerinde kullanılabilmesi için yeterli birlikte çalışabilir uygulama bulunmamaktadır. Umarım bu yakında değişecektir. Bu arada, önerdiğim geçici çözüm çoğu durumda çalışmalıdır.
Bu yanıtın, sorunun belirli bir sınıfa sahip her ilk alt öğeyi aradığını varsaydığını unutmayın. Tüm belgede karmaşık bir seçicinin n. Eşleşmesi için ne sahte bir sınıf, ne de genel bir CSS çözümü yoktur - bir çözümün olup olmadığı büyük ölçüde belge yapısına bağlıdır. jQuery içerir :eq()
, :first
, :last
ve bu amaç için daha ama yine not bu çok farklı bir şekilde işlev :nth-child()
ve diğ . Seçiciler API'sını kullanarak document.querySelector()
ilk eşleşmeyi elde etmek için kullanabilirsiniz :
var first = document.querySelector('.home > .red');
Veya document.querySelectorAll()
belirli bir eşleşmeyi seçmek için bir dizinleyici ile kullanın :
var redElements = document.querySelectorAll('.home > .red');
var first = redElements[0];
var second = redElements[1];
// etc
Her ne kadar Philip Daubmeier'in.red:nth-of-type(1)
orijinal kabul edilen cevabındaki çözüm (başlangıçta Martyn tarafından yazılmıştır ancak o zamandan beri silinmiştir), ancak beklediğiniz gibi davranmaz.
Örneğin, yalnızca p
orijinal işaretlemenizdeki simgesini seçmek istiyorsanız :
<p class="red"></p>
<div class="red"></div>
... o zaman .red:first-of-type
(buna eşdeğer .red:nth-of-type(1)
) kullanamazsınız , çünkü her öğe kendi türündeki ( p
ve div
sırasıyla) ilk (ve yalnızca) bir öğedir , bu nedenle her ikisi de seçici tarafından eşleştirilir.
Belirli bir sınıfın ilk öğesi de türünün ilk öğesi olduğunda, sözde sınıf çalışır, ancak bu sadece tesadüfle olur . Bu davranış Philip'in cevabında gösterilmiştir. Bu öğeden önce aynı türden bir öğeye yapıştığınız anda seçici başarısız olur. Güncellenmiş işaretlemeyi alma:
<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>
İle bir kural uygulamak .red:first-of-type
işe yarayacaktır, ancak p
sınıf olmadan başka bir kural eklediğinizde :
<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>
... seçici hemen başarısız olur, çünkü ilk .red
eleman şimdi ikinci p
elementtir.