
Fri Sep 18 2026

Selam! Bugün Container Queries'i tanıyalım ve neden Media Queries'den farklı (ve çoğu zaman daha güçlü) olduğunu keşfedelim 🚀
| Özellik | Media Queries | Container Queries |
|---|---|---|
| Referans noktası | Viewport | Kapsayıcı (container) |
| Esneklik | Sayfa genelinde | Bileşen bazında |
| Yeniden kullanım | Zor (global stiller) | Kolay (izole stiller) |
/* Kapsayıcıyı tanımla */
.card-container {
container-type: inline-size; /* genişliğe göre sorgula */
container-name: card;
}
/* Kapsayıcı 400px'den genişse iki sütun */
@container card (min-width: 400px) {
.card {
display: grid;
grid-template-columns: 1fr 1fr;
}
}
/* Dar kapsayıcıda tek sütun */
@container card (max-width: 399px) {
.card {
display: block;
}
}
Ne oluyor burada?
.card-container bir container olur.@container card (min-width: 400px) kuralı, o kapsayıcının genişliği 400 px'i geçtiğinde devreye girer..card bileşeni, yan menüde dar, ana alanda geniş olsa bile kendi kapsayıcısına göre düzenlenir 🎉Hadi bir sonraki bölümde nasıl tanıyacağımızı ve tarayıcı desteğini inceleyelim! 🚀
Hadi gelin, container queries'in sihrini birlikte keşfedelim 🎩✨
Media query'ler viewport'a bakar, hakikaten. Ama container query, "Benim kapsayıcım ne kadar geniş?" diye sorar. Yani bir öğe, kendi ebeveyninin (container'ının) boyutuna göre karar verir. Bu, bileşen tabanlı tasarımda devrim niteliğinde 🚀
İki adım var:
container-type (veya kısaca container)@container kuralı ile.card-container {
container: inline-size; /* veya: container-type: inline-size; */
/* artık bu eleman bir "container" sorgulama kaynağı */
}
@container (inline-size >= 300px) {
.card {
display: flex;
gap: 1rem;
padding: 1.5rem;
}
.card__title {
font-size: 1.25rem;
}
}
Ne oluyor burada?
.card-container artık bir container — sorgulanabilir bir referans noktası.@container (inline-size >= 300px): "Eğer bu container'ın inline boyutu (yani yazı yönündeki genişlik) 300px veya daha fazlaysa..." demek..card stilleri sadece o koşul sağlandığında uygulanır.💡
inline-sizeyerinesizeda kullanabilirsiniz (hem inline hem block boyutunu sorgular). Ama çoğu pratikteinline-sizeyeterli — ve performanslıdır.
| Özellik | @media |
@container |
|---|---|---|
| Kaynak | Viewport (tarayıcı penceresi) | Belirli bir kapsayıcı elementi |
| Kapsam | Sayfa geneli | Sadece o container'ın içindeki elemanlar |
| Bileşen izolasyonu | ❌ Zor | ✅ Doğal |
| Yeniden kullanım | Sınırlı | Çok yüksek |
Container query kullanmadan önce container tanımını unutmayın! Sık yapılan hata: @container yazıp container-type atamamak. Tarayıcı "Hangi container?" diyecektir 🤷♂️
/* ❌ Yanlış — container tanımı yok */
@container (inline-size >= 400px) { ... }
/* ✅ Doğru — önce container tanımla */
.sidebar { container: inline-size; }
@container (inline-size >= 400px) { ... }
Hazırsan bir sonraki bölümde gerçek bir kart bileşeni üzerinde container query'lerin nasıl hayat kurtardığını görelim 👇
Hazırsan bu kısımda container queries ile media queries karıştırıldığında neler oluyor, ona bir göz atalım 🎯
@media / @container sözdizimiyle başlar, bu yüzden kopyala‑yapıştır yapmaya çok cazip geliyor.| Hata | Ne oluyor? | Doğru yaklaşım |
|---|---|---|
Tek bir @media ile tüm bileşenleri kontrol etmek |
Sayfa boyutu değiştiğinde her bileşen aynı anda yeniden düzenlenir → beklenmedik kaymalar, boşluklar. | Her bileşen için kendi container’ına özel @container yaz. |
| Viewport’u tek referans almak (geçici çözüm) | Mobilde güzel görünse de, yan yana iki kart olduğunda biri daralır, diğeri boşluğa kapılır. | Container’ın kendi genişliğine göre stiller ver. |
| Statik breakpoint’ler sabitlemek | Yeni bir bileşen eklendiğinde eski breakpoint’ler bozulur, bakım kabusu. | Fluid (esnek) tasarım + container query → bileşen kendi içindeki alana uyar. |
@media (max-width: 600px) kopyalayıp @container yapmak |
Container 600 px’den küçülse bile, viewport hâlâ büyükse stiller uygulanmaz. | Container’ın gerçek boyutunu sorgula: @container (max-width: 600px) |
/* ❌ Yanlış: Tüm sayfa için tek media query */
@media (max-width: 600px) {
.card { font-size: 1rem; }
}
/* ✅ Doğru: Her kart kendi container’ına bakar */
.card-container {
container-type: inline-size;
}
@container (max-width: 400px) {
.card { font-size: 0.9rem; }
}
Ne değişti?
.card-container artık kendi genişliğini dinliyor.container-type: inline-size; (veya size için her iki boyut).container-name: card; @container card (max-width: 400px) { … }.@media yedeği koy, ama asıl mantık container’da olsun.Hadi şimdi kendi projende bir tane container query yazıp farkı hisset! 🚀
Hazırsan bu deseni adım adım inceleyelim 🎯
CSS’de bir elementin “konteyner” olduğunu bildirmek için container-type (veya kısaca container) özelliğini kullanırız.
Genelde inline‑size (yani genişlik) yeterlidir.
.card {
container: inline-size; /* ya da container-type: inline-size; */
}
Ne oluyor?
.card artık kendi içindeki child’lar için bir container query kaynağı olur. Tarayıcı, .card’ın genişliğini izler ve @container kuralları bu genişliğe göre tetiklenir.
@container ile uyarlamalar yazŞimdi container’ın genişliği 300px’i geçtiğinde başlık boyutunu büyütelim.
@container (inline-size >= 300px) {
.title {
font-size: 1.5rem;
}
}
Nasıl çalışıyor?
.card’ın inline-size’ını sürekli ölçer..card-inner)Bazen kartın içerik genişliğine göre kendi düzenini değiştirmek isteriz.
Örneğin, .card-inner içindeki .media ve .content yan yana ya da alt alta dursun.
.card-inner {
display: flex;
flex-direction: column; /* varsayılan: dikey */
gap: 1rem;
}
@container (inline-size >= 400px) {
.card-inner {
flex-direction: row; /* yatay dizilim */
align-items: center;
}
}
Bu sayede ne oluyor?
Projenizde utility‑first bir yaklaşım varsa (Tailwind, UnoCSS vb.) container query’leri de utility olarak yazabilirsiniz.
<div class="card container-inline">
<div class="card-inner flex flex-col gap-4 @container-[inline-size>=400px]:flex-row @container-[inline-size>=400px]:items-center">
<img class="media" src="..." alt="...">
<div class="content">
<h2 class="title">Başlık</h2>
<p class="text">Açıklama metni...</p>
</div>
</div>
</div>
container-inline → container-type: inline-size;@container-[inline-size>=400px]:flex-row → container 400px’i geçince flex-direction: row; uygular.Avantaj: HTML’de tek yerde hem container tanımı hem de responsive davranışları görürsünüz. Kod tekrarı azalır, okunabilirlik artar ✅
| Adım | Ne Yapıyor? |
|---|---|
| Container tanımla | .card { container: inline-size; } |
| Koşul yaz | @container (inline-size >= 300px) { … } |
| İçerik düzeni | .card-inner + @container ile flex-direction değiştir |
| Utility ile birleştir | HTML sınıflarında @container-[…] sözdizimi kullan |
Bu desen sayesinde komponent bazlı, bağlam duyarlı ve bakımı kolay stiller yazarsınız. Container query’ler artık modern tarayıcılarda (%95+ destek) güvenle kullanılabilir — deneyin, farkı hissedeceksiniz! 🚀
Hazırsan hemen koda geçelim. Önce HTML iskeletini oluşturup, sonra CSS ile container query’yi ekleyeceğiz. Adım adım gidersek kafası karışmaz 🎯
<article class="card">
<h2 class="title">Başlık</h2>
<p class="content">
Bu kart, içeriğinin genişliğine göre kendini ayarlar.
Container queries sayesinde medya sorgusuna ihtiyaç duymadan
bileşen seviyesinde responsive davranır.
</p>
</article>
<article class="card"> → kartımızın container olacak kök elemanı.title ve .content → içindekiler, container’ın boyutuna göre şekillenecek/* 1️⃣ Kartı bir container yapıyoruz */
.card {
container-type: inline-size; /* inline‑size = genişlik bazlı */
container-name: card; /* isim verince daha okunaklı olur */
border: 1px solid #ddd;
border-radius: 8px;
padding: 1rem;
background: #fafafa;
}
/* 2️⃣ 300 px ve üzeri genişlikte title büyüsün */
@container card (inline-size >= 300px) {
.title {
font-size: 1.5rem;
font-weight: 700;
}
}
/* 3️⃣ Küçük ekranlarda biraz daha kompakt */
@container card (inline-size < 300px) {
.title {
font-size: 1.1rem;
font-weight: 500;
}
.content {
font-size: 0.9rem;
}
}
Ne oluyor burada?
container-type: inline-size → .card artık container query için bir referans noktası.@container card (inline-size >= 300px) → kartın iç genişliği 300 px’i geçtiğinde .title’ın font‑size’ı 1.5 rem’e çıkar.< 300px) da daha küçük bir tipografi uyguluyoruz. Böylece kart kendi boyutuna göre karar veriyor, sayfa geneli değil 🙌index.html dosyasına yapıştır..card elementinin genişliğini elle değiştir (ör. width: 250px → width: 350px)..title yazı boyutunun anında değiştiğini göreceksin ✨İpucu: Container queries, bileşen tabanlı tasarımda medya sorgusundan kurtulmanı sağlar. Kartı nereye koyarsan koy, kendi içinde responsive olur 🛠
Özetle:
<article class="card">…</article>.card { container-type: inline-size; container-name: card; }Şimdi sen de kendi kart bileşenine container query ekleyip, farklı genişliklerde nasıl davrandığını deneyebilirsin. Keyifli kodlamalar! 🚀
Container query'ler harika bir araç ama yanlış kullanıldığında beklemediğiniz sürprizlerle karşılaşabilirsiniz 🎯. Ben de başlangıçta birkaç kez düşündüm, hadi en yaygın hataları ve nasıl kaçınacağınızı konuşalım.
En klasik hata: container-type özelliğini parent element'e değil, child element'e vermek.
/* ❌ YANLIŞ — child'e verilmiş */
.card {
container-type: inline-size;
}
/* ✅ DOĞRU — parent'e verilmeli */
.card-container {
container-type: inline-size;
}
Ne oluyor burada? Container query, ancestor (ata) elementte tanımlanmalı. Child element kendini container olarak tanımlamaz; onun boyutunu izleyen taraf olur.
container-type için iki ana değer var:
| Değer | Ne Zaman Kullanılır? |
|---|---|
inline-size |
Genişlik (width) bazlı sorgulama — en yaygın |
size |
Hem genişlik hem yükseklik — performans maliyeti var |
/* ❌ Gereksiz yere 'size' kullanmak */
.sidebar {
container-type: size; /* Yükseklik de izleniyor, maliyetli */
}
/* ✅ Genelde 'inline-size' yeterli */
.sidebar {
container-type: inline-size;
}
Püf noktası: Sadece genişlik sorguluyorsan inline-size yeterli. size tarayıcının layout hesaplamasını yavaşlatabilir ⚡.
Container query'ler modern tarayıcılarda destekleniyor ama eski sürümlerde (ör. Safari 15-, Firefox 105-) çalışmaz.
/* Fallback: media query ile yedek plan */
.card {
/* Varsayılan stiller */
padding: 1rem;
}
/* Modern tarayıcılar için container query */
@container (min-width: 400px) {
.card {
padding: 2rem;
}
}
/* Eski tarayıcılar için media query fallback */
@media (min-width: 768px) {
.card {
padding: 2rem;
}
}
Kural: Önce baseline (varsayılan) stilleri yaz, sonra @container ile enhance et, en son @media ile geniş ekran fallback'i ekle 🛡.
Tarayıcı konsolunda container query'nin tanınmadığını görürsen şuna benzer bir çıktı alırsın:
[Container Query] Unsupported at-rule: @container (min-width: 400px)
Bu genelde tarayıcı sürümü eski demektir. Chrome DevTools'da Elements panelinde container element'i seçiliyken, Styles sekmesinin altında "Container" badge'i görmüyorsan container-type tanımsızdır ❌.
Hızlı kontrol listesi:
container-type verildi mi?@container kuralı doğru syntax'ta mı? (@container (min-width: 400px))@container sidebar (min-width: 300px) — hangi container'ı hedeflediğin bell olur.container-name + container-type shorthand: container: sidebar / inline-size;style="container-type: inline-size") çalışmaz — CSS dosyasında veya <style> bloğunda olmalı.Hazırsan bir sonraki bölümde gerçek bir proje örneğiyle container query'leri baştan sona kuracağız 🚀.
Hazırsanız container queries dünyasına bir adım daha atalım 🚀
Artık viewport boyutuna bakmak yerine, bileşenin kendi kapsayıcısına odaklanıyoruz. İşte bu noktada inline-size ve block-size devreye giriyor.
inline-size / block-size? 🎯width / height yerine mantıksal boyutlar sunarlar → daha az sürpriz, daha tutarlı davranış.size (hem inline hem block) ya da tek boyutlu inline-size / block-size seçebilirsiniz.| Container Type | Ne Yapar? |
|---|---|
size |
Hem inline hem block boyutlarını izler. |
inline-size |
Sadece inline (yatay) boyutu takip eder. |
block-size |
Sadece block (dikey) boyutu takip eder. |
İpucu: Çoğu bileşen için
inline-sizeyeterlidir; dikey akış önemliyseblock-sizeekleyin.
/* Kapsayıcıyı tanımlıyoruz */
.card-container {
container-type: inline-size; /* ya da: size / block-size */
container-name: card; /* isim vererek hedefleme kolaylaşır */
}
/* Container query: kart 350px'den genişse düzeni değiştir */
@container card (inline-size >= 350px) {
.card {
display: flex;
gap: 1rem;
align-items: center;
}
.card__image {
width: 120px;
flex-shrink: 0;
}
}
/* İsterseniz block-size ile de kontrol edebilirsiniz */
@container card (block-size >= 200px) {
.card__description {
font-size: 1.1rem;
line-height: 1.5;
}
}
container-type: inline-size → Tarayıcı, .card-container elementinin inline boyutunu izlemeye başlar.@container card (inline-size >= 350px) → Kapsayıcı 350 px'i geçtiğinde içindeki stiller devreye girer.block-size sorgusu → Dikey alan büyüdüğünde (ör. accordion açıldığında) tipografi veya boşluk ayarlanabilir.container-type tanımlandığı elementin çocukları için geçerlidir.size kullanırsanız her iki eksen de izlenir → performans hafifçe artar, ihtiyacınız yoksa inline-size yeterli.Özetle: Viewport'a bağlı statik @media sorgularından kurtulup, bileşenin kendi bağlamına göre tepki veren stiller yazıyoruz. inline-size / block-size ile mantıksal boyutları takip etmek, hem RTL/LTR hem de dikey yazım senaryolarında hayat kurtarıyor 🎉
Container queries, bir bileşenin kendi kapsayıcısının boyutuna göre stillendirilmesini sağlar.
Bu sayede sayfa geneli @media sorgularına bağlı kalmadan, bileşen kendi bağlamında esnek olur 🎯.
Aşağıda hem HTML hem CSS kodunu paylaşıyorum.
Navbar, container-type: inline-size ile bir container olur; menü öğeleri container-query sayesinde genişlik değiştikçe yakınlaştırılır veya açılır.
<nav class="navbar" role="navigation" aria-label="Ana menü">
<div class="navbar__brand">Marka</div>
<ul class="navbar__list">
<li><a href="#">Ana Sayfa</a></li>
<li><a href="#">Ürünler</a></li>
<li><a href="#">Hakkımızda</a></li>
<li><a href="#">İletişim</a></li>
</ul>
</nav>
/* 1️⃣ Navbar'ı bir container yap */
.navbar {
container-type: inline-size; /* genişlik bazlı sorgu */
container-name: navbar; /* isim verip daha net hedefleyelim */
display: flex;
align-items: center;
justify-content: space-between;
padding: 0.75rem 1rem;
background: #1f2937;
color: #fff;
}
/* 2️⃣ Varsayılan (geniş) düzen – yatay liste */
.navbar__list {
display: flex;
gap: 1.5rem;
list-style: none;
margin: 0;
}
/* 3️⃣ Kapsayıcı 600px altına düştüğünde: dikey, daraltılmış menü */
@container navbar (max-width: 600px) {
.navbar__list {
flex-direction: column;
gap: 0.5rem;
position: absolute;
top: 100%;
left: 0;
right: 0;
background: #111827;
padding: 1rem;
border-top: 1px solid #374151;
}
.navbar__list a {
display: block;
padding: 0.5rem 0;
}
}
/* 4️⃣ Çok dar alanlarda (ör. 350px) ikonlu hamburger menüye geçiş */
@container navbar (max-width: 350px) {
.navbar__list {
display: none; /* gizle, JS ile aç/kapa yapabilirsin */
}
.navbar__toggle {
display: block; /* hamburger butonu görünür */
}
}
Bu sayede ne oluyor?
@media sorgusu yazmadık; her şey kendi kapsayıcısına göre halledildi 🛠.container-type: inline-size çoğu durumda yeterlidir; size (her iki boyut) performans maliyeti getirebilir.container-name vermek, iç içe container’larda hangi kapsayıcıyı hedeflediğinizi netleştirir..flex, .gap-4 vb.) container query içinde override ederek sistematik bir yaklaşıma ulaşırsınız.Hazırsan bir sonraki adımda bu pattern’i grid tabanlı kart bileşenlerine nasıl taşıyacağımızı görelim 🚀.
Hazırsan başlayalım! Container Queries artık modern tarayıcılarda native destekleniyor ama hala eski sürümlerde ya da özel bir stratejiyle polyfill kullanmak isteyebilirsiniz. İşte projenize sorunsuz eklemek için izleyebileceğiniz küçük bir yol haritası:
container-type, container-name ve @container sözdizimini ezberlemek yerine pratik yapın.Eski tarayıcılar için container-query-polyfill paketini ekleyebilirsiniz. Webpack / Vite kullanıyorsanız style-loader ile CSS’inize otomatik enjekte edebilirsiniz.
// scripts/add-container-polyfill.js
const fs = require('fs');
const path = require('path');
// 1️⃣ Polyfill dosyasını indir (npm i container-query-polyfill)
const polyfillPath = path.resolve(
__dirname,
'../node_modules/container-query-polyfill/dist/container-query-polyfill.global.js'
);
// 2️⃣ Ana CSS/JS giriş dosyanızı bulun
const entryFile = path.resolve(__dirname, '../src/index.js'); // veya main.js
// 3️⃣ Polyfill'i en başa ekle
const polyfillCode = fs.readFileSync(polyfillPath, 'utf8');
const entryCode = fs.readFileSync(entryFile, 'utf8');
if (!entryCode.includes('container-query-polyfill')) {
const newEntry = `${polyfillCode}\n${entryCode}`;
fs.writeFileSync(entryFile, newEntry);
console.log('✅ Polyfill başarıyla eklendi!');
} else {
console.log('ℹ️ Polyfill zaten mevcut, atlandı.');
}
Nasıl çalışıyor?
npm i container-query-polyfill ile paketi kurun.package.json içindeki prepare ya da dev scriptine ekleyin:"scripts": {
"dev": "node scripts/add-container-polyfill.js && vite",
"build": "node scripts/add-container-polyfill.js && vite build"
}
Böylece her npm run dev / npm run build çalıştığında polyfill otomatik enjekte edilir. 🎉
container-type: inline-size tanımlayın.Container Queries artık production-ready. Küçük bir bileşenden başlayın, polyfill’i bir kez ekleyin ve tarayıcı desteği arttıkça native kullanıma geçin. Kodunuz daha modüler, bakımı daha kolay ve tasarım sisteminiz gerçekten responsive hale gelecek.
Hadi, şimdi bir tane kart bileşeni yazıp @container kuralını deneyin! 🚀
Arkadaşlar, uzun bir yol katettik. Container queries'i tanıdık, nasıl çalıştığını anladık, gerçek hayat senaryolarında nasıl hayat kurtardığını gördük. Şimdi durup bir nefes alıp, neden bu kadar önemli olduğunu özetleyelim.
Önce: "Bu kart 320px'te tek sütun, 768px'te iki sütun, 1024px'te üç sütun olmalı — ama sidebar'da nasıl davranacak?"
Sonra: "Bu kart, kapsayıcısı 300px altındaysa dikey, 300-500px arasıysa yatay, 500px üzeriyse grid modunda gelsin."
Fark hissettiniz mi? Karar mekanizması bileşene ait. Bu, hem geliştirici deneyimini (DX) hem de tasarım tutarlılığını aynı anda yükseltiyor.
Container queries sadece bir CSS özelliği değil — bileşen odaklı düşünmenin tarayıcı tarafındaki yansıması. Artık "sayfa düzeni" değil, "bileşen davranışı" kodluyoruz. Bu zihniyet değişimi, frontend mimarimizi kökten şeffaflaştırıyor.
Hazırsan bu felsefeyi bir sonraki projene taşıyalım. Kodunuzun, tasarımınızın ve ekibiniz için ne kadar rahatlatıcı olacağını göreceksiniz. 🚀
Mutlu kodlamalar!
Bu içerik tamamen yapay zeka destekli otomasyon sistemi ile üretilmiştir.
All rights reserved