Modern CSS'i yeniden keşfetmek
Yıllarca JavaScript ve önişlemciyle çözdüğümüz şeyler artık CSS'in kendisinde: container query, :has() ve yerel nesting.
CSS’i yıllar önce öğrendim ve uzun süre onu öğrendiğim haliyle bildiğimi sandım. Float ile düzen kurardık, dikey ortalamak küçük bir bilmeceydi, bir bileşenin stilini kapsayan koşulları çoğu zaman JavaScript’le ölçerdik. Son birkaç yıl içinde CSS sessizce başka bir dile dönüştü — ve ben bunu, eski alışkanlıklarımla yazmaya devam ettiğim için geç fark ettim. Bu yazı, modern CSS’in bana en çok zaman kazandıran üç eklemesini anlatıyor.
Container query: bağlamı bileşenin kendisi belirler
Yıllarca medya sorgularıyla çalıştık: “ekran şu genişlikteyse şunu yap.” Ama bir bileşenin nasıl görüneceği çoğu zaman ekranın değil, içine konduğu alanın genişliğine bağlıdır. Aynı kart bileşeni hem geniş bir içerik alanında hem de dar bir kenar çubuğunda yaşayabilir.
Container query tam bunu çözüyor:
.kart-listesi {
container-type: inline-size;
}
@container (min-width: 400px) {
.kart { grid-template-columns: auto 1fr; }
}
Artık .kart, ekranın değil .kart-listesi’nin genişliğine göre yerleşiyor. Bu, gerçekten yeniden kullanılabilir bileşen yazmanın önündeki eski bir engeli kaldırdı.
:has(): CSS’in bir “ebeveyn seçicisi” var
Yıllarca CSS’in en çok özlenen özelliği “bir öğeyi içeriğine göre seçmek”ti. “İçinde görsel olan kartları farklı hizala” demek için JavaScript’e ya da fazladan bir sınıfa başvururduk.
.kart:has(img) { grid-template-rows: 200px 1fr; }
.form-alani:has(input:invalid) { border-color: crimson; }
:has() yalnızca bir ebeveyn seçici değil; bir öğeyi herhangi bir alt durumuna göre seçmeyi mümkün kılıyor. Daha önce küçük bir JavaScript dinleyicisiyle yaptığım pek çok şey, artık tek satır CSS.
Yerel nesting: önişlemciye olan bağımlılığın azalması
Sass’ı yıllarca neredeyse yalnızca iki şey için kullandım: değişkenler ve nesting. Değişkenleri CSS custom property’leri çoktan devraldı; nesting ise artık CSS’in kendisinde:
.kart {
padding: 1rem;
& .baslik { font-weight: 600; }
&:hover { box-shadow: 0 4px 12px rgb(0 0 0 / 0.1); }
}
Bu, küçük projelerde bir derleme adımını ve bir bağımlılığı tamamen ortadan kaldırabilir. Her bağımlılık bir bakım yüküdür; dilin kendisi o işi yapıyorsa, aradaki katmanı taşımanın gereği kalmıyor.
Bu özellikleri kademeli kullanmak
Bu üç özelliği kullanırken aklımda tuttuğum bir denge var: tarayıcı desteği. :has(), container query ve yerel nesting artık geniş ölçüde destekleniyor; ama her projenin kullanıcı kitlesi aynı değil. Bu yüzden bunları çoğu zaman kademeli geliştirme (progressive enhancement) mantığıyla kullanıyorum — temel deneyim bu özellikler olmadan da ayakta kalıyor, onlar üzerine yalnızca bir iyileştirme katmanı ekliyor.
Somut bir örnek: container query desteklemeyen eski bir tarayıcıda kart bileşeni, makul bir tek sütunlu düzene düşüyor — kusursuz değil ama tamamen kullanılabilir. Kullanıcı bir şeyin bozuk olduğunu fark etmiyor; yalnızca biraz daha sade bir düzen görüyor. Yeni bir CSS özelliğini benimsemek, onu her yere serpiştirmek değildir; desteklenmediği yerde bile zarif biçimde geri çekildiğinden emin olmaktır. Bu disiplin sayesinde yeni özellikleri “ya hep ya hiç” kararına dönüştürmeden, çıktıkları gün kullanmaya başlayabiliyorum.
Asıl ders
Bu üç eklemenin ortak noktası şu: yıllarca JavaScript, önişlemci ya da fazladan işaretlemeyle çözdüğümüz şeyler artık platformun kendisinde. Buradaki asıl ders teknik değil: bildiğinizi sandığınız bir aracı yeniden öğrenmek. Bir teknolojiyi bir kez öğrenip “tamam, bunu biliyorum” diye rafa kaldırmak kolaydır; ama olgun araçlar bile sessizce gelişir. Yılda bir, çok iyi bildiğimi sandığım bir aracın sürüm notlarını baştan sona okumayı alışkanlık edindim. Çoğu zaman, yıllardır zahmetle yaptığım bir işin artık tek satıra indiğini orada öğreniyorum. Deneyimin bir tuzağı var: sizi, dünyanın siz öğrendiğiniz an donduğuna inandırır.