İçeriğe geç
LibraryCSS
--custom-propertyOrta40 efektte kullanılıyor

CSS değişkenleriyle temalanabilir efekt yazmak

CSS özel değişkenleri (custom property), -- ile başlayan ve var() ile okunan gerçek CSS değerleridir. Sass değişkenlerinden temel farkı şudur: derleme anında değil çalışma anında çözülürler, kalıtım kurallarına uyarlar ve JavaScript'ten okunup yazılabilirler. Bir değişkeni değiştirdiğinde onu kullanan her bildirim anında güncellenir.

Efekt yazarken bu, tek bir kodun onlarca varyanta hizmet etmesi demektir. Rengi, süreyi, kalınlığı ve açıyı değişkene çıkarırsan aynı CSS'i kopyalayan kullanıcı yalnızca değişkenleri değiştirerek kendi temasına uydurur. Rehber tanımlama kurallarını, kalıtımı, yedek değerleri ve @property ile animasyonlanabilir değişkenleri anlatıyor.

Tanımlama, okuma ve yedek değer

Değişken normal bir bildirim gibi yazılır: --accent: #3b82f6. Adı büyük-küçük harfe duyarlıdır (--Accent ile --accent farklı değişkenlerdir) ve değer olarak neredeyse her şeyi kabul eder — renk, uzunluk, virgüllü liste, hatta yarım bir bildirim parçası. Tarayıcı değeri kullanıldığı yere kadar ayrıştırmaz; bu yüzden geçersiz bir değer yazmak tanım anında değil kullanım anında sorun çıkarır.

var() ikinci argüman olarak yedek değer alır: var(--accent, #3b82f6). Değişken hiç tanımlanmamışsa ya da değeri geçersizse yedek devreye girer. Yedeklerde virgül kullanılabilir; var(--gölge, 0 2px 6px rgb(0 0 0 / .3)) tamamen geçerlidir çünkü ilk virgülden sonrası bütünüyle yedek sayılır.

Tanımın nereye yazıldığı önemlidir. :root seçicisine yazılan değişken tüm belgeye yayılır; bir bileşenin kendi seçicisine yazılan ise yalnızca o eleman ve altındakiler için geçerlidir. Efektlerde ikinci yaklaşım tercih edilir: değişkenler bileşenin köküne yazılır, dışarıdan ezilebilir ama varsayılanları kendi içinde taşır.

cssBileşen kendi varsayılanlarını taşır
.puls-buton {
  /* Ayarlanabilir yüzey — dışarıdan ezilebilir, ama varsayılanı burada */
  --renk: #3b82f6;
  --sure: 1.6s;
  --yayilma: 14px;

  position: relative;
  border-radius: 0.75rem;
  background: var(--renk);
  color: #fff;
  padding: 0.7rem 1.3rem;
}

.puls-buton::after {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: inherit;
  box-shadow: 0 0 0 0 var(--renk);
  animation: puls var(--sure) ease-out infinite;
}

@keyframes puls {
  to { box-shadow: 0 0 0 var(--yayilma) transparent; }
}
htmlAynı CSS, üç farklı varyant — tek satır fark
<button class="puls-buton">Varsayılan</button>
<button class="puls-buton" style="--renk: #0ea5e9">Açık mavi</button>
<button class="puls-buton" style="--renk: #1d4ed8; --sure: 2.4s">Yavaş</button>

Kalıtım ve kapsam

Özel değişkenler normal CSS özellikleri gibi kalıtılır. Bir kaba tanımlanan değişkeni içindeki her eleman görür; aynı adı bir alt elemanda yeniden tanımlarsan yalnızca o alt ağaç yeni değeri kullanır. Bu, tema değiştirmenin en ucuz yoludur: bir sınıf ekleyerek tüm alt ağacın renklerini değiştirebilirsin.

Sözde sınıflar da bu mekanizmaya dahildir. :hover içinde bir değişkeni yeniden tanımlamak, o değişkeni kullanan tüm bildirimleri aynı anda günceller — beş ayrı :hover kuralı yazmak yerine tek bir değişken satırı yeter.

Kalıtımın bir sınırı var: değişken @keyframes bloğunun içinden okunduğunda, değeri animasyonun uygulandığı elemanda çözülür. Anahtar karede var(--x) yazıp --x değerini de aynı anda animasyonlamaya çalışmak beklendiği gibi çalışmaz; tarayıcı animasyon başlarken değeri bir kez çözer.

Duyarlı tasarımda değişkenleri medya sorgularıyla yeniden tanımlamak, aynı bildirimi iki kez yazmaktan çok daha temizdir. Kırılım noktasında yalnızca sayılar değişir, kuralların kendisi tek yerde durur.

cssTema, durum ve kırılım — hepsi tek değişken üzerinden
.kart {
  --yuzey: #121722;
  --kenar: rgb(255 255 255 / 0.09);
  --kalkis: 0px;

  background: var(--yuzey);
  border: 1px solid var(--kenar);
  transform: translateY(var(--kalkis));
  transition: transform 200ms ease, border-color 200ms ease;
}

/* Beş ayrı bildirim yerine iki değişken satırı */
.kart:hover {
  --kenar: rgb(96 165 250 / 0.3);
  --kalkis: -4px;
}

/* Alt ağaç teması: yalnızca bu kabın içi değişir */
.acik-tema .kart {
  --yuzey: #f8fafc;
  --kenar: rgb(15 23 42 / 0.12);
}

@media (max-width: 640px) {
  .kart { --kalkis: 0px; }   /* mobilde kalkış yok */
}

@property: tipli ve animasyonlanabilir değişkenler

Normal bir özel değişken tarayıcı için sadece bir metin parçasıdır. --aci: 0deg ile --aci: 360deg arasında geçiş yazarsan hiçbir ara değer üretilmez; değer belirli bir anda sıçrar. Bunun sebebi tarayıcının değişkenin bir açı olduğunu bilmemesidir.

@property kuralı değişkene tip verir. syntax alanı değerin ne olduğunu (<angle>, <color>, <length>, <number>, <percentage>), inherits kalıtılıp kalıtılmayacağını, initial-value ise varsayılanı bildirir. Bu üç alan zorunludur; biri eksikse kural tamamen yok sayılır.

Tip bildirildikten sonra değişken gerçek bir animasyonlanabilir özellik gibi davranır. Gradyan açısını döndürmek, bir rengi yumuşakça değiştirmek ya da bir yüzdeyi animasyonlamak artık mümkündür. Bu, konik gradyanlı dönen çerçevelerin ve ilerleme halkalarının saf CSS ile yazılabilmesinin tek sebebidir.

Tip kontrolünün ikinci faydası doğrulamadır: <length> olarak bildirilmiş bir değişkene red yazmaya çalışırsan tarayıcı değeri reddeder ve initial-value'ya döner. Bu, geçersiz değerin efekti tamamen bozmasını engeller.

cssAnimasyonlanabilir açı ve renk
@property --aci {
  syntax: "<angle>";
  inherits: false;
  initial-value: 0deg;
}

@property --vurgu {
  syntax: "<color>";
  inherits: true;
  initial-value: #3b82f6;
}

.hale {
  background: conic-gradient(from var(--aci), var(--vurgu), transparent 60%, var(--vurgu));
  transition: --vurgu 400ms ease;     /* renk geçişi artık çalışır */
  animation: cevir 5s linear infinite;
}

.hale:hover { --vurgu: #0ea5e9; }

@keyframes cevir {
  to { --aci: 360deg; }               /* açı gerçekten ara değer üretir */
}

Efektleri temalanabilir yazmak

İyi bir efekt, ayarlanabilir yüzeyini tek yerde toplar. Kural şu: kullanıcının değiştirmek isteyeceği her sayı ve renk bir değişken olmalı, geri kalan her şey sabit kalmalı. Tipik ayarlanabilir yüzey dört kalemden oluşur — vurgu rengi, animasyon süresi, boyut/kalınlık ve yoğunluk (opaklık, bulanıklık, yayılma).

Değişkenleri türetmek de mümkündür: --golge: 0 8px 24px rgb(from var(--renk) r g b / 0.35) yazmak, gölgeyi ana renkten otomatik üretir. rgb(from ...) göreli renk sözdizimi henüz her yerde yok, ama color-mix() daha geniş destekli bir alternatif sunar ve aynı işi yapar.

JavaScript tarafında değişkenler element.style.setProperty("--x", deger) ile yazılır ve getComputedStyle(el).getPropertyValue("--x") ile okunur. Fareyi takip eden ışık efektleri bu yolla yazılır: JavaScript yalnızca iki sayı günceller, geri kalan her şey CSS'te kalır. Sınıf değiştirmekten hem daha ucuz hem daha esnektir.

Son olarak yedek değerleri ihmal etme. Efekt kodunu kopyalayan biri değişken tanımlarını atlarsa, var(--renk, #3b82f6) yazımı efektin yine de çalışmasını sağlar. Sessizce bozulan bir efekt yerine varsayılanıyla çalışan bir efekt her zaman daha iyidir.

Ayrıntılı bir örnek için conic-gradient rehberindeki ilerleme halkasına bak: yüzde değeri tamamen bir CSS değişkeninden sürülüyor ve HTML tarafında tek bir style özniteliğiyle değiştiriliyor.

cssTüretilmiş renkler ve fare konumu değişkenleri
.isik-kart {
  --renk: #3b82f6;
  /* Gölge ve kenar ana renkten türetiliyor — tek değişken hepsini sürer */
  --golge: 0 12px 30px color-mix(in srgb, var(--renk) 40%, transparent);
  --kenar: color-mix(in srgb, var(--renk) 30%, transparent);

  /* JavaScript yalnızca bu ikisini günceller */
  --x: 50%;
  --y: 50%;

  position: relative;
  border: 1px solid var(--kenar);
  box-shadow: var(--golge);
  background:
    radial-gradient(240px circle at var(--x) var(--y),
      color-mix(in srgb, var(--renk) 22%, transparent),
      transparent 70%),
    #0c1017;
}

Katalogdan canlı örnekler

Aşağıdakiler --custom-property kullanan gerçek efektler — anlatılan teknik burada çalışır hâlde. Herhangi birine tıklayıp tam kaynağını açabilir, tarayıcı içi editörde değiştirip sonucu anında görebilirsin.

Tarayıcı desteği

Sürüm numaraları özelliğin öneksiz ve varsayılan olarak açık hâle geldiği ilk kararlı sürümü gösterir.

ÖzellikTarayıcılarNot
Özel değişkenler ve var()Chrome 49+, Firefox 31+, Safari 9.1+, Edge 15+On yıla yakın süredir her yerde çalışıyor; polyfill gerekmez.
@propertyChrome 85+, Firefox 128+, Safari 16.4+Desteklenmediğinde kural yok sayılır ve değişken metin gibi davranır — animasyon çalışmaz ama statik görünüm bozulmaz.
color-mix()Chrome 111+, Firefox 113+, Safari 16.2+Renk türetmenin geniş destekli yolu. Yedek olarak sabit bir renk yazmak eski tarayıcıları kurtarır.
Göreli renk sözdizimi rgb(from ...)Chrome 119+, Safari 16.4+, Firefox 128+Bir renkten kanal okuyup yenisini üretir. Yeni olduğu için @supports ile korumak mantıklı.

Yaygın hatalar

  • Değişken adını büyük-küçük harf farkıyla yazmak

    --Accent ile --accent iki ayrı değişkendir ve hata verilmez; efekt sessizce yedek değere düşer. Tek bir yazım kuralına bağlı kal.

  • Değişkeni @property olmadan animasyonlamaya çalışmak

    Tipsiz bir değişken tarayıcı için metindir ve ara değer üretilmez; geçiş süresi dolduğunda değer aniden sıçrar. Animasyon gerekiyorsa @property ile tip bildir.

  • Yedek değer yazmamak

    Kodunu kopyalayan biri değişken tanımını atlarsa bildirim geçersiz olur ve efekt bozulur. var(--renk, #3b82f6) yazımı bunu tek karakterle önler.

  • :root'a bileşene özel değişken yazmak

    Genel isim alanı hızla kirlenir ve iki efektin --renk değişkeni çakışır. Bileşene özel değerleri bileşenin kendi seçicisine yaz, yalnızca gerçekten global olanları :root'a bırak.

  • Değişkeni özellik adı olarak kullanmaya çalışmak

    var(--ozellik): 10px geçersizdir; var() yalnızca değer tarafında çalışır. Değişkenle bir bildirimin tamamını üretmek de tarayıcılar arasında güvenilir değildir.

Sıkça sorulan sorular

CSS değişkenleri Sass değişkenlerinin yerini alır mı?
Farklı işler yaparlar. Sass değişkeni derleme anında çözülür ve çıktıda hiç görünmez; koşul ve döngü içinde kullanılabilir. CSS değişkeni çalışma anında yaşar, kalıtılır, medya sorgusuyla değişebilir ve JavaScript'ten güncellenebilir. Tema ve durum yönetimi için CSS değişkeni, derleme mantığı için Sass uygun.
Değişkeni JavaScript'ten nasıl değiştiririm?
element.style.setProperty("--renk", "#0ea5e9") ile yazarsın, getComputedStyle(element).getPropertyValue("--renk") ile okursun. Fare konumu, kaydırma ilerlemesi gibi sürekli değişen değerleri sınıf eklemek yerine değişkenle geçirmek çok daha ucuzdur.
Değişken neden animasyonlanmıyor?
Tarayıcı tipsiz bir özel değişkeni metin olarak görür ve iki metin arasında ara değer üretemez. @property ile syntax alanını bildirdiğinde (örneğin "<angle>" ya da "<color>") değişken gerçek bir animasyonlanabilir özellik hâline gelir.
Değişkenleri :root'a mı yoksa bileşene mi yazmalıyım?
Renk paleti ve tipografi ölçeği gibi gerçekten global değerler :root'a; bir efektin süresi, kalınlığı, yayılması gibi bileşene özel değerler o bileşenin kendi seçicisine yazılmalı. Böylece bileşen kendi varsayılanlarını taşır ve dışarıdan ezilmeye açık kalır.
Değişken kullanmak performansı etkiler mi?
Ölçülebilir bir maliyeti vardır ama pratikte ihmal edilebilir. Dikkat edilecek tek nokta, çok derin bir ağacın kökündeki bir değişkeni sık sık güncellemektir: değişiklik tüm alt ağaçta stil yeniden hesabı tetikler. Sık güncellenen değişkeni mümkün olduğunca hedefe yakın elemanda tut.

İlgili rehberler

Son güncelleme:

Tüm rehberler