CSS if() fonksiyonu, bir özelliğin değerini bir koşula göre seçmenizi sağlar: koşul bir stil sorgusu (style()), bir medya sorgusu (media()) ya da bir özellik sorgusu (supports()) olabilir ve doğru çıkan ilk dalın değeri kullanılır. @function kuralı ise parametre alan, içinde mantık barındıran ve result ile bir değer döndüren özel CSS fonksiyonları tanımlamanıza izin verir; bu fonksiyonlar --fonksiyon-adi(...) biçiminde herhangi bir özellik değerinde çağrılır.
İki özellik de CSS'e programlama dillerindekine benzer bir mantık katmanı ekler, ama davranışları JavaScript'ten farklıdır. Bu yazıda önce if() sözdizimini ve üç test türünü, ardından @function parametrelerini, türleri, varsayılan değerleri ve kapsam kurallarını örneklerle anlatıyoruz. Örneklerdeki hesapları adım adım gösteriyoruz.
if() sözdizimi

if() içine noktalı virgülle ayrılmış dallar yazılır. Her dal bir koşul, iki nokta ve bir değerden oluşur: koşul: değer;. Koşul bir test ya da her zaman doğru sayılan else anahtar sözcüğüdür. Son daldan sonraki noktalı virgül isteğe bağlıdır.
div {
background-image: if(
style(--scheme: ice): linear-gradient(#caf0f8, white, #caf0f8);
style(--scheme: fire): linear-gradient(#ffc971, white, #ffc971);
else: none;
);
}
/* sonuç: --scheme değeri ice ise mavi, fire ise turuncu gradyan;
değişken yoksa ya da başka bir değerdeyse arka plan görseli yok */Değerlendirme kuralı basittir: dallar yazıldıkları sırayla denenir ve doğru çıkan ilk dalın değeri döndürülür. Hiçbir dal doğru çıkmazsa fonksiyon "garantili geçersiz" (guaranteed-invalid) bir değer döndürür. Tek bir dalın koşulu ya da değeri geçersizse bütün fonksiyon geçersiz olmaz; ayrıştırıcı bir sonraki dala geçer.
else dalının yeri önemlidir. MDN'e göre birden fazla else yazabilir ve onları herhangi bir konuma koyabilirsiniz, ama else her zaman doğru olduğu için ondan sonraki dallar hiç değerlendirilmez. En başa yazılmış bir else: none; fonksiyonu her durumda none döndüren bir sabite çevirir. Bu özellik hata ayıklamada işe yarayabilir: bir dalın çalışıp çalışmadığını görmek için hemen arkasına göze çarpan bir değerle geçici bir else koyabilirsiniz.
Üç test türü: style(), media(), supports()
Stil sorgusu style(), aynı öğede bir özel özelliğin belirli bir değere sahip olup olmadığını sınar. @container stil sorgularından farkı, kapsayıcı bir üst öğeye bakmak yerine doğrudan öğenin kendisini sınamasıdır. MDN, stil sorgularının şu anda yalnızca özel özellikleri desteklediğini, style(color: white) gibi normal bir özelliğin sınanamadığını belirtir. and, or ve not mantığı kullanılabilir.
background-color: if(
style((--scheme: dark) or (--scheme: very-dark)): black;
);
background-color: if(
not style(--scheme: light): black;
);Medya sorgusu media(), @media'da kullandığınız medya türlerini ve özelliklerini kabul eder. Tek bir özelliğin değerini ekran genişliğine ya da yazdırma ortamına göre değiştirmek için idealdir:
margin: if(
media(width < 700px): 0 auto;
else: 20px auto;
);
/* sonuç: görünüm alanı 700px'ten darsa margin 0 auto,
değilse 20px auto */
background-color: if(
media(print): white;
else: #eeeeee;
);Özellik sorgusu supports(), tarayıcının belirli bir özellik ve değer çiftini ya da selector() ile bir seçiciyi destekleyip desteklemediğini sınar:
color: if(
supports(color: lch(75% 0 0)): lch(75% 0 0);
else: rgb(185 185 185);
);
/* sonuç: lch() destekleniyorsa lch rengi, değilse rgb yedeği */Üç test türünün ortak sınırı şudur: if() her seferinde yalnızca bir özelliğin değerini belirler. Aynı koşula bağlı birden fazla bildirim ya da bütün bir kural kümesi gerekiyorsa @media, @supports veya @container daha uygundur. MDN iki yaklaşımı birbirinin rakibi değil, tamamlayıcısı olarak görür. Bu kuralların ayrıntısı için @media sözdizimi, @supports ve container queries yazılarına bakabilirsiniz.
Değerin tamamı, bir parçası ve iç içe if()
if() bir özelliğin bütün değerini oluşturabileceği gibi yalnızca bir parçasını da oluşturabilir. Örneğin bir border kısaltmasında yalnızca rengi koşula bağlayabilirsiniz. Fonksiyon bir değer parçasının yerini tutabildiği için başka bir if() içine ya da calc() içine de yerleştirilebilir:
border: 3px solid
if(
supports(color: lch(75% 0 0)): lch(75% 0 0);
else: silver;
);
width: calc(if(
style(--scheme: wide): 70%;
else: 50%;
) - 50px);
/* --scheme: wide ise calc(70% - 50px), değilse calc(50% - 50px) */if() için yedek nasıl yazılır?
Desteklemeyen tarayıcılar if() içeren bildirimi geçersiz sayıp atar. Bu, CSS'in genel hata işleme davranışıdır ve yedek yazmanın anahtarıdır: önce sabit bir değer, hemen ardından if() içeren bildirim yazılır. Destekleyen tarayıcı ikinci bildirimi uygular, desteklemeyen ise ilkinde kalır.
padding: 1em;
padding: if(style(--size: "2xl"): 1em; else: 0.25em);
/* destekleyen tarayıcı: --size "2xl" ise 1em, değilse 0.25em
desteklemeyen tarayıcı: ikinci satırı atar, 1em kalır */@function: özel CSS fonksiyonları
@function kuralı bir ad, isteğe bağlı parametreler, isteğe bağlı bir dönüş türü ve bir gövdeden oluşur. Ad, iki tire ile başlayan ve büyük-küçük harfe duyarlı bir <dashed-ident> olmalıdır. Gövdede yerel özel özellikler, @media gibi at-rule'lar ve döndürülecek değeri belirleyen result tanımlayıcısı bulunur.
@function --double(--value) {
result: calc(var(--value) * 2);
}
p {
--base-spacing: 10px;
border-radius: var(--base-spacing);
padding: --double(var(--base-spacing));
}
/* sonuç: border-radius 10px, padding calc(10px * 2) = 20px */Parametreler, fonksiyon gövdesine yerel olarak kapsamlanmış özel özellikler gibi davranır ve gövdede var() ile okunur. Fonksiyon çağrılırken argümanlar virgülle ayrılarak parantez içine yazılır. MDN'in yarı saydam renk örneği, göreli renk sözdizimiyle bir rengin saydamlığını değiştirir; bu sözdizimini color-mix() ve göreli renkler yazısında anlatıyoruz:
@function --transparent(--color, --alpha) {
result: oklch(from var(--color) l c h / var(--alpha));
}
section {
--base-color: #faa6ff;
background-color: --transparent(var(--base-color), 0.8);
}
/* sonuç: #faa6ff renginin %80 opak hâli */Türler ve varsayılan değerler
Parametrelere ve dönüş değerine tür verebilirsiniz. Tür yazılmazsa her tür kabul edilir; bu type(*) yazmakla aynıdır. Birden fazla türe izin vermek için type() fonksiyonu ve | ayırıcısı kullanılır. Varsayılan değer, parametre tanımının sonuna iki nokta ile eklenir ve belirtilen türe uygun olmalıdır.
@function --transparent(--color <color>, --alpha <number>: 0.8)
returns <color> {
result: oklch(from var(--color) l c h / var(--alpha));
}
.a { background-color: --transparent(var(--base-color)); }
/* --alpha verilmedi, varsayılan 0.8 kullanılır */
.b { background-color: --transparent(var(--base-color), 50%); }
/* 50% bir <number> değil: değer hesaplama anında geçersiz olur.
Ancak --alpha için varsayılan tanımlı olduğundan MDN'e göre
geçersiz argüman yok sayılır ve 0.8 kullanılır */Bu son ayrıntıya dikkat edin. MDN, varsayılan değeri olmayan bir parametreye yanlış türde argüman verildiğinde değerin hesaplama anında geçersiz olduğunu ve background-color'ın transparent kaldığını söyler. Aynı parametreye varsayılan değer tanımladığınızda ise geçersiz argüman yok sayılır ve varsayılan kullanılır. Yüzdeyi de kabul etmek istiyorsanız türü type(<number> | <percentage>) olarak yazmanız yeterlidir.
result: erken dönüş yoktur
MDN, anahtar sözcüğün neden return değil result olduğunu açıklar: CSS fonksiyonları ilk result satırında durmaz. Gövde baştan sona değerlendirilir ve birden fazla result varsa, CSS'in geri kalanında olduğu gibi kaynakta sonra gelen kazanır. Bu yüzden koşullu sonuçlarda varsayılanı önce, koşullu olanı sonra yazarsınız:
@function --narrow-wide(--narrow, --wide) {
result: var(--wide);
@media (width < 700px) {
result: var(--narrow);
}
}
/* aynı mantık if() ile: */
@function --narrow-wide(--narrow, --wide) {
result: if(media(width < 700px): var(--narrow); else: var(--wide));
}Birinci yazımda @media bloğunu result: var(--wide) satırından önce koyarsanız, sorgu doğru olsa bile sonraki satır onu ezer ve fonksiyon her zaman geniş değeri döndürür.
Kapsam: parametreler, yerel değişkenler ve öğe değişkenleri

Fonksiyon gövdesinde tanımlanan özel özellikler yerel sabitler gibi davranır. Fonksiyon, çağrıldığı öğede tanımlı özel özellikleri de görebilir. Aynı ad birden fazla yerde varsa öncelik şöyledir: gövdedeki yerel tanım en güçlüdür, ardından parametre gelir, en son öğede tanımlı değişken. MDN'in örneğini adım adım çözelim:
@function --add-a-b-c(--b, --c) {
--c: 300;
result: calc(var(--a) + var(--b) + var(--c));
}
div {
--a: 1;
--b: 2;
--c: 3;
z-index: --add-a-b-c(20, 30); /* 321 */
}--a: Parametre ya da yerel tanım yok, öğedeki1kullanılır.--b: Parametre olarak20verildi; öğedeki2ezilir.--c: Parametre30olsa da gövdedeki yerel300ikisini de ezer.- Sonuç:
1 + 20 + 300 = 321.
Bir fonksiyon başka bir fonksiyonu çağırabilir; içteki fonksiyon, çağrı zincirinde daha yukarıdaki fonksiyonların parametrelerine ve yerel değişkenlerine erişebilir. MDN'deki örnekte --outer(1) içinde yerel --outer-local: 2 tanımlanır ve --inner() bu ikisini toplar; sonuç 1 + 2 = 3 olur.
Virgül içeren bir değeri tek argüman olarak geçirmek için süslü parantez kullanılır. Aksi hâlde liste birden fazla argüman sanılır:
@function --max-plus-x(--list <length>#, --x <length>) {
result: calc(max(var(--list)) + var(--x));
}
div {
width: --max-plus-x({1px, 7px, 2px}, 3px); /* 10px */
}
/* max(1px, 7px, 2px) = 7px; 7px + 3px = 10px */Aynı adla birden fazla fonksiyon tanımlanırsa daha güçlü @layer içindeki kazanır; hepsi aynı katmandaysa kaynakta en son tanımlanan geçerli olur. Katman kavramı için @layer yazısına bakabilirsiniz.
Desteği sınamak için küçük bir hile
MDN'in özel fonksiyon rehberi, parametresiz bir fonksiyonla destek algılamayı gösterir. Fonksiyon none döndürür ve bir uyarı kutusunun display değeri olarak kullanılır. Destekleyen tarayıcıda uyarı gizlenir; desteklemeyen tarayıcı display: --supports() bildirimini geçersiz sayıp atar ve uyarı görünür kalır.
@function --supports() {
result: none;
}
.destek-uyarisi {
display: --supports();
}Mini örnek: boyutu değişkenle seçilen düğme
Şimdi iki özelliği birlikte kullanalım. Bir düğmenin iç boşluğunu --boyut değişkenine göre if() ile seçecek, zemin rengini de bir özel fonksiyonla yarı saydam yapacağız. Her iki bildirimin önüne, desteklemeyen tarayıcılar için sabit bir yedek koyuyoruz:
@function --yari(--renk <color>, --guc <number>: 0.6) returns <color> {
result: oklch(from var(--renk) l c h / var(--guc));
}
.dugme {
--boyut: buyuk;
padding: 0.5em 1em;
padding: if(style(--boyut: buyuk): 1em 2em; else: 0.5em 1em);
background-color: #6a1b9a;
background-color: --yari(#6a1b9a);
}
/* destekleyen tarayıcı: --boyut buyuk olduğu için padding 1em 2em;
zemin #6a1b9a renginin 0.6 opaklıktaki hâli (--guc varsayılanı)
desteklemeyen tarayıcı: ikinci bildirimler atılır,
padding 0.5em 1em ve zemin düz #6a1b9a kalır */Bu örnekte üç noktaya dikkat edin. Birincisi, style(--boyut: buyuk) testi düğmenin kendisinde tanımlı değişkene bakar; bir kapsayıcıya ihtiyaç yoktur. İkincisi, else dalı if()'i destekleyen tarayıcıda değişken başka bir değer aldığında da makul bir sonuç verir; yazılmasaydı iç boşluk başlangıç değerine dönerdi. Üçüncüsü, --guc parametresinin varsayılanı olduğu için fonksiyonu tek argümanla çağırabildik; ikinci argümana yanlışlıkla yüzde verilse bile varsayılan değer kullanılır.
Hangi aracı ne zaman seçmeli?

| Araç | Ne zaman uygun | Kapsamı |
|---|---|---|
| if() | Tek bir özelliğin değeri bir koşula bağlıysa | Bir değer ya da değer parçası |
| @media / @supports | Aynı koşula bağlı birden fazla bildirim varsa | Bütün kurallar |
| @container stil sorgusu | Koşul bir üst kapsayıcının değişkenine bağlıysa | Kapsayıcının torunları |
| @function | Aynı hesaplama veya uzun sözdizimi tekrar tekrar yazılıyorsa | Değer üreten yeniden kullanılabilir mantık |
| Özel özellik (var) | Sabit bir değer paylaşılacaksa | Kalıtılan değer |
Sık yapılan hatalar
- if ile parantez arasına boşluk koymak: Bildirimin tamamı geçersiz olur.
- Dalları virgülle ayırmak: Dallar noktalı virgülle, koşul ile değer iki noktayla ayrılır.
- style() içinde normal özellik sınamak: Şu anda yalnızca özel özellikler sınanabilir.
- else'i başa yazmak: Ondan sonraki dallar hiç değerlendirilmez.
- Yedek bildirim yazmamak:
if()kendiliğinden gerilemez; önce sabit bir değer yazın. - @function içinde erken dönüş beklemek: Sonra gelen
resultöncekini ezer. - Virgüllü listeyi süslü parantezsiz geçirmek: Liste birden fazla argüman sanılır.
Sık Sorulan Sorular
if() ile @media arasındaki fark nedir?
if() tek bir özelliğin değerini koşula bağlar ve doğrudan bildirimin içinde yazılır. @media ise aynı koşul altında istediğiniz kadar kuralı gruplar. Tek değer değişiyorsa if(), birden fazla bildirim değişiyorsa @media daha okunaklıdır.
@function, Sass fonksiyonlarının yerini tutar mı?
Sass bu serinin ve kullandığımız belgelerin kapsamı dışındadır. @function ise tarayıcının kendisinin değerlendirdiği yerel bir CSS özelliğidir; MDN'e göre çağrıldığı öğede tanımlı özel özellikleri görebilir ve gövdesinde @media ile if() kullanabilir.
Özel fonksiyon her özellikte kullanılabilir mi?
MDN'e göre özel fonksiyonlar herhangi bir özellik değerinde çağrılabilir. Döndürdükleri değerin, kullanıldıkları özellik için geçerli olması gerekir; aksi hâlde bildirim hesaplama anında geçersiz olur.
if() dallarının değerinde var() kullanabilir miyim?
Evet. Dalın değeri sıradan bir özellik değeridir; MDN'in --narrow-wide() örneğinde if(media(width < 700px): var(--narrow); else: var(--wide)) yazımı tam olarak bunu yapar. Değer parçası olarak başka fonksiyonlar, örneğin gradyanlar ya da iç içe bir if(), de kullanılabilir. Önemli olan, seçilen değerin o özellik için geçerli olmasıdır.
if() hiçbir dal doğru çıkmazsa ne döndürür?
Garantili geçersiz bir değer döndürür. Özel özellik ya da anchor() gibi yedeği olan bir yerde kullanılmışsa yedek devreye girer; normal bir özellikte ise MDN'in örneğindeki gibi özellik başlangıç değerine döner.
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 · CSS değişkenleri · calc(), min(), max(), clamp() · @property · Container ve style queries