CSS İç İçe Yerleştirme

En sevdiğimiz CSS ön işlemci özelliklerinden biri artık dile yerleşik olarak sunuluyor: iç içe yerleştirme stili kuralları.

Adam Argyle
Adam Argyle

İç içe yerleştirmeden önce her seçicinin birbirinden ayrı ve açık bir şekilde bildirilmesi gerekiyordu. Bu da tekrara, stil sayfası toplu olmasına ve dağınık bir yazma deneyimine yol açar.

Önce
.nesting {
  color: hotpink;
}

.nesting > .is {
  color: rebeccapurple;
}

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

İç içe yerleştirildikten sonra seçiciler devam edilebilir ve bunlarla ilgili stil kuralları gruplandırılabilir.

Sonra
.nesting {
  color: hotpink;

  > .is {
    color: rebeccapurple;

    > .awesome {
      color: deeppink;
    }
  }
}

Bunu tarayıcıda deneyin.

İç içe yerleştirme, hem seçicileri tekrarlama ihtiyacını azaltarak hem de ilgili öğeler için stil kurallarını birlikte konumlandırarak geliştiricilere yardımcı olur. Ayrıca, stillerin hedefledikleri HTML ile eşleşmesine de yardımcı olabilir. Önceki örnekte bulunan .nesting bileşeni projeden kaldırıldıysa dosyaları ilgili seçici örneklerini aramak yerine tüm grubu silebilirsiniz.

İç içe yerleştirmenin avantajları: - Kuruluş - Dosya boyutunu küçültme - Yeniden düzenleme

İç içe yerleştirme özelliği Chrome 112'den itibaren mevcuttur ve Safari Teknik Önizleme 162'de deneyebilirsiniz.

CSS Nesting'i kullanmaya başlama

Bu gönderinin geri kalanında,seçimleri görselleştirmenize yardımcı olması 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 olur. Çeşitli şekil ve boyutlar seçerek söz dizimi alıştırması yapabilir ve onu iş başında görebilirsiniz.

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

Korumalı alan içinde daireler, üçgenler ve kareler vardır. Bazıları küçük, orta veya büyük olabilir. Diğerleri mavi, pembe veya mor. Hepsi, .demo içeren öğenin içindedir. Aşağıda, hedefleyeceğiniz HTML öğelerinin ö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, başka bir seçicinin bağlamında bir öğe için stiller tanımlamanızı sağlar.

.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 olan öğelere uygulanacağı 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 size sunulan seçeneklerin nedeni daha açık olacaktır.

Çevreleri seçme

Bu ilk örnekte görev, yalnızca demodaki daireleri solduracak ve bulanıklaştıracak stiller eklemektir.

İç içe yerleştirme olmadan, CSS bugün:

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

İç içe yerleştirme 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çta, .demo içindeki .circle sınıfındaki tüm öğeler bulanıklaştırılır ve neredeyse görünmez:

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

Üçgen ve kare seçme

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

Şu anda CSS'yi iç içe yerleştirmeden iki şekilde kullanabilirsiniz:

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

veya :is() ile

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

İç içe yerleştirme ile geçerli iki yöntem vardı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 öğeleri kalır:

Renkli şekiller ızgarasında yalnızca daireler var ve diğer
    şekiller neredeyse hiç görünmez.
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 olmadan, CSS bugün:

.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 ile geçerli iki yöntem vardır:

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

veya

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

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

Renkli ızgarada yalnızca küçük ve orta şekiller görülebilir.
Demoyu deneyin
Bileşik seçiciler ve iç içe yerleştirilmiş bir profesyonel ipucu

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

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

İç içe yerleştirmenin geçerli bir yolu olsa da sonuçlar beklediğiniz öğelerle eşleşmez. Bunun nedeni, & olmadan, birleştirilmiş .lg.triangle, .lg.circle için istenen sonucu belirtmemesi durumunda gerçek sonuç .lg .triangle, .lg .circle; alt seçiciler olacaktır.

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

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

İç içe yerleştirme olmadan, CSS bugün:

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

İç içe yerleştirme ile geçerli iki yöntem vardır:

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

veya

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

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

Rengarenk ızgarada artık tek renkli, yalnızca pembe şekiller gösteriliyor.
Demoyu deneyin
& ile hassas ve esneklik

:not() seçicisini kullanarak .demo hedefini hedeflemek istediğinizi varsayalım. Bunun için & gereklidir:

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

Bu, .demo :not() gerektiren önceki örneğin aksine .demo ve :not() değerlerini .demo:not() olarak oluşturur. Bir :hover etkileşimini iç içe yerleştirmek istediğinizde bu hatırlatıcı çok önemlidir.

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

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

Daha fazla iç içe yerleştirme örneği

İç içe yerleştirme için CSS spesifikasyonu daha fazla örnekle dolu. Örnekler aracılığıyla söz dizimi hakkında daha fazla bilgi edinmek istiyorsanız bu site, çok çeşitli geçerli ve geçersiz örnekleri kapsar.

Sıradaki birkaç örnekte, sunduğu olanakların kapsamını anlamanıza yardımcı olmak için kısaca bir CSS iç içe yerleştirme özelliği anlatılacaktır.

@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ın içine doğrudan yerleştirmek imkanı sayesinde bu dikkat dağınıklığı ortadan kalktı.

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

.card {
  font-size: 1rem;

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

& açıkça kullanılabilir:

.card {
  font-size: 1rem;

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

Bu örnekte, & ile genişletilmiş söz dizimi gösterilmektedir. Ayrıca 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.

Her yerde iç içe yerleştirme

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

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

& sembolü, bir seçici nesnesine (dize değil) başvuruyu temsil eder ve iç içe yerleştirilmiş bir seçicide herhangi bir yere yerleştirilebilir. Hatta birden fazla kez yerleştirilebilir:

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

Bu örnek biraz faydasız olsa da seçici bağlamı tekrarlamanın işe yaradığı durumlar vardır.

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

İç içe yerleştirilmiş birkaç söz dizimi senaryosu vardır. Bunlar, ön işlemcilerde 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 dizeymiş gibi birleştirmek veya eklemek için iç içe yerleştirmeye güvenir. Seçiciler dize olmadığından, nesne referansları olduğundan bu CSS iç içe yerleştirmede işe yaramaz.

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

Daha ayrıntılı bir açıklamayı özelliklerde bulabilirsiniz.

Tricky 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 blokunu göz önünde bulundurun:

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

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

İç içe yerleştirmenin amacının çalışması için, en iç içe yerleştirme olmayan seçici listeleri tarayıcı tarafından :is() ile sarmalanır. Bu sarmalama, seçici listesinin yazılan bağlamlar içinde gruplandırılmasını sağlar. Bu gruplandırmanın (:is(.one, #two)) yan etkisi, parantez içindeki seçiciler içindeki en yüksek puanın kesinliğini dikkate almasıdır. :is() her zaman bu şekilde çalışır, ancak iç içe yerleştirme söz dizimi kullanıldığında sürpriz olabilir. Çünkü bu, tam olarak yazıldığı şekilde değildir. İşin püf noktası özet: Kimlikler ve seçici listeleriyle iç içe yerleştirmek, oldukça yüksek özgünlükteki seçicilere yol açabilir.

Karmaşık örneği net 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çicinin kullanıldığı bir seçici listesinin içine iç içe yerleştirirken lintörlerinize uyarı vermelerini öğretin. Bu seçici listesindeki iç içe yerleştirmelerin belirginliği yüksek olacaktır.

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

Aşağıdaki iç içe yerleştirilmiş CSS blokunu göz önünde bulundurun:

.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 yerleştirilir. Daha fazla ayrıntıyı spesifikasyonda bulabilirsiniz.

Bununla ilgili yollar vardır. Aşağıda, & içindeki üç renk stili sarmalanmıştır. Bu stil, yazarın amaçladığı şekilde basamak sırasını korur. .card öğelerinin rengi kırmızı olur.

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

Hatta, iç içe yerleştirmenin ardından gelen stilleri & ile sarmalamak iyi bir uygulamadır.

.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 harika yolu vardır: iç içe yerleştirme veya iç içe yerleştirme seçici ayrıştırma özelliğini kontrol etmek için @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 sinyalini veren yeşil bir kutu var.

İç içe yerleştirmeyi kullanma:

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

  .no-nesting {
    display: none;
  }
}

@supports kullanılıyor:

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

İş arkadaşım Bramus, bu stratejiyi gösteren harika bir Codepen'e sahip.

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

Geliştirici Araçları'nda şu anda iç içe yerleştirme desteği minimum düzeydedir. Şu anda stillerin Stiller bölmesinde beklendiği gibi temsil edildiğini görebilirsiniz ancak iç içe yerleştirme ve tam seçici bağlamı henüz desteklenmemektedir. Bunu şeffaf ve anlaşılır kılmak için tasarım ve planlarımız var.

Chrome Geliştirici Araçları söz diziminin ekran görüntüsü.

Chrome 113 sürümünde, CSS iç içe yerleştirme için ek destek sunulacaktır. Takip etmeye devam edin.

Gelecek

CSS iç içe yerleştirme yalnızca sürüm 1'dedir. 2. sürümde daha fazla söz dizimsel içerik sunulacak ve ezberlenmesi gereken kural sayısı daha az olacak. İç içe yerleştirmenin ayrıştırılmasının sınırlı olmaması veya yanıltıcı anlara sahip olmaması için çok fazla talep vardır.

İç içe yerleştirme, CSS dilinde yapılan büyük bir geliştirmedir. CSS'nin neredeyse her mimari yöntemi üzerinde yazma etkileri vardır. Sürüm 2'nin etkili bir şekilde tanımlanabilmesi için bu büyük etkinin derinlemesine incelenmesi ve anlaşılması gerekir.

@scope, iç içe yerleştirme ve @layer özelliklerini birlikte kullanan bir demoyu inceleyebilirsiniz. Hepsi çok heyecan verici.

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