Belirginlik

The CSS Podcast - 003: Specificity

Aşağıdaki HTML ve CSS ile çalıştığınızı varsayalım:

<button class="branding">Hello, Specificity!</button>
.branding {
  color: blue;
}

button {
  color: red;
}

Burada aynı öğeyi hedefleyen iki kural var. Her kural, düğmenin rengini ayarlamak isteyen bir bildirim içerir: Biri düğmeyi kırmızı, diğeri ise mavi renge boyamaya çalışır. Öğeye hangi bildirim uygulanır?

CSS özgüllük algoritmasını anlamak, CSS'nin rekabet eden bildirimler arasında nasıl karar verdiğini anlamanın anahtarıdır.

Belirlilik, basamaklandırma ile ilgili son modülde ele alınan basamaklandırmanın farklı aşamalarından biridir.

Belirginlik puanlaması

Bir kaynak içindeki her seçici kuralı puanlanır. Özgüllüğü toplam puan olarak düşünebilirsiniz. Her seçici türü, bu puana katkıda bulunur. En yüksek özgüllüğe sahip kurallardan gelen beyanlar önceliklidir.

Gerçek bir projede, dengeyi sağlamak için beklediğiniz CSS kurallarının gerçekten uygulandığından emin olmanız ve karmaşıklığı önlemek için puanları genel olarak düşük tutmanız gerekir. Belirginlik, mümkün olan en yüksek belirginliği hedeflemek yerine yalnızca ihtiyaç duyduğumuz kadar yüksek olmalıdır. Gelecekte gerçekten daha önemli bazı CSS'lerin uygulanması gerekebilir. En yüksek özgüllüğü seçerseniz bu işi zorlaştırırsınız.

Belirginlik, ondalık sayı değil, üç bileşenden oluşan bir üçlüdür: A, B ve C.

  • A: Kimliğe benzer özgüllük
  • B: sınıf benzeri özgüllük
  • C: öğe benzeri özgünlük

Genellikle (A,B,C) gösterimiyle ifade edilir. Örneğin: (1,0,2). Alternatif A-B-C gösterimi de yaygın olarak kullanılır.

Özgüllüğün üç bileşenini (A,B,C) gösteren bir şema. Şemada her bileşenin neyi temsil ettiği ve onu etkileyen bazı örnek seçiciler gösterilir.
Çeşitli seçicilerin özgüllüğün hangi bileşenini etkilediğini gösteren bir şema.

Özellikleri karşılaştırma

Belirlilikler, üç bileşenin sırayla karşılaştırılmasıyla belirlenir: Daha büyük bir A değerine sahip olan belirlilik daha belirgindir; İki A değeri eşitse daha büyük bir B değerine sahip olan belirlilik daha belirgindir; İki B değeri de eşitse daha büyük bir C değerine sahip olan belirlilik daha belirgindir; Tüm değerler eşitse iki belirlilik eşittir.

Örneğin, (1,0,0), (0,4,3) değerinden daha yüksek bir özellikte kabul edilir. Bunun nedeni, (1,0,0) içindeki A değerinin (1) (0,4,3) içindeki A değerinden (0) büyük olmasıdır.

Seçiciler, özgüllüğü etkiler

Özgüllük üçlüsündeki her bölüm 0 değeriyle başlar. Bu nedenle, varsayılan özgüllük (0,0,0) olur. Seçicinin her bölümü, seçici türüne bağlı olarak A, B veya C değerini artıran özgüllüğü artırır.

Evrensel seçici

Evrensel seçici (*), özellik eklemez ve değerini (0,0,0) başlangıç özelliğinde bırakır.

* {
  color: red;
}

Öğe veya sözde öğe seçici

Bir element (tür) veya sözde öğe seçici, öğe benzeri özgüllük ekler. Bu da C bileşenini 1 artırır.

Aşağıdaki örneklerin genel özgüllüğü (0,0,1)'dır.

Tür seçici

div {
  color: red;
}

Sözde öğe seçici

::selection {
  color: red;
}

Sınıf, sözde sınıf veya özellik seçici

Bir sınıf, sözde sınıf veya özellik seçici, sınıfa benzer özgüllük ekler. Bu da B bileşenini 1 artırır.

Aşağıdaki örneklerin özgüllük değeri (0,1,0)'dır.

Sınıf seçici

.my-class {
  color: red;
}

Sözde sınıf seçici

:hover {
  color: red;
}

Özellik seçici

[href='#'] {
  color: red;
}

Kimlik seçici

Bir kimlik seçici, A bileşenini 1 artırarak kimliğe benzer bir özgüllük ekler. Bunun için özellik seçici ([id="myID"]) değil, kimlik seçici (#myID) kullanmanız gerekir.

Aşağıdaki örnekte, özgüllük (1,0,0)'dır.

#myID {
  color: red;
}

Diğer seçiciler

CSS'de birçok seçici vardır. Bunların hepsi spesifiklik katmaz. Örneğin, :not() sözde sınıfı, özgüllük hesaplamasına hiçbir şey katmaz.

:not() sözde sınıfının özgüllüğü, virgülle ayrılmış seçici bağımsız değişkenindeki en özgül seçicinin özgüllüğüyle değiştirilir. Bu, :not(:is(argument)) yazılmış gibi aynı özgüllüğü sağlar.

div:not(.my-class) {
  color: red;
}

:is() sözde sınıfı da özgüllük hesaplamasına katkıda bulunmaz. :not() gibi, en spesifik argümanının spesifikliğini alır.

:is(h1, h2, h3) {
  color: blue;
}

Bu örnekte yalnızca bir tür seçici (type) olduğundan özgüllük (0,0,1)'dır.

id eklenmesiyle özgüllük (1,0,0)'ye yükselir.

:is(h1, h2, h3, #my-heading) {
  color: blue;
}

:where() sözde sınıfı farklıdır. Bağımsız değişkenlerinin özgüllüğü ne olursa olsun, her zaman (0,0,0) özgüllüğüne sahiptir.

:where(h1, h2, h3, #my-heading) {
  color: blue;
}

:where() kullanılarak uygulanan düşük özgüllükteki stiller, stil sayfanızda daha sonra temel seçicilerle bu stilleri geçersiz kılmanıza olanak tanır:

:where(#my-content) {
   color: red;
}

p {
   color: blue;
}

:where(), bağımsız değişkenler listesinde id olmasına rağmen yalnızca (0, 0, 0) özgüllüğüne sahiptir. Bu nedenle, temel p seçici bunu geçersiz kılar ve metin blue olur.

Bilgilerinizi sınayın

Özgüllük puanlamasıyla ilgili bilginizi test edin

a[href="#"]'nın özgüllüğü nedir?

(0,0,1)
a değeri (0,0,1), [href="#"] değeri ise (0,1,0).
(0,1,0)
Tekrar deneyin. a değeri (0,0,1), [href="#"] değeri ise (0,1,0).
(0,1,1)
a, (0,0,1) değerinde ve [href="#"], (0,1,0) değerinde olup toplam özgüllük (0,1,1)'dir.

Özelliği etkilemeyen faktörler

Aşağıda, özgüllüğü etkileyen faktörlerle ilgili bazı yaygın yanlış kanılar verilmiştir.

Satır içi stil öznitelikleri

Bir öğenin style özelliğine doğrudan uygulanan CSS, basamaklandırmada farklı bir adım olduğu için özgüllüğü etkilemez. Bu adım, özgüllükten önce değerlendirilir.

<div style="color: red"></div>

Bu bildirimi bir stil sayfasından geçersiz kılmak için basamaklandırmanın önceki bir adımında bildirimin kazanmasını sağlamanız gerekir.

Örneğin, !important kaynağını Authored !important kaynağının bir parçası haline getirmek için bu kaynağı ekleyebilirsiniz.

!important beyan

Bir CSS beyanının sonundaki !important, özgüllüğü etkilemez ancak beyanı farklı bir kaynağa, yani Authored !important'a yerleştirir.

Aşağıdaki örnekte, .my-class öğesinin özgüllüğü, !important beyanının kazanması için önemli değildir.

.my-class {
  color: red !important;
  color: white;
}

İki bildirim !important olduğunda, basamaklandırmadaki kaynak adımı henüz kazananı belirleyemediği için özgüllük tekrar devreye girer.

.branding {
  color: blue !important;
}

button {
  color: red !important;
}

Bağlamda özgüllük

Karmaşık veya bileşik bir seçici kullanıldığında, bu seçicinin her bölümü özgüllüğe katkıda bulunur. Aşağıdaki örnek HTML'yi inceleyin:

<a class="my-class another-class" href="#">A link</a>

Bu bağlantıda iki sınıf var. Aşağıdaki CSS'deki kuralın özelliği (0,0,1)'dir:

a {
  color: red;
}

Seçicideki sınıflardan birine referans verirseniz artık (0,1,1) özgüllüğe sahiptir:

a.my-class {
  color: green;
}

Diğer sınıfı seçiciye ekleyin. Artık (0,2,1) özgüllüğe sahip:

a.my-class.another-class {
  color: rebeccapurple;
}

Seçiciye href özelliğini ekleyin. Artık (0,3,1) özgüllüğe sahip:

a.my-class.another-class[href] {
  color: goldenrod;
}

Son olarak,tüm bunlara bir :hover sözde sınıfı ekleyin. Seçici, (0,4,1) özgüllüğe sahip olur:

a.my-class.another-class[href]:hover {
  color: lightgrey;
}

Bilgilerinizi sınayın

Özgüllük puanlamasıyla ilgili bilginizi test edin

Aşağıdaki seçicilerden hangisinin özgüllüğü (0,2,1)'dir?

article > section
Öğeler, öğe benzeri özgünlük (`C` bileşeni) ekler. Seçicide 2 öğe olduğundan bu seçicinin özgüllüğü (0,0,2) olur.
article.card.dark
Öğeler, öğe benzeri özgüllük (`C` bileşeni) ve sınıflar, sınıf benzeri özgüllük (`B` bileşeni) ekler. 2 sınıf ve 1 öğe ile bu seçicinin özgüllüğü (0,2,1) olur.
article:hover a[href]
Öğeler, öğe benzeri özgüllük (`C` bileşeni), sahte sınıflar ve özellikler ise sınıf benzeri özgüllük (`B` bileşeni) ekler. 2 öğe seçici (2 × (0,0,1)), bir özellik seçici ((0,1,0) değerinde) ve bir sınıf seçici ((0,1,0) değerinde) vardır. Bu, seçicinin toplam özgüllüğünü (0,2,2) yapar.

Özgüllüğü pragmatik olarak artırma

Aşağıdaki gibi bir CSS'niz olduğunu varsayalım:

.my-button {
  background: blue;
}

button[onclick] {
  background: grey;
}

Aşağıdaki gibi bir HTML ile:

<button class="my-button" onclick="alert('hello')">Click me</button>

İkinci seçicinin belirginliği (0,1,1) olduğu için düğmenin arka planı gri renktedir. Bunun nedeni, (0,0,1) olan bir tür seçici (button) ve (0,1,0) olan bir özellik seçici ([onclick]) içermesidir.

Önceki kural (.my-button), (0,1,1)'den daha düşük bir özgüllüğe sahip olan bir sınıf seçiciye sahip olduğundan (0,1,0)'e eşittir.

Bu kurala destek vermek isterseniz sınıf seçiciyi aşağıdaki gibi tekrarlayabilirsiniz:

.my-button.my-button {
  background: blue;
}

button[onclick] {
  background: grey;
}

Yeni seçici (0,2,0) özgüllüğüne sahip olduğundan düğme artık mavi arka plana sahip olacak.

Belirlilikte eşitlik olması durumunda, basamaklı stil sayfasındaki bir sonraki adım uygulanır.

Şimdilik düğme örneğiyle devam ederek CSS'yi şu şekilde değiştirin:

.my-button {
  background: blue;
}

[onclick] {
  background: grey;
}

Her iki seçicinin de (0,1,0) eşitlikte olması nedeniyle düğmenin arka planı gridir.

Kuralları kaynak sırasına göre değiştirirseniz düğme mavi olur.

[onclick] {
  background: grey;
}

.my-button {
  background: blue;
}

Bunun nedeni, her iki seçicinin de aynı özgüllüğe sahip olmasıdır. Bu durumda, basamaklı reklam görünme sırası adımına geri döner.

Kaynaklar