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.
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.
@layer
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.
İç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.
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:
Ö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: