CSS @property kuralı bir özel özelliği (custom property, CSS değişkeni) tarayıcıya kaydeder: değişkenin hangi türde değer alabileceğini (syntax), kalıtılıp kalıtılmayacağını (inherits) ve başlangıç değerini (initial-value) belirlersiniz. Kayıtlı bir değişken artık sıradan bir metin parçası değil, türü bilinen bir değerdir. Bu sayede yanlış türde değer atandığında öngörülebilir biçimde başlangıç değerine döner ve en önemlisi, geçiş ile animasyonlarda adım adım (yumuşak) değişebilir.
Bu yazı, özel özellikleri ve var() fonksiyonunu bildiğinizi varsayar; temel kullanım için önce CSS değişkenleri ve var() yazısını okuyabilirsiniz. Burada üç tanımlayıcıyı, kuralın geçerlilik şartlarını, geçersiz değerlerin nasıl ele alındığını ve kayıtlı değişkenlerle animasyonu adım adım inceliyoruz.
Neden bir değişkeni kaydetmek gerekir?
Sıradan bir özel özellik herhangi bir değeri kabul eder. :root üzerinde --ana-renk: #bada55 tanımlayıp başka bir yerde aynı değişkene 45deg atamanızı hiçbir şey engellemez. Sorun, değişken kullanıldığı yerde ortaya çıkar:
:root {
--theme-color: 45deg;
}
body {
background-color: var(--theme-color);
}
/* sonuç: 45deg bir renk değildir. Bildirim yok sayılmaz;
background-color kalıtılmayan bir özellik olduğu için
başlangıç değeri transparent kullanılır */MDN bu durumu hata işleme rehberinde anlatır: var() ile yapılan yer değiştirme geçersiz bir değer üretirse bildirim atılmaz, özellik kalıtılan bir özellikse üst öğeden kalıtılan değeri, değilse başlangıç değerini alır. Yani beklediğiniz renk yerine sessizce saydam bir zemin elde edersiniz. @property ile değişkenin türünü belirlediğinizde ise yanlış türdeki atama değişkenin kendisinde reddedilir ve değişken kendi kayıtlı başlangıç değerine döner.
MDN'in kayıt rehberi kaydetmeyi özellikle üç durumda önerir: değişkeni animasyonla değiştirecekseniz, tür denetimi istiyorsanız ve kalıtım davranışının öngörülebilir olmasını istiyorsanız. Bir CSS çatısı (framework) yazıyorsanız değişkenlerinizi kaydetmek, kullanıcıların onlara yanlış türde değer atamasını önler ve her zaman bir varsayılan değer olmasını sağlar.
Sözdizimi ve üç tanımlayıcı

@property --rotation {
syntax: "<angle>";
inherits: false;
initial-value: 45deg;
}
@property --defaultSize {
syntax: "<length> | <percentage>";
inherits: true;
initial-value: 200px;
}Özellik adı iki tire ile başlayan bir <dashed-ident> olmalıdır ve büyük-küçük harfe duyarlıdır; --rotation ile --Rotation farklı özelliklerdir. Gövdede üç tanımlayıcı kullanılır:
| Tanımlayıcı | Ne belirler | Zorunlu mu |
|---|---|---|
| syntax | Kabul edilen değer türleri (tırnak içinde bir metin) | Evet |
| inherits | Değerin varsayılan olarak alt öğelere kalıtılıp kalıtılmayacağı (true veya false) | Evet |
| initial-value | Başka değer yokken kullanılacak başlangıç değeri | syntax "*" değilse evet |
Kuralın geçerli olma şartları
@property kuralının geçersiz sayılıp tamamen yok sayılması, sık karşılaşılan ve fark edilmesi zor bir sorundur. MDN'deki şartları tek tek sıralayalım:
syntaxveinheritstanımlayıcılarının ikisi de bulunmalıdır. Biri eksikse bütün kural geçersizdir.syntaxdeğeri bir metindir ve tırnak içinde yazılmalıdır:syntax: "<color>";doğru, tırnaksız yazım yanlıştır.initial-valueyalnızcasyntaxevrensel tanım olan"*"ise atlanabilir. Başka bir sözdiziminde gerekli olup eksikse bütün kural geçersizdir.- Evrensel olmayan bir sözdiziminde
initial-valuehesaplama açısından bağımsız (computationally independent) olmalıdır:10pxgeçerlidir,2inde geçerlidir çünkü1inher zaman96px'e eşittir; ama3emgeçersizdir, çünküemüst öğenin yazı tipi boyutuna bağlıdır. - Bilinmeyen tanımlayıcılar yok sayılır ama kuralı geçersiz kılmaz.
- Aynı adla birden fazla geçerli
@propertyvarsa stil dosyasında sonra gelen kazanır.
Aynı adın hem CSS'te @property ile hem de JavaScript'te CSS.registerProperty() ile kaydedilmesi durumunda JavaScript kaydı kazanır. JavaScript tarafı bu serinin kapsamı dışındadır; MDN, iki yöntemin eşdeğer olduğunu belirtir.
syntax tanımlayıcısı: hangi türler kabul edilir?
syntax metni bir veya daha fazla bileşen adından oluşur. Bileşen adı açılı parantezle yazılan bir veri türü (<length> gibi) ya da açılı parantezsiz bir anahtar sözcük (auto gibi) olabilir. Desteklenen veri türleri şunlardır: <angle>, <color>, <custom-ident>, <image>, <integer>, <length>, <length-percentage>, <number>, <percentage>, <resolution>, <string>, <time>, <transform-function>, <transform-list> ve <url>.
syntax: "<color>"; /* tek tür */
syntax: "<length> | <percentage>"; /* biri ya da öteki */
syntax: "<color>+"; /* boşlukla ayrılmış liste */
syntax: "<length>#"; /* virgülle ayrılmış liste */
syntax: "small | medium | large"; /* anahtar sözcükler */
syntax: "<length> | auto"; /* tür ve anahtar sözcük */
syntax: "*"; /* her geçerli değer */+ çarpanı boşlukla ayrılmış bir listeyi, # çarpanı virgülle ayrılmış bir listeyi, | birleştiricisi ise "ya da" koşulunu ifade eder. <transform-list>, <transform-function>+ yazımına eşdeğerdir. <length-percentage> ise uzunluk, yüzde ve ikisini birleştiren calc() ifadelerini kabul eder. Evrensel tanım * herhangi bir geçerli değeri kabul eder ama çarpanlarla ya da başka bileşenlerle birleştirilemez.
inherits: kalıtımı siz seçersiniz
Kaydedilmemiş bütün özel özellikler varsayılan olarak kalıtılır. inherits: false yazdığınızda değişken, değer verilmeyen alt öğelerde üst öğenin değerini değil, kendi initial-value değerini kullanır. MDN, bunun performans açısından da bir faydası olduğunu belirtir: kalıtılmayan kayıtlı bir değişken değiştiğinde tarayıcının alt öğeleri yeniden değerlendirmesi gerekmez, stil yeniden hesaplamasının kapsamı daralır.
CSS'in genel anahtar sözcükleri olan initial, inherit, unset, revert ve revert-layer, syntax ne olursa olsun her kayıtlı değişken için geçerlidir. Böylece kalıtılmayan bir değişkende bile inherit yazarak üst öğenin değerini açıkça alabilirsiniz. Bu anahtar sözcüklerin genel anlamı için cascade ve kalıtım yazısına bakabilirsiniz.
Çalışılmış örnek: geçerli ve geçersiz değerler

MDN'in kayıt rehberindeki örneği CSS ile yazalım. İki değişken kaydediyoruz: kalıtılan bir boyut ve kalıtılmayan bir renk. Ardından kapsayıcıya ve üç öğeye farklı değerler veriyoruz:
@property --item-size {
syntax: "<percentage>";
inherits: true;
initial-value: 40%;
}
@property --item-color {
syntax: "<color>";
inherits: false;
initial-value: aqua;
}
.container {
--item-size: 20%;
--item-color: orange;
}
.two {
--item-size: initial;
--item-color: inherit;
}
.three {
--item-size: 1000px;
--item-color: xyz;
}
.item {
width: var(--item-size);
height: var(--item-size);
background-color: var(--item-color);
}<div class="container">
<div class="item one">Bir</div>
<div class="item two">İki</div>
<div class="item three">Üç</div>
</div>Şimdi her öğeyi adım adım çözelim:
- Bir: Hiçbir değişken atanmamış.
--item-sizekalıtıldığı için kapsayıcıdaki20%değerini alır.--item-colorkalıtılmadığı için kapsayıcıdakiorangedikkate alınmaz, başlangıç değeriaquakullanılır. Sonuç: %20 boyutunda, aqua renkli kutu. - İki:
--item-size: initialkayıtlı başlangıç değeri olan40%'ı verir.--item-color: inheritise kalıtılmayan değişkeni açıkça kalıtır veorangeolur. Sonuç: %40 boyutunda, turuncu kutu. - Üç:
1000pxbir uzunluktur, ama kayıt yalnızca<percentage>kabul ettiği için bildirim geçersizdir; değişken kalıtılan olduğundan kapsayıcının20%değeri kullanılır.xyzgeçerli bir renk değildir; değişken kalıtılmadığındanaquakullanılır. Sonuç: %20 boyutunda, aqua renkli kutu.
Buradaki ince nokta şudur: MDN'e göre kayıtlı özellikler ayrıştırma (parse) sırasında değil, değer hesaplanırken doğrulanır. Bu yüzden geçerli bir bildirimden sonra gelen geçersiz bir bildirim, önceki geçerli değere geri düşmez; doğrudan kayıtlı varsayılan davranışa, yani kalıtılan değere ya da başlangıç değerine döner. Ayrıca geçersiz değer, öğenin özelliklerini incelerken geçersiz olarak görünmeyebilir. Bu, sıradan CSS bildirimlerinin "son geçerli değer kazanır" davranışından farklıdır.
Kayıtlı değişkenlerle animasyon
Kaydedilmemiş özel özellikler tarayıcı için yalnızca metindir; iki metin arasında ara değer hesaplanamadığı için bu değişkenler animasyonda kesikli (discrete) olarak, yani bir anda atlayarak değişir. Kayıtlı bir değişkenin türü bilindiği için tarayıcı iki değer arasında ara değerler hesaplayabilir ve değişken yumuşak biçimde canlandırılabilir. MDN'in ilerleme çubuğu örneği bunu gösterir:
@property --progress {
syntax: "<percentage>";
inherits: false;
initial-value: 25%;
}
.bar {
display: inline-block;
--progress: 25%;
width: 100%;
height: 5px;
background: linear-gradient(
to right,
#00d230 var(--progress),
black var(--progress)
);
animation: progressAnimation 2.5s ease infinite;
}
@keyframes progressAnimation {
to {
--progress: 100%;
}
}
/* sonuç: yeşil bölüm 2.5 saniyede %25'ten %100'e akarak büyür
ve animasyon sürekli tekrarlanır */Aynı fikirle konik bir gradyanın başlangıç açısını kayıtlı bir değişkene bağlayıp döndürebilirsiniz: değişken türü <angle> olarak bilindiği için ara değerlerle değişir ve gradyan her adımda yeni açıyla çizilir. Gradyan sözdizimi için linear, radial ve conic gradient yazısına bakabilirsiniz:
@property --aci {
syntax: "<angle>";
inherits: false;
initial-value: 0deg;
}
.halka {
background: conic-gradient(from var(--aci), red, blue, red);
animation: don 4s linear infinite;
}
@keyframes don {
to { --aci: 360deg; }
}
/* sonuç: konik gradyan 4 saniyede bir tam tur döner;
@property olmasaydı açı kesikli değişir, dönüş akıcı görünmezdi */Animasyonun genel kuralları için animation ve @keyframes yazısına bakabilirsiniz; hareketi azaltma tercihini (prefers-reduced-motion) orada ele alıyoruz.
Kayıtlı ve kayıtsız değişken karşılaştırması

| Davranış | Sıradan özel özellik | @property ile kayıtlı |
|---|---|---|
| Tür denetimi | Yok, her değer kabul edilir | syntax ile sınırlı |
| Kalıtım | Her zaman kalıtılır | inherits ile seçilir |
| Varsayılan değer | Yok (var() yedeği gerekir) | initial-value |
| Yanlış türde atama | Kullanıldığı özellikte sorun çıkar | Değişken varsayılan davranışa döner |
| Animasyon | Kesikli değişir | Ara değerlerle akıcı değişir |
Pratik desen: tasarım değişkenlerini kaydetmek
Bir sitenin renklerini ve boşluklarını değişkenlerle yönetiyorsanız, en kritik birkaç değişkeni kaydetmek hataları erkenden yakalamanızı sağlar. MDN, bir CSS çatısı geliştirenlere değişkenlerine bir ad öneki vermelerini (namespace) ve onları kaydetmelerini önerir; böylece her değişkenin her zaman bir varsayılan değeri olur ve kullanıcılar yanlış türde değer atayamaz. Aşağıdaki örnekte --ky- öneki kendi projenize ait değişkenleri başka kütüphanelerin değişkenlerinden ayırır:
@property --ky-vurgu {
syntax: "<color>";
inherits: true;
initial-value: rebeccapurple;
}
@property --ky-bosluk {
syntax: "<length>";
inherits: true;
initial-value: 16px;
}
.dugme {
background-color: var(--ky-vurgu);
padding: var(--ky-bosluk);
}
.kampanya {
--ky-vurgu: 12px;
}
/* sonuç: .kampanya içindeki 12px ataması <color> türüne uymaz ve
reddedilir; değişken kalıtılan olduğu için üst öğeden gelen değer,
o da yoksa rebeccapurple kullanılır. Düğme saydam kalmaz */Kayıt olmasaydı aynı hatalı atama, değişkeni kullanan background-color bildirimini hesaplama anında geçersiz kılar ve zemin saydam olurdu. Kayıtla birlikte hatanın etkisi değişkenin kendisinde kalır ve tasarım bozulmaz. Bu davranışın bir bedeli de vardır: hata sessizce düzeltildiği için fark edilmesi zorlaşabilir; değerlerin beklediğiniz gibi gelmediğini düşündüğünüzde önce atamanın türünü kontrol edin. initial-value için 16px seçmemizin nedeni de şartlarla ilgilidir: 1rem gibi göreli bir birim başlangıç değeri olarak kabul edilmez.
Houdini bağlantısı
@property, MDN'in CSS Houdini olarak adlandırdığı API ailesinin bir parçasıdır. Houdini, CSS motorunun bazı bölümlerini geliştiricilere açan API'lerin genel adıdır; worklet adı verilen JavaScript modülleriyle CSS'e yeni çizim yetenekleri eklemek de bu ailededir. @property'nin farkı, kaydı JavaScript yazmadan doğrudan stil dosyasında yapabilmenizdir.
Sık yapılan hatalar
- Tırnakları unutmak:
syntax: <color>;geçersizdir, metin tırnak içinde olmalıdır. - inherits tanımlayıcısını atlamak: Varsayılan bir değeri yoktur, eksikse bütün kural yok sayılır.
- Göreli birimli başlangıç değeri:
initial-value: 2emkuralı geçersiz kılar. - Önceki değere düşmeyi beklemek: Geçersiz atama, aynı kuraldaki önceki geçerli değere değil, kalıtılan ya da başlangıç değerine döner.
- Kalıtılmayan değişkeni üstte tanımlayıp altta kullanmak:
inherits: falseile:rootüzerinde verdiğiniz değer alt öğelere ulaşmaz; alt öğeler başlangıç değerini görür.
Sık Sorulan Sorular
@property ile tanımladığım değişkeni yine :root içinde değiştirebilir miyim?
Evet. Kayıt yalnızca türü, kalıtımı ve başlangıç değerini belirler; değişkene istediğiniz kuralda, türüne uygun yeni değerler atayabilirsiniz.
initial-value ile var() yedek değeri arasındaki fark nedir?
initial-value değişkenin kendisinin başlangıç değeridir ve değişkenin kullanıldığı her yerde geçerlidir. var(--ad, yedek) içindeki yedek ise yalnızca o kullanımda, değişken tanımsız ya da geçersizse devreye girer.
syntax olarak "*" yazmak ne işe yarar?
Evrensel sözdizimi her geçerli değeri kabul eder ve initial-value zorunluluğunu kaldırır. Tür denetimi ve ara değer hesaplaması kaybolur, ama kalıtım davranışını inherits ile yine belirleyebilirsiniz.
Kayıt için JavaScript kullanmam gerekir mi?
Hayır. @property kuralı, JavaScript'teki CSS.registerProperty() çağrısıyla aynı etkiyi doğrudan stil dosyasında sağlar. İkisi aynı ad için birlikte kullanılırsa MDN'e göre JavaScript kaydı kazanır; karışıklığı önlemek için her değişkeni tek bir yerden kaydetmeniz daha kolay takip edilir.
Neden animasyonum hâlâ atlayarak ilerliyor?
Değişkenin kaydı geçersiz olabilir: syntax veya inherits eksik mi, initial-value türe uygun ve hesaplama açısından bağımsız mı, kontrol edin. Kural geçersizse değişken kayıtsız kabul edilir ve kesikli değişir.
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 · animation ve @keyframes · transition · if() ve @function