CSS media query, bir stil bloğunun yalnızca belirli koşullar sağlandığında uygulanmasını sağlayan sorgudur. @media kuralına bir sorgu ve bir kural bloğu verirsiniz; tarayıcı sorguyu sayfanın görüntülendiği cihaza ve ortama göre değerlendirir, sonuç doğruysa bloğun içindeki kurallar devreye girer, yanlışsa blok hiç yokmuş gibi davranılır. Sorgu ekran genişliğini, yönünü, giriş aygıtının fareyle üzerine gelmeyi destekleyip desteklemediğini ya da kullanıcının hareketin azaltılmasını isteyip istemediğini sınayabilir.

Bu yazı yalnızca @media sözdizimine odaklanıyor: medya türleri, medya özellikleri, aralık (range) yazımı, and, not, only, or ve virgül operatörleri, yazdırma stilleri ve sık yapılan hatalar. Duyarlı (responsive) tasarım kavramı, viewport meta etiketi, kırılma noktası seçimi ve srcset konuları mobil uyumluluk yazısında anlatılıyor. Bir bileşeni ekrana göre değil de kapsayıcısına göre biçimlendirmek istiyorsanız container queries yazısına geçebilirsiniz.

@media kuralının yapısı

MDN'ye göre bir media query üç parçadan oluşur: isteğe bağlı bir medya türü, sıfır ya da daha fazla medya özelliği ifadesi ve bunları birleştiren mantıksal operatörler. Sorgu, belirtilmişse medya türü cihazla eşleştiğinde ve tüm özellik ifadeleri doğru olduğunda doğru sayılır. Sorgular büyük küçük harfe duyarlı değildir. Tanınmayan bir medya türü içeren sorgu her zaman yanlıştır.

css
/* En üst düzeyde */
@media screen and (width >= 900px) {
  article {
    padding: 1rem 3rem;
  }
}

/* Başka bir koşullu grup kuralının içinde */
@supports (display: flex) {
  @media screen and (width >= 900px) {
    article {
      display: flex;
    }
  }
}

Örnekteki ilk kural yalnızca ekran türündeki cihazlarda ve viewport genişliği 900 piksel ya da daha fazlayken uygulanır. İkinci kural, @media kuralının @supports gibi başka bir koşullu grup kuralının içine yerleştirilebildiğini gösterir: İçteki stiller ancak iki koşul birden doğruysa çalışır. @media kuralları seçici içine de yazılabilir; bu kullanım CSS nesting yazısında anlatılıyor. Kural bloğunun içindeki seçiciler ve bildirimler her zamanki gibi çalışır; özgüllük ve kaynak sırası kuralları da aynen geçerlidir. Media query bir seçicinin ağırlığını artırmaz, yalnızca bloğun etkin olup olmadığını belirler.

Medya türleri: all, print ve screen

Medya türü cihazın genel kategorisini anlatır. Bugün geçerli üç tür kalmıştır. all tüm cihazlar için uygundur ve tür yazmadığınızda varsayılan olarak bu kabul edilir. print kâğıda basılan sayfalar ve baskı önizlemesinde ekranda gösterilen belgeler içindir. screen ise öncelikle ekranlar içindir. CSS 2.1 ve Media Queries 3 döneminde tanımlanmış tty, tv, projection, handheld, braille, embossed ve aural türleri Media Queries 4 ile kullanımdan kaldırılmıştır ve MDN bunların kullanılmamasını söyler.

Türler cihazları çok kaba biçimde ayırdığı için daha ince bir ayrım gerekiyorsa medya özelliklerine başvurmanız gerekir. Örneğin bir telefonun ya da tabletin ayrı bir türü yoktur; ikisi de screen türüdür ve aralarındaki farkı ancak genişlik, işaretçi hassasiyeti gibi özelliklerle sorgulayabilirsiniz.

Medya özellikleri: ayrık ve aralık türleri

Medya özellikleri: ayrık ve aralık türleri: width / height, orientation, aspect-ratio, resolution

Medya özelliği, kullanıcı aracısının, çıkış cihazının ya da ortamın belirli bir niteliğini sınar. Her özellik ifadesi parantez içinde yazılmalıdır; @media width >= 600px geçersizdir, doğrusu @media (width >= 600px) biçimidir. MDN özellikleri iki gruba ayırır. Ayrık (discrete) özellikler değerini sabit bir anahtar kelime kümesinden alır; örneğin orientation yalnızca portrait ya da landscape olabilir. Aralık (range) özellikleri ise sayısal bir değer taşır ve karşılaştırma operatörleriyle ya da min-/max- önekleriyle sorgulanabilir; width, height, aspect-ratio ve resolution bu gruptadır.

ÖzellikNe sınarÖrnek değerler
width / heightViewport genişliği / yüksekliği (width kaydırma çubuğunu da içerir)length, örn. 40em
orientationViewport yönüportrait, landscape
aspect-ratioViewport en boy oranıratio, örn. 16/9
resolutionÇıkış cihazının piksel yoğunluğu2dppx, 2x, 150dpi
hoverBirincil giriş aygıtı rahatça üzerine gelebiliyor munone, hover
pointerBirincil giriş aygıtı işaretçi mi, ne kadar hassasnone, coarse, fine
any-hover / any-pointerMevcut giriş aygıtlarından herhangi biri için aynı sorunone, hover / none, coarse, fine
prefers-color-schemeKullanıcı açık mı koyu tema mı istiyorlight, dark
prefers-reduced-motionKullanıcı gereksiz hareketin azaltılmasını istiyor muno-preference, reduce
prefers-contrastKullanıcı daha yüksek ya da düşük kontrast istiyor muno-preference, more, less, custom
forced-colorsTarayıcı sınırlı bir renk paletini zorluyor munone, active
scriptingBetik (JavaScript) kullanılabilir minone, initial-only, enabled
updateCihaz görünümü ne sıklıkta güncelleyebilirnone, slow, fast

width özelliği hakkında MDN'nin altını çizdiği bir ayrıntı var: Değer, kaydırma çubuğunun genişliği dahil viewport genişliğidir. device-width, device-height ve device-aspect-ratio ise Media Queries Level 4 ile kullanımdan kaldırılmıştır; bunların yerine viewport tabanlı width, height ve aspect-ratio kullanılır. Benzer biçimde önekli -webkit-device-pixel-ratio yerine resolution özelliğinin dppx birimiyle yazılması önerilir.

Özelliği değer vermeden de yazabilirsiniz. Bu durumda sorgu, özelliğin değeri 0 ya da none olmadığı sürece doğrudur. Örneğin @media (color) renkli ekranı olan her cihazda eşleşir. Aynı mantıkla @media (prefers-reduced-motion) yazımı @media (prefers-reduced-motion: reduce) ile eşdeğerdir, çünkü no-preference değeri bu bağlamda yanlış sayılır. Bir özellik tarayıcının çalıştığı cihaz için anlamlı değilse o özelliği içeren ifade her zaman yanlış döner.

Aralık sözdizimi ve min-/max- önekleri

Aralık sözdizimi ve min-/max- önekleri

Aralık özelliklerini iki yolla sorgulayabilirsiniz. Eski ve hâlâ geçerli yol min- ve max- önekleridir. Daha kısa olan yeni yol ise karşılaştırma operatörleriyle yazılan aralık sözdizimidir. MDN'nin örneğine göre aşağıdaki üç yazım tamamen aynı anlama gelir:

css
@media (max-width: 1250px) { /* ... */ }
@media (width <= 1250px) { /* ... */ }
@media (1250px >= width) { /* ... */ }
/* üçü de: viewport genişliği 1250px veya daha dar */

Aralık sözdizimi iki sınırı tek ifadede birleştirmeye de izin verir. @media (min-width: 30em) and (max-width: 50em) yerine @media (30em <= width <= 50em) yazabilirsiniz. Burada önemli olan karşılaştırmanın kapsayıcı ya da dışlayıcı olmasıdır: min-, max-, <= ve >= sınır değerini dahil eder; < ve > ise sınırı dışarıda bırakır.

css
/* sınırlar dahil: 30em ve 50em de eşleşir */
@media (30em <= width <= 50em) { /* ... */ }

/* sınırlar hariç: tam 30em ve tam 50em eşleşmez */
@media (30em < width < 50em) { /* ... */ }

Bu fark kırılma noktalarında sık görülen bir hatayı açıklar. Bir kuralı (max-width: 600px), diğerini (min-width: 600px) ile yazarsanız ikisi de kapsayıcı olduğu için viewport tam 600 piksel genişliğindeyken iki blok aynı anda uygulanır ve sonradan gelen kural kazanır. Aralık sözdiziminde bu çakışmayı önlemek kolaydır: Bir tarafı width < 600px, diğer tarafı width >= 600px yazdığınızda her genişlik değeri yalnızca bir bloğa düşer.

Mantıksal operatörler: and, virgül, or, not ve only

Birden fazla koşulu birleştirmek için mantıksal operatörler kullanılır. and bir medya türünü bir özellikle ya da birden çok özelliği birbiriyle bağlar ve sorgunun doğru olması için zincirdeki her parçanın doğru olmasını ister. Virgül ise birden çok bağımsız sorguyu tek kuralda toplar ve listedeki sorgulardan biri doğruysa bütün kural doğru olur; yani virgül mantıksal bir veya gibi çalışır. Media Queries Level 4 ile eklenen or anahtar kelimesi de virgüle eşdeğerdir.

css
/* iki özellik birlikte doğru olmalı */
@media (width >= 30em) and (orientation: landscape) { /* ... */ }

/* virgül: sorgulardan biri doğruysa yeterli */
@media (height >= 680px), screen and (orientation: portrait) { /* ... */ }

/* or: tek sorgu içinde özellikler arasında veya */
@media (not (color)) or (hover) { /* ... */ }

not operatörünün kapsamı en çok karışan konudur. Parantezsiz yazıldığında, içinde bulunduğu sorgunun tamamını tersine çevirir ve yalnızca virgüle kadar olan sorguyu etkiler. @media not screen and (color), print and (color) yazımında not sadece screen and (color) kısmını tersler; virgülden sonraki print and (color) sorgusu olduğu gibi kalır. Sorgu bir medya türüyle başlıyorsa screen and (color) kısmını paranteze alamazsınız. Sorgu yalnızca özelliklerden oluşuyorsa tersine çevirmek istediğiniz kısmı paranteze almanız gerekir.

css
/* yalnızca özellikler: tamamı parantez içinde terslenir */
@media not ((width > 1000px) and (color)), print and (color) { /* ... */ }

/* sadece genişlik koşulu terslenir */
@media (not (width > 1000px)) and (color), print and (color) { /* ... */ }

/* not yalnızca sağındaki hover özelliğini tersler, screen türünü değil */
@media screen and not (hover) { /* ... */ }

or kullanırken dikkat edilmesi gereken bir kural daha var: or, and ve not ile aynı düzeyde karıştırılamaz. Sırayı belirtmek için alt ifadeleri parantezle gruplamanız ya da sorguları virgülle ayırmanız gerekir. @media ((color) and (hover)) or (monochrome) ve @media (color) and (hover), (monochrome) yazımlarının ikisi de geçerlidir.

only operatörü, medya özelliklerini anlamayan eski tarayıcıların stilleri yanlışlıkla uygulamasını engellemek için tasarlanmıştı. MDN'ye göre only kullanılmazsa eski bir tarayıcı screen and (width <= 500px) sorgusunu yalnızca screen olarak okuyup stilleri bütün ekranlara uygulayabiliyordu. Modern tarayıcılarda only hiçbir etki yaratmaz. Kullanırsanız bir medya türü yazmanız zorunludur: only screen ya da only print gibi.

Kullanıcı tercihlerine ve giriş aygıtına göre sorgular

Media query yalnızca ekran boyutu için değildir. Giriş aygıtını sorgulayan hover ve pointer özellikleri, dokunmatik ve fareyle kullanılan cihazlar arasında arayüzü ayarlamanızı sağlar. hover: none değeri, birincil giriş aygıtının üzerine gelme yapamadığını ya da bunu ancak zahmetli biçimde yapabildiğini gösterir; MDN örnek olarak uzun dokunuşla üzerine gelmeyi taklit eden birçok mobil cihazı anar. pointer: coarse parmak gibi hassasiyeti sınırlı bir işaretçiyi, pointer: fine ise fare gibi hassas bir işaretçiyi belirtir.

css
/* varsayılan üzerine gelme efekti */
a:hover {
  color: black;
  background: yellow;
}

/* birincil giriş aygıtı rahatça üzerine gelebiliyorsa */
@media (hover: hover) {
  a:hover {
    color: white;
    background: black;
  }
}

/* kaba işaretçide dokunma hedefini büyüt */
@media (pointer: coarse) {
  button {
    padding: 0.75em 1.25em;
  }
}

Kullanıcı tercihi sorguları ise işletim sistemi ya da tarayıcı ayarlarını okur. prefers-reduced-motion: reduce, kullanıcının cihazında gereksiz hareketin azaltılması ayarını açtığını gösterir. MDN'ye göre ölçekleme ya da büyük nesneleri kaydırma gibi animasyonlar vestibüler bozukluğu olan kişilerde rahatsızlığa yol açabilir; bu yüzden bu sorguya uyarak animasyonu sadeleştirmek iyi bir uygulamadır. Animasyon tarafı CSS animation ve keyframes yazısında, açık ve koyu tema için prefers-color-scheme ise dark mode yazısında ayrıntılı olarak ele alınıyor.

css
.kutu {
  animation: nabiz 1s linear infinite both;
}

/* aynı özgüllük, daha sonra geldiği için bu kazanır */
@media (prefers-reduced-motion: reduce) {
  .kutu {
    animation: solma 4s linear infinite both;
  }
}

Bu örnekte iki kural aynı seçiciyi kullanır, dolayısıyla özgüllükleri eşittir. Media query bloğu kaynakta sonra geldiği için kullanıcı hareketin azaltılmasını istediğinde animation değerini o belirler. Sorgu yanlış olduğunda blok yok sayılır ve ilk kural geçerli kalır. Bu düzen, media query kullanırken genel bir ilkeyi de gösterir: Önce varsayılan stili yazıp koşullu bloğu ondan sonra yerleştirirseniz özgüllükle uğraşmadan geçersiz kılabilirsiniz.

Yazdırma stilleri: @media print

print medya türü sayfa kâğıda ya da PDF'e yazdırılırken kullanılacak stilleri tanımlar. MDN'nin yazdırma rehberi iki yol gösterir: Ayrı bir yazdırma stil dosyasını media="print" özniteliğiyle bağlamak ya da ana stil dosyasının sonuna bir @media print bloğu eklemek. Rehber, bu blokta da özgüllük ve öncelik kurallarının geçerli olduğunu hatırlatır.

css
@media print {
  #header,
  #footer,
  #nav {
    display: none !important;
  }

  body {
    font-size: 10pt;
  }
}

@media screen {
  body {
    font-size: 13px;
  }
}

/* her iki ortamda ortak */
@media screen, print {
  body {
    line-height: 1.2;
  }
}
html
<link href="print.css" media="print" rel="stylesheet" />

Kâğıt boyutu, yönü ve sayfa kenar boşlukları gibi sayfaya özgü ayarlar için @page kuralı kullanılır. MDN'nin bağlantılı stil dosyalarıyla ilgili notu da önemlidir: <link> etiketine bağlanmış bir media query yanlış dönse bile tarayıcı dosyayı yine indirir, yalnızca indirme önceliği çok daha düşük olur. İçerik ise sorgu doğru olana kadar uygulanmaz. Yani media="print" yazmak dosyanın hiç indirilmeyeceği anlamına gelmez. Sayfa hızına etkisini merak ediyorsanız Core Web Vitals yazısına göz atabilirsiniz.

Media query başka nerelerde kullanılır

Aynı sorgu sözdizimi @media dışında da karşınıza çıkar. @import kuralında URL'den sonra virgülle ayrılmış sorgular yazarak bir stil dosyasının yalnızca belirli ortamlarda uygulanmasını sağlayabilirsiniz. MDN'ye göre tarayıcı bu sorguların hiçbirini desteklemiyorsa bağlantılı kaynağı yüklemez; sorgu yazmamak ya da all yazmak içe aktarmayı koşulsuz yapar. HTML tarafında <link>, <style> ve <source> öğelerinin media özniteliği de aynı sözdizimini kullanır. JavaScript'te ise window.matchMedia() ile bir sorgunun durumunu okuyabilirsiniz.

css
@import "fine-print.css" print;
@import "bluish.css" print, screen;
@import "landscape.css" screen and (orientation: landscape);

Erişilebilirlik ve gizlilik notları

MDN, sorgularda uzunluk değeri gerektiğinde em kullanılmasını önerir. px da geçerli bir birimdir, ancak kullanıcı tarayıcısındaki metin boyutunu değiştirdiğinde em ile yazılmış kırılma noktaları bu değişikliğe daha iyi uyum sağlar. Birimlerin genel davranışı için CSS birimleri yazısına bakabilirsiniz.

Gizlilik tarafında MDN bir uyarı yapar: Media query'ler cihazın yetenekleri hakkında bilgi verdiği için kullanıcıyı tanımlayan bir parmak izi oluşturmakta kötüye kullanılabilir. Bu nedenle bir tarayıcı bazı değerleri bilerek bulanıklaştırabilir ya da varsayılan değerler döndürebilir. Örneğin Firefox'ta parmak izine direnme ayarı açıksa birçok sorgu gerçek cihaz durumunu değil varsayılan değerleri bildirir. Tasarımınızın bu durumda da kullanılabilir kalması gerekir.

Uygulamalı mini örnek: menü düzeni

Aşağıdaki örnek dar ekranda alt alta duran bir menüyü, viewport en az 40em genişliğe ulaştığında yatay hâle getirir. Fareyle kullanılan cihazlarda bağlantılara üzerine gelme efekti eklenir, yazdırmada ise menü tamamen gizlenir.

html
<nav class="menu">
  <a href="#">Ana sayfa</a>
  <a href="#">Blog</a>
  <a href="#">İletişim</a>
</nav>
css
.menu {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
}

/* 40em ve üzeri: bağlantılar yan yana */
@media (width >= 40em) {
  .menu {
    flex-direction: row;
  }
}

/* yalnızca rahat üzerine gelinebilen cihazlarda */
@media (hover: hover) {
  .menu a:hover {
    text-decoration: underline;
  }
}

@media print {
  .menu {
    display: none;
  }
}
/* sonuç: 40em altı dikey, 40em ve üstü yatay menü;
   dokunmatik birincil girişte hover kuralı devreye girmez;
   baskıda menü görünmez */

Örnekte varsayılan düzen dar ekran için yazılmış, geniş ekran durumu sorguyla eklenmiştir. width >= 40em kapsayıcı bir karşılaştırma olduğundan genişlik tam 40em olduğunda da yatay düzen uygulanır. Flexbox'ın flex-direction ve gap özellikleri flexbox rehberinde anlatılıyor.

Sık yapılan hatalar

Sık yapılan hatalar: Özelliği parantezsiz yazmak, Kapsayıcı sınırlarla çakışma yaratmak, not operatörünün kapsamını yanlış okumak, or ile and operatörünü aynı düzeyde karıştırmak
  • Özelliği parantezsiz yazmak: @media screen and max-width: 600px geçersizdir. Her özellik ifadesi parantez içinde olmalıdır.
  • Kapsayıcı sınırlarla çakışma yaratmak: max-width: 600px ile min-width: 600px aynı genişlikte birlikte eşleşir. Bir tarafta dışlayıcı < kullanın.
  • not operatörünün kapsamını yanlış okumak: Parantezsiz not virgüle kadar olan sorgunun tamamını tersler, yalnızca ilk özelliği değil.
  • or ile and operatörünü aynı düzeyde karıştırmak: Sırayı parantezle belirtmezseniz sorgu geçersiz olur.
  • only kullanıp türü unutmak: only yalnızca bir medya türüyle birlikte yazılabilir.
  • Kullanımdan kalkmış türleri ve özellikleri kullanmak: handheld ya da device-width yerine screen, width ve resolution tercih edin.
  • Koşullu bloğu varsayılan kuraldan önce yazmak: Özgüllükler eşitse sonra gelen kazanır. Sorgu bloğu önce gelirse varsayılan kural onu ezer. Kuralların neden uygulanmadığını bulmak için CSS hata ayıklama yazısına bakabilirsiniz.

Sık Sorulan Sorular

min-width ile width >= arasında fark var mı?

Anlam olarak yoktur. MDN'ye göre (min-width: 30em) ile (width >= 30em) eşdeğerdir ve ikisi de sınır değerini dahil eder. Aralık sözdizimi daha kısadır ve < ile dışlayıcı karşılaştırma yapmanıza da izin verir. Tarayıcı desteği için MDN sayfasındaki uyumluluk tablosuna bakın.

Medya türü yazmak zorunlu mu?

Hayır. Tür yazmazsanız all kabul edilir. Tek istisna only operatörüdür; onu kullanıyorsanız bir tür belirtmelisiniz.

@media kuralını bir seçicinin içine yazabilir miyim?

Evet. Yerel CSS nesting ile @media bir stil kuralının içine yerleştirilebilir ve içine doğrudan bildirim yazılabilir. Ayrıntılar ve eşdeğer düz yazım CSS nesting yazısında var.

Media query mi container query mi kullanmalıyım?

Media query viewport ve cihaz özelliklerini sınar; sayfanın genel iskeletini değiştirmek ve kullanıcı tercihlerine uymak için uygundur. Bir bileşenin yerleştirildiği alanın genişliğine göre değişmesi gerekiyorsa container queries daha doğru araçtır.

Marka adları sahiplerine aittir. Bu yazı bağımsız bir teknik rehberdir; adı geçen kuruluşlarla bayilik veya ortaklık ilişkisi bulunduğu anlamına gelmez.

İlgili içerikler: CSS öğrenme rehberi · Container queries · Dark mode ve prefers-color-scheme · @supports özellik sorguları · CSS animation · Mobil uyumluluk nedir