CSS Kapsayıcı Sorguları: Kullanım Örnekleri ve Taşıma Stratejileri

Yayınlanan: 2022-03-10
Kısa özet ↬ CSS Kapsayıcı sorguları, medya sorgularını hedef öğelerin kendisine yaklaştırır ve bunların neredeyse herhangi bir kapsayıcıya veya düzene uyum sağlamasını sağlar. Bu makalede, CSS kapsayıcı sorgusu temellerini ve bunların aşamalı geliştirme veya çoklu dolgularla bugün nasıl kullanılacağını ele alacağız.

Bir UI öğesi için medya sorguları yazdığımızda, o öğenin ekran boyutlarına bağlı olarak nasıl stillendirildiğini her zaman açıklarız. Bu yaklaşım, hedef öğe medya sorgusunun yanıt verebilirliğinin yalnızca görüntü alanı boyutuna bağlı olması gerektiğinde iyi çalışır. Aşağıdaki duyarlı sayfa düzeni örneğine bir göz atalım.

Duyarlı sayfa düzeni örneği. Soldaki resim, masaüstü düzenini 1280 piksel görünüm alanı genişliğinde gösterir ve sağdaki resim, 568 piksel görünüm alanı genişliğindeki mobil düzeni gösterir.
Duyarlı sayfa düzeni örneği. Soldaki resim, masaüstü düzenini 1280 piksel görünüm alanı genişliğinde gösterir ve sağdaki resim, 568 piksel görünüm alanı genişliğindeki mobil düzeni gösterir. (Büyük önizleme)

Ancak, duyarlı Web Tasarımı (RWD) bir sayfa düzeniyle sınırlı değildir - tek tek UI bileşenleri genellikle, görünüm penceresi boyutlarına bağlı olarak stillerini değiştirebilen medya sorgularına sahiptir.

Duyarlı ürün kartı bileşeni örneği. Soldaki resim 720 piksel görünüm alanı genişliğinde bir bileşeni gösterir ve sağdaki resim 568 piksel görünüm alanı genişliğinde bileşen düzenini gösterir.
Duyarlı ürün kartı bileşeni örneği. Soldaki resim 720 piksel görünüm alanı genişliğinde bir bileşeni gösterir ve sağdaki resim 568 piksel görünüm alanı genişliğinde bileşen düzenini gösterir. (Büyük önizleme)

Önceki ifadede zaten bir sorun fark etmiş olabilirsiniz - bireysel UI bileşen düzeni genellikle yalnızca görünüm penceresi boyutlarına bağlı değildir. Sayfa düzeni, görünüm boyutlarına yakından bağlı bir öğe ve HTML'deki en üstteki öğelerden biri olsa da, UI bileşenleri farklı bağlamlarda ve kapsayıcılarda kullanılabilir. Düşünürseniz, görünüm alanı yalnızca bir kapsayıcıdır ve UI bileşenleri, bileşenin boyutlarını ve düzenini etkileyen stillerle diğer kapların içine yerleştirilebilir.

Üst bölüm 3 sütunlu ızgarada ve alt bölüm listesinde aynı ürün kartı UI bileşenine sahip sayfa düzeni örneği.
Üst bölüm 3 sütunlu ızgarada ve alt bölüm listesinde aynı ürün kartı UI bileşenine sahip sayfa düzeni örneği. (Büyük önizleme)

Hem üst hem de alt bölümlerde aynı ürün kartı bileşeni kullanılmasına rağmen, bileşen stilleri yalnızca görüntü alanı boyutlarına değil, aynı zamanda bağlam ve kapsayıcı CSS özelliklerine (örnekteki ızgara gibi) yerleştirildiği yere de bağlıdır.

Elbette, CSS'mizi, mizanpaj sorununu manuel olarak ele almak için farklı bağlamlar ve kaplar için stil varyasyonlarını destekleyecek şekilde yapılandırabiliriz. En kötü senaryoda, bu varyasyon, kod çoğaltma ve özgünlük sorunlarına yol açacak olan stil geçersiz kılma ile eklenecektir.

 .product-card { /* Default card style */ } .product-card--narrow { /* Style variation for narrow viewport and containers */ } @media screen and (min-width: 569px) { .product-card--wide { /* Style variation for wider viewport and containers */ } }

Ancak bu, uygun bir çözümden ziyade medya sorgularının sınırlamaları için bir geçici çözümdür. UI öğeleri için medya sorguları yazarken, hedef öğenin düzenin bozulmadığı minimum boyutlara sahip olduğu bir kesme noktası için "sihirli" bir görünüm değeri bulmaya çalışıyoruz. Kısacası, "büyülü" bir görüntü alanı boyut değerini eleman boyutları değerine bağlıyoruz . Bu değer genellikle görünüm boyutundan farklıdır ve iç kap boyutları veya düzeni değiştiğinde hatalara eğilimlidir.

Ortam sorgusunun öğe boyutlarına nasıl güvenilir bir şekilde bağlanamayacağına ilişkin örnek. Çeşitli CSS özellikleri, bir kap içindeki öğe boyutlarını etkileyebilir. Bu örnekte, kap dolgusu iki görüntü arasında farklıdır.
Ortam sorgusunun öğe boyutlarına nasıl güvenilir bir şekilde bağlanamayacağına ilişkin örnek. Çeşitli CSS özellikleri, bir kap içindeki öğe boyutlarını etkileyebilir. Bu örnekte, kap dolgusu iki görüntü arasında farklıdır. (Büyük önizleme)

Aşağıdaki örnek tam olarak bu sorunu göstermektedir - duyarlı bir ürün kartı öğesi uygulanmış ve standart bir kullanım durumunda iyi görünse de, öğe boyutlarını etkileyen CSS özelliklerine sahip farklı bir kapsayıcıya taşınırsa bozuk görünüyor. Her ek kullanım durumu, yinelenen koda, kod şişmesine ve bakımı zor kodlara yol açabilecek ek CSS kodunun eklenmesini gerektirir .

Adrian Bece'nin Kalem [Ürün Kartları: Çeşitli Kaplar](https://codepen.io/smashingmag/pen/eYvWVxz) bölümüne bakın.

Adrian Bece'den Kalem Ürün Kartlarına bakın: Çeşitli Kaplar.

Bu, konteyner sorgularının düzeltmeye çalıştığı sorunlardan biridir. Kapsayıcı sorguları, hedef öğe boyutlarına bağlı sorgularla mevcut medya sorguları işlevselliğini genişletir . Bu yaklaşımı kullanmanın üç ana faydası vardır:

  • Kapsayıcı sorgu stilleri, hedef öğenin kendisinin boyutlarına bağlı olarak uygulanır. UI bileşenleri, verilen herhangi bir bağlama veya kapsayıcıya uyum sağlayabilecektir.
  • Geliştiricilerin, bir görünüm alanı medya sorgusunu belirli bir kapsayıcıda veya belirli bir bağlamda UI bileşeninin hedef boyutuna bağlayan bir "sihirli sayı" görünüm boyutu değeri araması gerekmez.
  • Farklı bağlamlar ve kullanım durumları için ek CSS sınıfları veya medya sorguları eklemeye gerek yok.
"İdeal duyarlı web sitesi, birden çok bağlamda hizmet vermek üzere yeniden kullanılabilen esnek, modüler bileşenlerden oluşan bir sistemdir."

— "Konteyner Sorguları: Bir Kez Daha İhlalde", Mat Marquis

Konteyner sorgularına derinlemesine dalmadan önce, tarayıcı desteğini kontrol etmemiz ve tarayıcımızda deneysel özelliği nasıl etkinleştirebileceğimizi görmemiz gerekiyor.

Tarayıcı Desteği

Kapsayıcı sorguları, bu makalenin yazıldığı sırada şu anda Chrome Canary sürümünde bulunan deneysel bir özelliktir. Bu makaledeki CodePen örneklerini takip etmek ve çalıştırmak istiyorsanız, aşağıdaki ayarlar URL'sinde kapsayıcı sorgularını etkinleştirmeniz gerekir.

 chrome://flags/#enable-container-queries
Kapsayıcı sorguları
(Büyük önizleme)

Kapsayıcı sorgularını desteklemeyen bir tarayıcı kullanıyorsanız, CodePen demosunun yanında amaçlanan çalışma örneğini gösteren bir resim sağlanacaktır.

Atlamadan sonra daha fazlası! Aşağıdan okumaya devam edin ↓

Kapsayıcı Sorgularıyla Çalışma

Kapsayıcı sorguları, normal medya sorguları kadar basit değildir. Kapsayıcı sorgularının çalışmasını sağlamak için UI öğemize fazladan bir CSS kodu satırı eklememiz gerekecek, ancak bunun bir nedeni var ve onu daha sonra ele alacağız.

Sınırlama Özelliği

CSS contain özelliği, modern tarayıcıların çoğuna eklenmiştir ve bu makalenin yazıldığı sırada %75 oranında iyi bir tarayıcı desteğine sahiptir. contain özelliği esas olarak, tarayıcıya sayfanın hangi bölümlerinin (alt ağaçların) bağımsız olarak değerlendirilebileceğini ve bir ağaçtaki diğer öğelerdeki değişiklikleri etkilemeyeceğini ima ederek performans optimizasyonu için kullanılır. Bu şekilde, tek bir öğede bir değişiklik meydana gelirse, tarayıcı tüm sayfa yerine yalnızca o kısmı (alt ağaç) yeniden oluşturacaktır. contain özelliği değerleriyle, layout , size veya paint gibi hangi tür çevrelemeyi kullanmak istediğimizi belirtebiliriz.

Kullanılabilir seçenekleri ve kullanım durumlarını çok daha ayrıntılı olarak özetleyen contain özelliği hakkında birçok harika makale var, bu nedenle yalnızca kapsayıcı sorgularıyla ilgili özelliklere odaklanacağım.

Optimizasyon için kullanılan CSS memnuniyet özelliğinin kapsayıcı sorgularıyla ne ilgisi var? Kapsayıcı sorgularının çalışması için, tarayıcının, öğenin alt düzeninde yalnızca o bileşeni yeniden oluşturması gereken bir değişiklik olup olmadığını bilmesi gerekir. Tarayıcı, bileşen oluşturulduğunda veya bileşenin boyutu değiştiğinde, kapsayıcı sorgusundaki kodu eşleşen bileşene uygulamayı bilecektir.

contain​ için layout​ style​ kullanacağız, ancak tarayıcıya değişikliğin gerçekleşeceği eksen hakkında sinyal gönderen ek bir değere de ihtiyacımız olacak.

  • inline-size
    Hat içi eksende muhafaza. Bu değerin önemli ölçüde daha fazla kullanım örneğine sahip olması bekleniyor, bu nedenle ilk olarak uygulanıyor.
  • block-size
    Blok ekseninde muhafaza. Hala geliştirme aşamasındadır ve şu anda mevcut değildir.

contain özelliğinin küçük bir dezavantajı, düzen öğemizin bir contain öğesinin alt öğesi olması gerektiğidir; bu, ek bir iç içe yerleştirme düzeyi eklediğimiz anlamına gelir.

 <section> <article class="card"> <div class="card__wrapper"> <!-- Card content --> </div> </article> </section>
 .card { contain: layout inline-size style; } .card__wrapper { display: grid; grid-gap: 1.5em; grid-template-rows: auto auto; /* ... */ }

Bu değeri daha uzak bir ebeveyn benzeri section nasıl eklemediğimize ve kapsayıcıyı etkilenen öğeye mümkün olduğunca yakın tutmadığımıza dikkat edin.

“Performans, işten kaçınma ve yaptığınız herhangi bir işi mümkün olduğunca verimli hale getirme sanatıdır. Çoğu durumda mesele, tarayıcıya karşı değil, tarayıcıyla çalışmaktır.”

— “Görüntüleme Performansı,” Paul Lewis

Bu yüzden tarayıcıya değişiklik hakkında doğru bir şekilde sinyal vermeliyiz. Uzak bir üst öğeyi bir contain özelliğiyle sarmak ters etki yapabilir ve sayfa performansını olumsuz etkileyebilir. contain özelliğinin kötüye kullanılmasının en kötü senaryolarında, düzen bozulabilir ve tarayıcı onu doğru şekilde oluşturmaz.

Kapsayıcı Sorgusu

Kart elemanı sarmalayıcısına contain özelliği eklendikten sonra bir kapsayıcı sorgusu yazabiliriz. card sınıfına sahip bir öğeye bir contain özelliği ekledik, böylece artık onun alt öğelerinden herhangi birini bir kapsayıcı sorgusuna dahil edebiliriz.

Normal medya sorgularında olduğu gibi, min-width veya max-width özelliklerini kullanarak bir sorgu tanımlamamız ve tüm seçicileri bloğun içine yerleştirmemiz gerekiyor. Ancak, bir kapsayıcı sorgusu tanımlamak için @media yerine @container anahtar sözcüğünü kullanacağız.

 @container (min-width: 568px) { .card__wrapper { align-items: center; grid-gap: 1.5em; grid-template-rows: auto; grid-template-columns: 150px auto; } .card__image { min-width: auto; height: auto; } }

Hem card__wrapper hem de card__image öğesi, tanımlanan contain özelliğine sahip card öğesinin çocuklarıdır. Normal medya sorgularını kapsayıcı sorgularla değiştirdiğimizde, dar kapsayıcılar için ek CSS sınıflarını kaldırdığımızda ve kapsayıcı sorgularını destekleyen bir tarayıcıda CodePen örneğini çalıştırdığımızda aşağıdaki sonucu alıyoruz.

Bu örnekte, görünümü yeniden boyutlandırmıyoruz, ancak resize CSS özelliğinin uygulanmış olduğu <section> kapsayıcı öğesinin kendisini yeniden boyutlandırıyoruz. Bileşen, konteyner boyutlarına bağlı olarak düzenler arasında otomatik olarak geçiş yapar.
Bu örnekte, görünümü yeniden boyutlandırmıyoruz, ancak uygulanan resize CSS özelliğine sahip <section> kapsayıcı öğesinin kendisini yeniden boyutlandırıyoruz. Bileşen, konteyner boyutlarına bağlı olarak düzenler arasında otomatik olarak geçiş yapar. (Büyük önizleme)

Adrian Bece'nin Kalem [Ürün Kartları: Kapsayıcı Sorguları](https://codepen.io/smashingmag/pen/PopmQLV) bölümüne bakın.

Kalem Ürün Kartlarına bakın: Adrian Bece'nin Kapsayıcı Sorguları.

Lütfen kapsayıcı sorgularının şu anda Chrome geliştirici araçlarında görünmediğini ve bunun da kapsayıcı sorgularında hata ayıklamayı biraz zorlaştırdığını unutmayın. Gelecekte tarayıcıya uygun hata ayıklama desteğinin eklenmesi bekleniyor.

Kapsayıcı sorgularının, neredeyse her kapsayıcıya ve düzene uyum sağlayabilen daha sağlam ve yeniden kullanılabilir UI bileşenleri oluşturmamıza nasıl olanak tanıdığını görebilirsiniz. Ancak, kapsayıcı sorguları için uygun tarayıcı desteği, özellikte hala çok uzakta. Aşamalı geliştirme kullanarak kapsayıcı sorguları uygulayıp uygulayamayacağımızı deneyelim ve görelim.

Aşamalı Geliştirme ve Çoklu Dolgular

Bakalım CSS sınıf varyasyonuna ve medya sorgularına bir geri dönüş ekleyebilecek miyiz. Kullanılabilir tarayıcı özelliklerini tespit etmek için CSS özellik sorgularını @supports kuralıyla kullanabiliriz. Ancak, diğer sorguları kontrol edemeyiz, bu nedenle contain: layout inline-size style değeri için bir kontrol eklememiz gerekiyor. inline-size özelliğini destekleyen tarayıcıların da kapsayıcı sorgularını desteklediğini varsaymamız gerekecek.

 /* Check if the inline-size value is supported */ @supports (contain: inline-size) { .card { contain: layout inline-size style; } } /* If the inline-size value is not supported, use media query fallback */ @supports not (contain: inline-size) { @media (min-width: 568px) { /* ... */ } } /* Browser ignores @container if it's not supported */ @container (min-width: 568px) { /* Container query styles */ }

Ancak, aynı stiller hem kapsayıcı sorgusu hem de ortam sorgusu tarafından uygulandığından, bu yaklaşım yinelenen stillere yol açabilir. Aşamalı geliştirme ile kapsayıcı sorguları uygulamaya karar verirseniz, kod bloklarını çoğaltmaktan kaçınmak için SASS gibi bir CSS ön işlemcisi veya PostCSS gibi bir son işlemci kullanmak ve bunun yerine CSS karışımlarını veya başka bir yaklaşımı kullanmak istersiniz.

Adrian Bece'nin Kalem [Ürün Kartları: Aşamalı geliştirme ile Kapsayıcı Sorguları](https://codepen.io/smashingmag/pen/zYZwRXZ) belgesine bakın.

Kalem Ürün Kartlarına bakın: Adrian Bece tarafından aşamalı olarak geliştirilmiş Konteyner Sorguları.

Bu kapsayıcı sorgu spesifikasyonu hâlâ deneysel bir aşamada olduğundan, spesifikasyonun veya uygulamanın gelecekteki sürümlerde değişmeye açık olduğunu akılda tutmak önemlidir.

Alternatif olarak, güvenilir bir geri dönüş sağlamak için çoklu dolguları kullanabilirsiniz. Vurgulamak istediğim, şu anda aktif olarak korunan ve gerekli kapsayıcı sorgu özelliklerini sağlayan iki JavaScript çoklu dolgusu var:

  • cqfill tarafından Jonathan Neal
    CSS ve PostCSS için JavaScript çoklu doldurma
  • react-container-query , Chris Garcia
    React için özel kanca ve bileşen

Medya Sorgularından Kapsayıcı Sorgularına Geçiş

Medya sorguları kullanan mevcut bir projede kapsayıcı sorguları uygulamaya karar verirseniz, HTML ve CSS kodunu yeniden düzenlemeniz gerekir. Bunu, medya sorgularına güvenilir bir geri dönüş sağlarken kapsayıcı sorguları eklemenin en hızlı ve en basit yolu olarak buldum. Bir önceki kart örneğine bir göz atalım.

 <section> <div class="card__wrapper card__wrapper--wide"> <!-- Wide card content --> </div> </section> /* ... */ <aside> <div class="card__wrapper"> <!-- Narrow card content --> </div> </aside>
 .card__wrapper { display: grid; grid-gap: 1.5em; grid-template-rows: auto auto; /* ... */ } .card__image { /* ... */ } @media screen and (min-width: 568px) { .card__wrapper--wide { align-items: center; grid-gap: 1.5em; grid-template-rows: auto; grid-template-columns: 150px auto; } .card__image { /* ... */ } }

İlk olarak, medya sorgusu uygulanan kök HTML öğesini, contain özelliğine sahip bir öğeyle sarın.

 <section> <article class="card"> <div class="card__wrapper"> <!-- Card content --> </div> </article> </section>
 @supports (contain: inline-size) { .card { contain: layout inline-size style; } }

Ardından, bir ortam sorgusunu bir özellik sorgusuna sarın ve bir kapsayıcı sorgusu ekleyin.

 @supports not (contain: inline-size) { @media (min-width: 568px) { .card__wrapper--wide { /* ... */ } .card__image { /* ... */ } } } @container (min-width: 568px) { .card__wrapper { /* Same code as .card__wrapper--wide in media query */ } .card__image { /* Same code as .card__image in media query */ } }

Bu yöntem bazı kod şişkinliği ve yinelenen kodla sonuçlansa da, SASS veya PostCSS kullanarak geliştirme kodunun kopyalanmasını önleyebilirsiniz, böylece CSS kaynak kodunun bakımı yapılabilir kalır.

Kapsayıcı sorguları uygun tarayıcı desteğini aldıktan sonra, @supports not (contain: inline-size) kod bloklarını kaldırmayı ve yalnızca kapsayıcı sorgularını desteklemeye devam etmeyi düşünebilirsiniz.

Stephanie Eckles kısa süre önce çeşitli geçiş stratejilerini kapsayan kapsayıcı sorguları hakkında harika bir makale yayınladı. Konu hakkında daha fazla bilgi için incelemenizi tavsiye ederim.

Kullanım Durumu Senaryoları

Önceki örneklerden gördüğümüz gibi, kapsayıcı sorguları en iyi, kullanılabilir kapsayıcı alanına bağlı olan ve çeşitli bağlamlarda kullanılabilen ve sayfadaki farklı kapsayıcılara eklenebilen bir düzene sahip yeniden kullanılabilirliği yüksek bileşenler için kullanılır.

Diğer örnekler şunları içerir (örnekler, kapsayıcı sorgularını destekleyen bir tarayıcı gerektirir):

  • Kartlar, form öğeleri, afişler vb. gibi modüler bileşenler.
  • Uyarlanabilir düzenler
  • Mobil ve masaüstü için farklı işlevlere sahip sayfalandırma
  • CSS yeniden boyutlandırma ile eğlenceli deneyler

Çözüm

Spesifikasyon uygulandıktan ve tarayıcılarda geniş çapta desteklendikten sonra, kapsayıcı sorguları oyunun kurallarını değiştiren bir özellik haline gelebilir. Geliştiricilerin, uzak ve neredeyse hiç ilişkili olmayan görünüm alanı medya sorgularını kullanmak yerine, sorguları ilgili bileşenlere yaklaştırarak, bileşen düzeyinde sorgular yazmasına olanak tanır. Bu, çeşitli kullanım durumlarına, yerleşimlere ve kapsayıcılara uyum sağlayabilecek daha sağlam, yeniden kullanılabilir ve bakımı yapılabilir bileşenlerle sonuçlanacaktır.

Halihazırda, kapsayıcı sorguları hala erken, deneysel bir aşamadadır ve uygulama değişmeye açıktır. Bugün projelerinizde kapsayıcı sorguları kullanmaya başlamak istiyorsanız, bunları özellik algılama ile aşamalı geliştirme kullanarak eklemeniz veya bir JavaScript çoklu dolgu kullanmanız gerekir. Her iki durum da kodda bir miktar ek yüke neden olacaktır; bu nedenle, bu erken aşamada kapsayıcı sorguları kullanmaya karar verirseniz, özellik geniş çapta desteklendiğinde kodu yeniden düzenlemeyi planladığınızdan emin olun.

Referanslar

  • “Kapsayıcı Sorguları: Hızlı Başlangıç ​​Kılavuzu” David A. Herron
  • "CSS Kapsayıcı Sorgularına Merhaba Deyin", Ahmad Shadeed
  • "Chrome 52'de CSS Kapsama Alanı", Paul Lewis
  • "CSS Özelliği İçererek Tarayıcıların Optimize Edilmesine Yardımcı Oluyor" Rachel Andrew