CSS'te Kapsülleme Devrimi: `@scope` ile JavaScript Olmadan İzole Stiller Yazmak
CSS'te Kapsülleme Devrimi: @scope ile JavaScript Olmadan İzole Stiller Yazmak
Web geliştirme dünyasında CSS yönetimi, projeler büyüdükçe her zaman en büyük zorluklardan biri olmuştur. Küresel (global) etki alanına sahip olan CSS, yanlışlıkla başka sayfadaki bir butonu bozmanıza, "specificity" (özgünlük/belirleyicilik) savaşlarına girmenize ve devasa !important yığınları oluşturmanıza neden olur.
Yıllarca bu sorunu çözmek için BEM gibi metodolojiler, CSS Modules gibi derleme araçları ve Styled Components veya Emotion gibi karmaşık CSS-in-JS kütüphaneleri kullandık. Ancak tüm bu çözümler ya geliştiriciye ekstra bilişsel yük getiriyor ya da tarayıcıya fazladan JavaScript yükü yüklüyordu.
Artık bunlara ihtiyacımız kalmayabilir. Karşınızda modern CSS'in en heyecan verici özelliklerinden biri: @scope.
Bu yazıda, @scope kuralının ne olduğunu, nasıl çalıştığını ve web geliştirme süreçlerimizi nasıl kökten değiştireceğini pratik örneklerle inceleyeceğiz.
@scope Nedir?
@scope, CSS kurallarının etki alanını DOM ağacının belirli bir alt kümesiyle sınırlamanıza olanak tanıyan yerel (native) bir CSS kuralıdır.
Basitçe söylemek gerekirse: Tarayıcıya, "Bu stilleri sadece X öğesinin içindeki Y öğelerine uygula, dışarıdaki hiçbir şeye dokunma" demenin en temiz ve modern yoludur.
Temel Sözdizimi (Syntax)
@scope (.card) {
/* Bu stiller sadece .card içindeki elemanlar için geçerlidir */
img {
border-radius: 8px;
}
p {
color: #333;
}
}
Yukarıdaki örnekte, .card dışındaki hiçbir img veya p etiketi bu stillerden etkilenmez. Üstelik bunu yapmak için CSS Modules gibi sınıf isimlerini karmaşık hash'lere (.card_title__a8d3x) dönüştürmemize gerek kalmaz.
@scope ile "Simit Kapsülleme" (Doughnut Scoping)
@scope özelliğini asıl güçlü kılan şeylerden biri, kapsülleme alanına bir sınır (limit) koyabilmemizdir. Buna literatürde "Doughnut Scoping" (Simit Kapsülleme) deniyor. Bir başlangıç noktası ve bir bitiş noktası belirleyerek aradaki alanı stilize edebilirsiniz.
Örnek Senaryo:
Bir .article (makale) bileşeniniz var ve içindeki paragrafları stilize etmek istiyorsunuz. Ancak makalenin içine yerleştirilmiş olan .comment-section (yorumlar alanı) bu stillerden etkilensin istemiyorsunuz.
@scope (.article) to (.comment-section) {
p {
font-size: 1.2rem;
line-height: 1.6;
color: #2c3e50;
}
}
Bu kod şu anlama gelir:
* .article içindeki tüm p etiketlerini stilize et.
* Ancak .comment-section içine ulaştığında dur ve onun içindeki p etiketlerine bu stilleri uygulama.
Bu, geleneksel CSS ile yazılması son derece zor ve karmaşık seçiciler gerektiren bir mantıktı. @scope ile bunu tek bir satırda çözebiliyoruz.
:scope Sözde Sınıfı (Pseudo-class)
Kapsülleme alanı içinde, kapsayıcının kendisini hedeflemek istiyorsanız :scope sözde sınıfını kullanabilirsiniz.
@scope (.alert-box) {
:scope {
border: 2px solid red;
padding: 15px;
background-color: #ffeef0;
}
span {
font-weight: bold;
}
}
Burada :scope, doğrudan .alert-box elementinin kendisine karşılık gelir.
Proximity (Yakınlık) Önceliği: CSS Cascade Değişiyor!
CSS'te geleneksel olarak öncelik sırası (cascade) seçicinin türüne (ID, class, element) göre belirlenir. Ancak @scope ile hayatımıza "Proximity" (Yakınlık) kavramı giriyor.
Eğer iki farklı scope kuralı aynı hedefi vuruyorsa, DOM ağacında hedefe en yakın olan scope kazanır.
Örnek:
<div class="light-theme">
<div class="dark-theme">
<p>Ben hangi renk olacağım?</p>
</div>
</div>
@scope (.light-theme) {
p { color: white; }
}
@scope (.dark-theme) {
p { color: black; }
}
Geleneksel CSS'te yazım sırasına göre en alttaki kazanırken, @scope dünyasında <p> etiketine DOM ağacında en yakın olan ata .dark-theme olduğu için metin rengi siyah olacaktır. Bu, stil çakışmalarını yönetmeyi inanılmaz derecede kolaylaştırır.
Neden @scope Kullanmalıyız? (Avantajları)
- Sıfır JavaScript ve Derleme Yükü: CSS Modules, CSS-in-JS (Styled Components) veya Tailwind gibi araçlar harika olsa da bir derleme (build) adımına ihtiyaç duyarlar.
@scopetarayıcıda yerel olarak çalışır. - Daha Küçük Dosya Boyutları: Karmaşık sınıf isimleri (BEM gibi
block__element--modifier) yazmak zorunda kalmadığınız için HTML ve CSS dosyalarınız daha temiz ve hafif olur. - Kolay Bakım: Bir bileşenin stilini değiştirmek istediğinizde, o bileşenin scope bloğuna gitmeniz yeterlidir. Yan etkilerden (side-effects) korkmanıza gerek kalmaz.
- Mükemmel Entegrasyon: Mevcut CSS yapınızla tamamen uyumludur. Tüm projeyi yeniden yazmanıza gerek kalmadan, sadece yeni bileşenleri
@scopeile yazarak kademeli geçiş yapabilirsiniz.
@scope vs. Shadow DOM vs. CSS Modules
| Özellik | @scope |
Shadow DOM | CSS Modules |
|---|---|---|---|
| Çalışma Zamanı | Tarayıcı (Yerel) | Tarayıcı (Yerel) | Derleme (Build) Zamanı |
| JS Bağımlılığı | Yok | Gerekli (Web Components) | Yok (Ama build aracı şart) |
| Dışarıdan Stil Sızması | Sınırlandırılabilir | Tamamen Kapalı | Sınıf isimleriyle önlenir |
| Kullanım Kolaylığı | Çok Kolay | Orta/Zor | Kolay |
Tarayıcı Desteği ve Bugün Kullanımı
@scope, modern tarayıcılar tarafından hızla benimsenmektedir. Chrome, Edge, Safari ve Opera'nın güncel sürümleri @scope özelliğini tamamen desteklemektedir. Firefox tarafında ise geliştirme çalışmaları devam etmekte olup, yakın zamanda tam desteğin gelmesi beklenmektedir.
Güncel tarayıcı desteğini kontrol etmek için Can I Use: css-cascade-6-scope adresini ziyaret edebilirsiniz.
Progressive Enhancement (Kademeli Geliştirme)
Eski tarayıcıları desteklemek için @supports kuralını kullanarak @scope özelliğini güvenle projenize dahil edebilirsiniz:
@supports (background: -webkit-grabbing) or (selector(:scope)) {
@scope (.card) {
/* Modern tarayıcılar için izole stiller */
}
}
Sonuç
CSS @scope, web standartlarının ne kadar olgunlaştığının en büyük kanıtlarından biri. JavaScript kütüphanelerine ve karmaşık derleme araçlarına bağımlı kalmadan, doğrudan CSS'in kendi gücüyle kapsüllenmiş, güvenli ve performanslı stiller yazabilmek frontend dünyasında yeni bir dönemin kapısını aralıyor.
Bir sonraki projenizde, CSS dosyalarınızı karmaşıklaştırmak yerine yerel @scope kuralını denemeye ne dersiniz?
Siz @scope hakkında ne düşünüyorsunuz? CSS-in-JS kütüphanelerinin sonu geliyor olabilir mi? Yorumlarda düşüncelerinizi paylaşın!