CSS İç İçe Yerleştirme

En sevdiğimiz CSS ön işlemci özelliklerinden biri de artık dilin içine yerleştirilmiş: iç içe yerleştirme stili kuralları.

Adem Argyle
Adam Argyle

İç içe yerleştirmeden önce her seçicinin birbirinden ayrı olarak açıkça bildirilmesi gerekiyordu. Bu da tekrarlara, stil sayfalarında yığına neden olur ve dağınık yazma deneyimi sağlar.

Önce
.nesting {
  color: hotpink;
}

.nesting > .is {
  color: rebeccapurple;
}

.nesting > .is > .awesome {
  color: deeppink;
}

İç içe yerleştirme işleminden sonra seçicilere devam edilebilir ve seçicilerle ilgili stil kuralları içlerinde gruplandırılabilir.

Sonra
.nesting {
  color: hotpink;

  > .is {
    color: rebeccapurple;

    > .awesome {
      color: deeppink;
    }
  }
}

Bunu tarayıcıda deneyin.

İç içe yerleştirmek, seçicileri tekrarlama ihtiyacını azaltarak geliştiricilere yardımcı olur ve aynı zamanda ilgili öğelerin stil kurallarını birlikte bulur. Ayrıca stillerin hedefledikleri HTML ile eşleşmesine de yardımcı olabilir. Önceki örnekte .nesting bileşeni projeden kaldırıldıysa ilgili seçici örneklerini bulmak için dosyalarda arama yapmak yerine grubun tamamını silebilirsiniz.

İç içe yerleştirme şu konularda yardımcı olabilir: - Kuruluş - Dosya boyutunu küçültme - Yeniden düzenleme

İç içe yerleştirme özelliği Chrome 112'de kullanılabilir ve Safari Teknik Önizleme 162'de denenebilir.

CSS iç içe yerleştirmeye başlama

Bu yayının geri kalanında,seçimleri görselleştirmenize yardımcı olmak için aşağıdaki demo korumalı alanı kullanılmıştır. Bu varsayılan durumda hiçbir şey seçilmez ve her şey görünür durumda olur. Çeşitli şekilleri ve boyutları seçerek, söz dizimini kullanabilir ve nasıl çalıştığını görebilirsiniz.

Küçük ve büyük daireler, üçgenler ve karelerden oluşan renkli bir ızgara.

Korumalı alanın içinde daireler, üçgenler ve kareler vardır. Bazıları küçük, orta veya büyük olabilir. Diğerleri mavi, pembe veya mordur. Bunların tümü .demo uygulamasını içeren öğenin içindedir. Aşağıda, hedefleyeceğiniz HTML öğelerinin bir önizlemesi verilmiştir.

<div class="demo">
  <div class="sm triangle pink"></div>
  <div class="sm triangle blue"></div>
  <div class="square blue"></div>
  <div class="sm square pink"></div>
  <div class="sm square blue"></div>
  <div class="circle pink"></div>
  …
</div>

İç içe yerleştirme örnekleri

CSS iç içe yerleştirme, bir öğe için başka bir seçicinin bağlamında stil tanımlamanıza olanak tanır.

.parent {
  color: blue;

  .child {
    color: red;
  }
}

Bu örnekte, .child sınıf seçici .parent sınıf seçicinin içine yerleştirilmiştir. Bu, iç içe yerleştirilmiş .child seçicinin yalnızca .parent sınıfına sahip öğelerin alt öğeleri için geçerli olduğu anlamına gelir.

Bu örnek, üst sınıfın nereye yerleştirilmesi gerektiğini açıkça belirtmek için & sembolü kullanılarak da yazılabilir.

.parent {
  color: blue;

  & .child {
    color: red;
  }
}

Bu iki örnek, işlevsel olarak eşdeğerdir ve bu makalede daha gelişmiş örnekler incelendikçe seçenek sahibi olma nedeninizi netleştireceğiz.

Çevreleri seçme

Bu ilk örnekte görev, yalnızca demodaki daireleri karartmak ve bulanıklaştırmak için stiller eklemektir.

İç içe yerleştirme kullanılmadan, bugün CSS'ler:

.demo .circle {
  opacity: .25;
  filter: blur(25px);
}

Yuvalama ile, iki geçerli yol vardır:

/* & is explicitly placed in front of .circle */
.demo {
  & .circle {
    opacity: .25;
    filter: blur(25px);
  }
}

veya

/* & + " " space is added for you */
.demo {
  .circle {
    opacity: .25;
    filter: blur(25px);
  }
}

Sonuç, .demo içinde .circle sınıfı olan tüm öğeler bulanıklaştırılır ve neredeyse görünmez:

Renkli şekillerin ızgarasında artık daireler yok, arka planda çok soluk görünüyorlar.
Demoyu deneyin

Üçgen ve kare seçimi

Bu görev, grup seçici olarak da adlandırılır ve iç içe yerleştirilmiş birden çok öğenin seçilmesini gerektirir.

Bugün CSS'yi iç içe yerleştirmeden iki yöntem kullanabilirsiniz:

.demo .triangle,
.demo .square {
  opacity: .25;
  filter: blur(25px);
}

veya :is() kullanarak

/* grouped with :is() */
.demo :is(.triangle, .square) {
  opacity: .25;
  filter: blur(25px);
}

İç içe yerleştirme yöntemiyle, iki geçerli yöntem şunlardır:

.demo {
  & .triangle,
  & .square {
    opacity: .25;
    filter: blur(25px);
  }
}

veya

.demo {
  .triangle, .square {
    opacity: .25;
    filter: blur(25px);
  }
}

Sonuç, .demo içinde yalnızca .circle öğe kalır:

Renkli şekiller ızgarası yalnızca dairelerden oluşur. Diğer tüm şekiller neredeyse görünmezdir.
Demoyu deneyin

Büyük üçgenler ve daireler seçme

Bu görev, bir bileşik seçici gerektirir. Burada öğelerin seçilebilmesi için her iki sınıfın da mevcut olması gerekir.

İç içe yerleştirme kullanılmadan, bugün CSS'ler:

.demo .lg.triangle,
.demo .lg.square {
  opacity: .25;
  filter: blur(25px);
}

veya

.demo .lg:is(.triangle, .circle) {
  opacity: .25;
  filter: blur(25px);
}

İç içe yerleştirme yöntemiyle, iki geçerli yöntem şunlardır:

.demo {
  .lg.triangle,
  .lg.circle {
    opacity: .25;
    filter: blur(25px);
  }
}

veya

.demo {
  .lg {
    &.triangle,
    &.circle {
      opacity: .25;
      filter: blur(25px);
    }
  }
}

Sonuç, tüm büyük üçgenler ve daireler .demo içinde gizlenir:

Renkli ızgarada yalnızca küçük ve orta boy şekiller görünür.
Demoyu deneyin
Bileşik seçiciler ve iç içe yerleştirmeyle ilgili uzman ipucu

İç içe yerleştirilmiş seçicilerin nasıl birleştirileceğini açıkça gösterdiği için & sembolü sizin arkadaşınızdır. Aşağıdaki örneği inceleyin:

.demo {
  .lg {
    .triangle,
    .circle {
      opacity: .25;
      filter: blur(25px);
    }
  }
}

İç içe yerleştirmek için geçerli bir yöntem olsa da sonuçlar, beklediğiniz öğelerle eşleşmez. Bunun nedeni, birlikte birleştirilmiş .lg.triangle, .lg.circle için istenen sonucu belirtmek üzere & özelliği kullanılmadığında gerçek sonuç .lg .triangle, .lg .circle; alt seçiciler olur.

Pembe olanlar dışındaki tüm şekilleri seçer

Bu görev, öğelerin belirtilen seçiciye sahip olmaması gereken bir olumsuzlama işlevi sözde sınıfı gerektirir.

İç içe yerleştirme kullanılmadan, bugün CSS'ler:

.demo :not(.pink) {
  opacity: .25;
  filter: blur(25px);
}

İç içe yerleştirme yöntemiyle, iki geçerli yöntem şunlardır:

.demo {
  :not(.pink) {
    opacity: .25;
    filter: blur(25px);
  }
}

veya

.demo {
  & :not(.pink) {
    opacity: .25;
    filter: blur(25px);
  }
}

Sonuç, pembe olmayan tüm şekiller .demo içinde gizlenir:

Artık tek renkli olan renkli ızgarada yalnızca pembe şekiller gösteriliyor.
Demoyu deneyin
& ile hassasiyet ve esneklik

:not() seçicisini kullanarak .demo alanını hedeflemek istediğinizi varsayalım. & bunun için zorunludur:

.demo {
  &:not() {
    ...
  }
}

.demo :not() gerektiren bir önceki örneğin aksine, bu işlem .demo ve :not() ile .demo:not() formülünü birleştirmiştir. Bir :hover etkileşimini iç içe yerleştirmek istediğinizde bu hatırlatıcı çok önemlidir.

.demo {
  &:hover {
    /* .demo:hover */
  }

  :hover {
    /* .demo :hover */
  }
}

Diğer iç içe yerleştirme örnekleri

İç içe yerleştirme için CSS spesifikasyonunda daha fazla örnek bulunmaktadır. Örnekler üzerinden söz dizimi hakkında daha fazla bilgi edinmek istiyorsanız çok çeşitli geçerli ve geçersiz örnekler ele alınmaktadır.

Sıradaki birkaç örnekte kısaca bir CSS iç içe yerleştirme özelliği tanıtılacak. Böylece bu özelliğin sunduğu özelliklerin kapsamını kolayca anlayabilirsiniz.

@media'yı iç içe yerleştirme

Bir seçiciyi ve stillerini değiştiren medya sorgusu koşullarını bulmak için stil sayfasının farklı bir alanına geçmek çok dikkat dağıtıcı olabilir. Koşulları doğrudan bağlamın içine yerleştirme özelliği sayesinde bu dikkat dağınıklığı ortadan kalktı.

Söz dizimi kolaylığı açısından, iç içe yerleştirilmiş medya sorgusu yalnızca geçerli seçici bağlamı için stilleri değiştiriyorsa minimum söz dizimi kullanılabilir.

.card {
  font-size: 1rem;

  @media (width >= 1024px) {
    font-size: 1.25rem;
  }
}

& açık bir şekilde kullanılarak da kullanılabilir:

.card {
  font-size: 1rem;

  @media (width >= 1024px) {
    &.large {
      font-size: 1.25rem;
    }
  }
}

Bu örnekte, & ile genişletilmiş söz dizimi gösterilmektedir. Aynı zamanda ek iç içe yerleştirme özelliklerinin çalışmaya devam ettiğini göstermek için .large kartları hedeflenmektedir.

@kuralları iç içe yerleştirme hakkında daha fazla bilgi edinin.

Herhangi bir yerde iç içe yerleştirme

Bu noktaya kadarki tüm örnekler devam ettirilmiştir veya önceki bir bağlama eklenmiştir. Gerekirse bağlamı tamamen değiştirebilir veya yeniden düzenleyebilirsiniz.

.card {
  .featured & {
    /* .featured .card */
  }
}

& simgesi, bir seçici nesnesine (dize değil) yapılan referansı temsil eder ve iç içe yerleştirilmiş bir seçicide herhangi bir yere yerleştirilebilir. Hatta birden çok kez yerleştirilebilir:

.card {
  .featured & & & {
    /* .featured .card .card .card */
  }
}

Bu örnek biraz işe yaramaz görünse de, seçici bağlamını tekrar etmenin kullanışlı olduğu durumlar vardır.

Geçersiz iç içe yerleştirme örnekleri

Bazı iç içe yerleştirme söz dizimi senaryoları geçersizdir ve ön işlemcilere iç içe yerleştiriyorsanız sizi şaşırtabilir.

İç içe yerleştirme ve birleştirme

Birçok CSS sınıfı adlandırma kuralı, seçicileri dizelermiş gibi birbirine bağlayabilmesi veya ekleyebilmesi için iç içe yerleştirmeye bağlıdır. Seçiciler dize olmadığından ve nesne referansları olduğundan bu, CSS iç içe yerleştirme işleminde çalışmaz.

.card {
  &--header {
    /* is not equal to ".card--header" */
  }
}

Daha ayrıntılı bilgiyi özellikte bulabilirsiniz.

Kolay iç içe yerleştirme örneği

Seçici listeleri ve :is() içinde iç içe yerleştirme

Aşağıdaki iç içe yerleştirilmiş CSS bloğunu düşünün:

.one, #two {
  .three {
    /* some styles */
  }
}

Bu, bir seçici listesiyle başlayan ve daha fazla iç içe yerleştirmeye devam eden ilk örnektir. Önceki örnekler yalnızca seçici listesiyle sona ermişti. Bu iç içe yerleştirme örneğinde geçersiz bir şey yoktur, ancak seçici listelerinin içine, özellikle de kimlik seçici içerenlere iç içe yerleştirme ile ilgili yanıltıcı olabilecek bir uygulama ayrıntısı mevcuttur.

İç içe yerleştirmenin amacının çalışması için en içte iç içe yerleştirme olmayan seçici listeleri, tarayıcı tarafından :is() ile sarmalanır. Bu sarmalama, yazılan bağlamlarda seçici listesinin gruplandırmasını korur. Bu gruplamanın (:is(.one, #two)) yan etkisi, parantez içindeki seçiciler içinde bulunan en yüksek puanın belirginliğini benimsemesidir. :is() her zaman bu şekilde çalışır ancak iç içe geçme söz dizimi kullanılırken şaşırtıcı olabilir, çünkü tam olarak bu şekilde yazılmamıştır. Kısaca özetleyelim. Kimlikler ve seçici listeleriyle iç içe yerleştirmek, doğruluk düzeyi yüksek seçicilere yol açabilir.

Karmaşık örneği açık bir şekilde özetlemek gerekirse, önceki iç içe yerleştirme bloğu dokümana şu şekilde uygulanacaktır:

:is(.one, #two) .three {
  /* some styles */
}

Kimlik seçici kullanan bir seçici listesinin içine iç içe yerleştirildiğinde gözünüzü açık tutun veya linçerlerinize uyarı öğretin. Bu seçici listesinin içindeki tüm iç içe yerleştirmelerin kesinliği yüksek olacaktır.

İç içe yerleştirme ve bildirimleri karıştırma

Aşağıdaki iç içe yerleştirilmiş CSS bloğunu düşünün:

.card {
  color: green;
  & { color: blue; }
  color: red;
}

.card öğelerinin rengi blue olacak.

Karışık stil bildirimleri, herhangi bir iç içe yerleştirme gerçekleşmeden önce yazılmış gibi en üste yükseltilir. Spesifikasyonda daha fazla bilgi bulabilirsiniz.

Bu konuda çeşitli yöntemler vardır. Aşağıda, & metnindeki üç renk stili ele alınmıştır. Bu stilde, yazarın amaçladığı şekilde basamak sırası korunur. .card öğelerinin rengi kırmızı olur.

.card {
  color: green;
  & { color: blue; }
  & { color: red; }
}

Aslında, & ile iç içe yerleştirmenin ardından gelen stilleri sarmalamanız önerilir.

.card {
  color: green;

  @media (prefers-color-scheme: dark) {
    color: lightgreen;
  }

  & {
    aspect-ratio: 4/3;
  }
}

Özellik algılama

CSS iç içe yerleştirmeyi algılamanın iki etkili yolu vardır: İç içe yerleştirme seçicisi ayrıştırma özelliğini kontrol etmek için iç içe yerleştirme veya @supports kullanma

Tarayıcınızın CSS iç içe yerleştirmeyi destekleyip desteklemediğini soran Bramus Codepen demosunun ekran görüntüsü. Bu sorunun altında, destek ekibini işaret eden yeşil bir kutu yer alır.

İç içe yerleştirmeyi kullanma:

html {
  .has-nesting {
    display: block;
  }

  .no-nesting {
    display: none;
  }
}

@supports kullanılarak:

@supports (selector(&)) {
  /* nesting parsing available */
}

İş arkadaşım Bramus'un bu stratejiyi gösteren harika bir Codepen var.

Chrome Geliştirici Araçları ile hata ayıklama

Geliştirici Araçları'nda iç içe yerleştirme için şu anda sunulan destek minimum düzeydedir. Şu anda stillerin Stiller bölmesinde beklendiği gibi temsil edildiğini bulabilirsiniz, ancak iç içe yerleştirmenin ve tam seçici içeriğinin izlenmesi henüz desteklenmemektedir. Bunu şeffaf ve anlaşılır hale getirecek tasarım ve planlarımız var.

Chrome DevTools iç içe yerleştirme söz diziminin ekran görüntüsü.

Chrome 113, CSS iç içe yerleştirme için ek destek sunmayı planlamaktadır. Takip etmeye devam edin.

Gelecek

CSS İç İçe Yerleştirme yalnızca sürüm 1'dedir. Sürüm 2'de daha fazla söz dizimsel şeker sunulacak ve ezberlenmesi gereken daha az kural bulunacaktır. İç içe yerleştirmenin ayrıştırılmaması veya yanıltıcı anlar yaşanmaması için çok fazla talep var.

İç içe yerleştirme, CSS dilinde yapılan önemli bir geliştirmedir. CSS'nin neredeyse her mimari yönünü etkiliyor. Sürüm 2 etkili bir şekilde belirtilmeden önce bu büyük etkinin derinlemesine araştırılması ve anlaşılması gerekir.

Son olarak, @scope, iç içe yerleştirme ve @layer öğelerinin birlikte kullanıldığı bir demoyu burada bulabilirsiniz. Her şey çok heyecan verici.

Gri arka plan üzerinde açık renk bir kart. Kartta bir başlık ve metin, birkaç işlem düğmesi ve siber punk tarzı bir resim bulunuyor.