Basamaklı katmanlar tarayıcınıza geliyor

Basamaklandırılmış katmanlar (@layer CSS kuralı), Chromium 99, Firefox 97 ve Safari 15.4 Beta'ya eklendi. Stil özgünlüğüne bağlı çakışmaları önlemek için CSS dosyalarınız üzerinde daha net bir kontrol sağlarlar. Bu, özellikle büyük kod tabanları, tasarım sistemleri ve uygulamalarda üçüncü taraf stilleri yönetirken yararlıdır.

CSS'nizi net bir şekilde katmanlara ayırmak, beklenmedik stil geçersiz kılmalarını önler ve daha iyi CSS mimarisi sağlar.

CSS özgüllüğü ve basamaklı stil uygulama

CSS özgüllüğü, CSS'nin hangi öğelere hangi stillerin uygulanacağına karar verme şeklidir. Kullanabileceğiniz farklı seçiciler, stil kurallarının özgünlüğünü belirler. Örneğin, öğeler sınıflara veya özelliklere kıyasla daha az spesifiktir. Sınıflar da kimliklere kıyasla daha az spesifiktir. Bu, CSS'yi öğrenmenin temel bir parçasıdır.

Kullanıcılar, spesifikliğin yanlışlıkla geçersiz kılınmasını önlemek için BEM gibi CSS adlandırma kurallarına başvurur. Her şeye tek bir sınıf adı vererek her şey aynı özgünlük düzleminde yerleştirilir. Ancak özellikle üçüncü taraf kod ve tasarım sistemleriyle çalışırken bu tür düzenli stilleri korumak her zaman mümkün değildir.

Sınıf içeren bir kartın BEM görseli
keepinguptodate.com adresindeki BEM adlandırmasının açıklayıcı örneği.

Basamaklı katmanlar bu sorunu çözmeyi amaçlar. CSS düşüşümüne yeni bir katman ekler. Katmanlı stillerde, katmanın önceliği her zaman seçicinin özgünlüğünü geçer.

Örneğin, .post a.link seçicisinin özgünlüğü .card a seçicisinden daha yüksektir. Bir kartın içindeki bağlantıya stil uygulamaya çalışırsanız daha spesifik seçicinin uygulandığını görürsünüz.

@layer kullanarak her birinin stil özgünlüğü hakkında daha net bilgi verebilir ve tüm CSS'niz aynı düzlemde olsaydı özgünlük sayısal olarak daha düşük olsa bile kart bağlantınızın stillerinin gönderi bağlantısının stillerini geçersiz kılmasını sağlayabilirsiniz. Bunun nedeni, basamak sırası önceliğidir. Katmanlı stiller yeni basamaklı "düzlemler" oluşturur.

Kullanıcı arayüzünü bölmeyle ilgili proje demosundan görsel

@layer

İçe aktarmalarla bağlantı renklerini gösteren demo
Codepen'deki demoyu inceleyin.

Bu örnekte, @layer kullanılarak basamaklı katmanların gücü gösterilmektedir. Birkaç bağlantı gösterilir: Bazılarında ek sınıf adı uygulanmaz, birinde .link sınıfı, diğerinde ise .pink sınıfı vardır. Ardından CSS, aşağıdaki gibi üç katman ekler: base, typography ve utilities:

@layer base {
  a {
    font-weight: 800;
    color: red; /* ignored */
  }

  .link {
    color: blue; /* ignored */
  }
}

@layer typography {
  a {
    color: green; /* styles *all* links */
  }
}

@layer utilities {
  .pink {
    color: hotpink;  /* styles *all* .pink's */
  }
}

Sonuç olarak tüm bağlantılar yeşil veya pembe olur. Bunun nedeni: .link, seçici düzeyinde a'ten daha yüksek bir özgünlüğe sahip olsa da a'te daha yüksek öncelikli bir @layer içinde bir renk stili vardır. Yeşil kural mavi kuraldan sonraki bir katmanda olduğunda a { color: green }, .link { color: blue }'ü geçersiz kılar.

Katman önceliği, öğe özgünlüğünü geçersiz kılar.

Katmanları düzenleme

Katmanları doğrudan sayfa üzerinde (yukarıda gösterildiği gibi) veya dosyanın üst kısmında düzenleyebilirsiniz.

Katman sırası, her katman adının kodunuzda ilk kez göründüğü sırada belirlenir.

Yani dosyanın üst kısmına aşağıdakileri eklerseniz bağlantıların tümü kırmızı, .link sınıfına sahip bağlantı ise mavi görünür:

@layer utilities, typography, base;

Bunun nedeni, katman sırasının artık tersine çevrilmesi ve yardımcı programların önce, temel katmanın ise sona yerleştirilmesidir. Bu nedenle, base katmanındaki stil kuralları her zaman tipografi katmanındaki stil kurallarına göre daha yüksek bir özgünlüğe sahiptir. Bu bağlantılar artık yeşil değil, kırmızı veya mavi olacak.

Codepen projesinin ekran görüntüsü
Codepen'deki demoyu inceleyin.

İçe aktarma işlemlerini düzenleme

@layer'ü kullanmanın bir diğer yolu da içe aktarma dosyalarıdır. Bunu, aşağıdaki örnekte gösterildiği gibi layer() işlevini kullanarak doğrudan stilleri içe aktarırken yapabilirsiniz:

/* Base */
@import '../styles/base/normalize.css' layer(base); /* normalize or rest file */
@import '../styles/base/base.css' layer(base); /* body and base styles */
@import '../styles/base/theme.css' layer(theme); /* theme variables */
@import '../styles/base/typography.css' layer(theme); /* theme typography */
@import '../styles/base/utilities.css' layer(utilities); /* base utilities */

/* Layouts */
@import '../styles/components/post.css' layer(layouts); /* post layout */

/* Components */
@import '../styles/components/cards.css' layer(components); /* imports card */
@import '../styles/components/footer.css' layer(components); /* footer component */

Yukarıdaki kod snippet'inde üç katman vardır: base,layouts ve components. base'te normalleştirme, tema ve yazı tipi dosyaları, layouts'de post dosyası ve components'te cards ile footer dosyaları. Dosya içe aktarıldığında katmanlar, katman işlevi kullanılarak oluşturulur. Alternatif bir yaklaşım, katmanlarınızı dosyanın en üstünde organize etmek ve içe aktarma işlemlerinden önce tanımlamaktır:

@layer base,
       theme,
       layouts,
       components,
       utilities;

Artık stillerinizi @import sırası, katman adının ilk örneğinde belirlendiği için katman sırası açısından önemli değildir. Bu sayede endişelenmeniz gereken bir şey daha azalır. İçe aktarılan dosyaları belirli katmanlara ayarlamaya devam edebilirsiniz ancak sıralama zaten belirlenmiştir.

Codepen projesinin ekran görüntüsü
Codepen'deki projeyi keşfedin.

Katmanlar ve basamaklı düzen

Bir adım geri çekilip katmanların daha geniş bir akışla ilişkili olarak nerede kullanıldığını görelim:

Cascade Görseli

Öncelik sırası şu şekildedir:

  • Kullanıcı aracısı normal (en düşük öncelik)
  • Yerel Kullanıcı @katman
  • Yerel kullanıcı normal
  • Yazar @layers
  • Yazar normal
  • Yazar !important
  • Yazar @layer !important
  • Yerel Kullanıcı !important
  • User-Agent !important** (en yüksek öncelik)

Burada @layer !important stillerinin ters çevrildiğini fark edebilirsiniz. Katmansız (normal) stillere kıyasla daha az spesifik olmak yerine daha yüksek önceliğe sahiptirler. Bunun nedeni, !important'ün kademeli olarak çalışma şeklidir: Stil sayfalarınızdaki normal kademeli çalışmayı bozar ve normal katman düzeyindeki özgüllüğü (öncelik) tersine çevirir.

İç içe yerleştirilmiş katmanlar

Katmanlar diğer katmanların içine yerleştirilebilir. Aşağıdaki örnek, Miriam Suzanne'in Cascade Layers (Dizi Katmanları) açıklamalı makalesinden alınmıştır:

@layer default {
  p { max-width: 70ch; }
}

@layer framework {
  @layer default {
    p { margin-block: 0.75em; }
  }

  p { margin-bottom: 1em; }
}

Yukarıdaki kod snippet'inde, framework içinde iç içe yerleştirilmiş default katmanının işaretçisi olarak bir . kullanarak framework.default'e erişebilirsiniz. Bunu daha kısa bir biçimde de yazabilirsiniz:

@layer framework.default {
  p { margin-block: 0.75em }
}

Elde edilen katmanlar ve katman sırası şunlardır:

  • varsayılan
  • framework.default
  • framework katman kaldırıldı
  • katmansız

Dikkat etmeniz gerekenler

Doğru şekilde kullanırsanız basamaklı katmanlar çok faydalı olabilir ancak ek karışıklık ve beklenmedik sonuçlar da yaratabilir. Basamaklandırılmış katmanlarla çalışırken aşağıdakilere dikkat edin:

1. Kural: Kapsam belirleme için @layer kullanmayın

Basamak katmanları, kapsamı çözmez. @layer içeren bir CSS dosyanız (ör. card.css) varsa ve karttaki tüm bağlantılara stil uygulamak istiyorsanız aşağıdaki gibi stiller yazmayın:

a {
  
}

Bu işlem, dosyanızdaki tüm a etiketlerinin bu geçersiz kılma işlemini almasına neden olur. Yine de stillerinizi doğru şekilde kapsama önemlidir:

.card a {
  
}

2. Kural: Kaskad katmanları, katmansız CSS'nin arkasında sıralanır.

Katmanlı bir CSS dosyasının, katmanlı olmayan CSS'yi geçersiz kılmayacağını unutmayın. Bu, mevcut kod tabanınızla çalışmak için katmanları daha mantıklı bir şekilde tanıtmayı kolaylaştırmak amacıyla bilinçli olarak alınmış bir karardır. Örneğin, reset.css dosyası kullanmak, basamaklı katmanlar için iyi bir başlangıç noktası ve kullanım alanıdır.

3. kural: !important, basamaklılık özgünlüğünü tersine çevirir

Katmanlı stiller genel olarak katmansız stillere göre daha az spesifik olsa da !important kullanıldığında bu durum tersine döner. Bir katmanda, !important kuralını içeren bildirimler katmanlandırılmamış stillerden daha spesifiktir.

Bu durumda, !important stilleri özgüllüklerini tersine çevirir. Yukarıdaki şema, referans olarak bu durumu göstermektedir: @layers yazarı, normal yazarı, !important yazarı ve @layer !important yazarı sırasıyla daha düşük önceliğe sahiptir.

Birden fazla katmanınız varsa !important içeren ilk katman !important önceliğine sahip olur ve en belirgin stil olur.

4. Kural: Enjeksiyon noktalarını anlama

Katman sırası, her katman adı kodunuzda ilk kez göründüğünde belirlenir. Bu nedenle, layer()'leri içe aktarıp ayarladıktan sonra veya farklı bir @layer ifadesi sonrasında bir @layer beyanı eklerseniz bu beyan yoksayılabilir. CSS'de, basamaklı katmanlar için sayfanın en altındaki stil kuralının uygulandığından farklı olarak, sıra ilk aşamada belirlenir.

Bu, bir listede, katman bloğunda veya içe aktarma işleminde olabilir. layer() içeren bir içe aktarma listesinin sonuna @layer eklerseniz hiçbir işlem yapılmaz. Dosyanın en üstüne yerleştirdiğinizde katman sırasını belirler ve mimarideki katmanları net bir şekilde görmenize yardımcı olur.

5. Kural: Belirginliğinize dikkat edin

Kaskad katmanlarda, daha az spesifik bir seçici (a gibi) daha spesifik bir katmandaysa daha spesifik bir seçiciyi (.link gibi) geçersiz kılar. Aşağıdakileri göz önünde bulundurun:

Aşağıdaki durumlarda layer(components) içindeki a, layer(utilities) içindeki .pink değerini geçersiz kılar: @layer utilities, components belirtilmişse. API'nin kasıtlı bir parçası olsa da bunu beklemiyorsanız kafa karıştırıcı ve can sıkıcı olabilir.

Bu nedenle, yardımcı sınıflar yazıyorsanız bunları her zaman geçersiz kılmayı amaçladığınız bileşenlerden daha yüksek düzeyli bir katman olarak ekleyin. "Rengi değiştirmek için bu .pink sınıfını ekledim ama uygulanmıyor" diye düşünebilirsiniz.

Basamak katmanları hakkında daha fazla bilgi

Kaskad katmanlar hakkında daha fazla bilgi edinmek için aşağıdaki kaynaklara da göz atabilirsiniz: