@keyframes ile CSS animasyonu
@keyframes, bir animasyonun zaman çizelgesini tanımlayan at-kuralıdır. Elemanın hangi anda hangi stile sahip olacağını yüzdelerle yazarsın; tarayıcı aradaki kareleri kendisi üretir. transition'dan farkı şudur: geçiş yalnızca iki durum arasında ve bir tetikleyiciye bağlı çalışır, anahtar kare animasyonu ise istediğin kadar ara duruma sahiptir ve sayfa yüklenir yüklenmez kendiliğinden başlar.
Katalogdaki yükleyicilerin, kayan arka planların, nabız atan rozetlerin ve yazı makinesi metinlerinin tamamı bu tek at-kuralına dayanır. Bu rehber sözdizimini, animation alt özelliklerini, birden fazla animasyonu tek elemanda birleştirmeyi ve hangi özelliklerin animasyonunun ucuz hangisinin pahalı olduğunu anlatıyor.
Sözdizimi: kareler ve animation kısayolu
Bir animasyon iki parçadan oluşur. Birincisi @keyframes bloğu: animasyona bir ad verir ve kareleri listeler. İkincisi elemana uygulanan animation bildirimi: hangi adın, ne kadar sürede, hangi hızlanma eğrisiyle ve kaç kez oynatılacağını söyler. @keyframes bloğu tek başına hiçbir şey yapmaz; bir eleman onu adıyla çağırana kadar tarayıcı için sadece bir tanımdır.
Kareler from / to anahtar sözcükleriyle ya da yüzdelerle yazılır. from, 0% ile; to, 100% ile aynı şeydir. Yüzde kullanmak birden fazla ara durum gerektiğinde şart olur. Aynı kare için birden fazla yüzdeyi virgülle gruplayabilirsin: 0%, 100% { opacity: 1 } yazmak, animasyonun başında ve sonunda aynı stili tekrar yazmaktan kısadır.
- animation-direction
alternateher tekrarda yönü ters çevirir. Gidiş-dönüş animasyonlarında 100% karesini yazmana gerek kalmaz, kare sayısı yarıya iner.- animation-fill-mode
forwardsanimasyon bitince son karenin stilini korur,backwardsgecikme süresince ilk kareyi uygular,bothikisini birden yapar. Varsayılannoneolduğu için animasyon biter bitmez eleman eski hâline döner.- animation-play-state
pausedanimasyonu bulunduğu karede dondurur.:hoverile birleştirilince JavaScript'siz duraklat/devam et elde edilir.
@keyframes nabiz {
0% { transform: scale(1); opacity: 1; }
50% { transform: scale(1.18); opacity: 0.6; }
100% { transform: scale(1); opacity: 1; }
}
.nokta {
width: 14px;
height: 14px;
border-radius: 50%;
background: #3b82f6;
animation: nabiz 1.2s ease-in-out infinite;
}.nokta {
animation-name: nabiz;
animation-duration: 1.2s;
animation-timing-function: ease-in-out;
animation-delay: 0s;
animation-iteration-count: infinite;
animation-direction: normal;
animation-fill-mode: none;
animation-play-state: running;
}Adım adım: üç noktalı yükleyici
Klasik üç noktalı yükleyici, tek bir animasyonun üç elemana farklı gecikmelerle uygulanmasından ibarettir. Üç ayrı @keyframes bloğu yazmak yerine aynı kareyi paylaşır, sadece animation-delay değerini kaydırırsın. Sonuç dalga gibi ilerleyen bir hareket olur.
Kritik nokta both doldurma modudur. Onsuz, gecikme süresi boyunca noktalar animasyonun ilk karesine değil kendi statik konumlarına yerleşir; animasyon başladığı anda gözle görülür bir sıçrama olur. both gecikme süresince de ilk kareyi uygular ve sıçramayı kaldırır.
<div class="yukleyici">
<span></span><span></span><span></span>
</div>.yukleyici { display: flex; gap: 8px; }
.yukleyici span {
width: 10px;
height: 10px;
border-radius: 50%;
background: #60a5fa;
/* both: gecikme boyunca da ilk kare uygulansın — başlangıç sıçraması olmasın */
animation: zipla 0.6s ease-in-out infinite alternate both;
}
.yukleyici span:nth-child(2) { animation-delay: 0.15s; }
.yukleyici span:nth-child(3) { animation-delay: 0.30s; }
@keyframes zipla {
from { transform: translateY(0); }
to { transform: translateY(-10px); }
}Zamanlama fonksiyonları ve steps()
animation-timing-function iki kare arasındaki ara değerlerin nasıl dağıtılacağını belirler. linear sabit hızda ilerler ve dönen yükleyicilerde doğru seçimdir; ease-in-out ise başta ve sonda yavaşlar, doğal hareket taklidi için uygundur. Daha hassas kontrol için cubic-bezier(0.68, -0.55, 0.27, 1.55) gibi değerlerle geri esneyen (overshoot) eğriler yazılabilir — kontrol noktaları 0–1 aralığının dışına çıktığında animasyon hedefi aşıp geri döner.
steps(n) ara değer üretmeyi tamamen kapatır: animasyon n eşit sıçramayla ilerler. Yazı makinesi efekti, kare kare sprite oynatma ve yanıp sönen imleç bu fonksiyonla yazılır. Aşağıdaki örnekte genişlik ch biriminde artar, dolayısıyla her adım tam bir karakter genişliğine denk gelir.
Zamanlama fonksiyonu @keyframes bloğu içinde tek tek karelere de yazılabilir. Bir karede animation-timing-function: linear yazarsan, o kareden sonrakine geçiş o eğriyle yapılır — böylece tek animasyonun farklı bölümleri farklı hızlanma davranışı gösterir.
.yazi {
width: 12ch; /* metin tam 12 karakter olmalı */
overflow: hidden;
white-space: nowrap;
border-right: 2px solid #60a5fa;
font-family: monospace;
animation:
yaz 2s steps(12) forwards,
imlec 0.7s steps(1) infinite;
}
@keyframes yaz { from { width: 0; } to { width: 12ch; } }
@keyframes imlec { 50% { border-color: transparent; } }Performans: hangi özelliği animasyonlamalı
Tarayıcı her karede üç aşamadan geçebilir: layout (geometriyi yeniden hesapla), paint (pikselleri boya), composite (katmanları birleştir). width, height, top, left, margin ve padding animasyonu üçünü birden tetikler ve uzun listelerde kare düşmesine yol açar. transform ve opacity ise yalnızca composite aşamasını çalıştırır; bu iş GPU'da, ana iş parçacığından bağımsız yürür.
Pratik kural: konum için top/left yerine transform: translate(), boyut için width/height yerine transform: scale(), görünürlük için display yerine opacity kullan. Yukarıdaki yükleyici örneğinde noktalar margin-top ile değil translateY ile hareket ettiriliyor; aradaki fark tek elemanda görünmez ama ekranda otuz kart varken belirgindir.
will-change: transform tarayıcıya elemanı önceden ayrı bir katmana almasını söyler. Faydalıdır ama bedava değildir: her katman ayrı bellek tüketir. Sayfadaki her animasyonlu elemana yazmak yerine yalnızca gözle görülür takılma olan yerlere ekle, animasyon bitince kaldır.
Son olarak erişilebilirlik: vestibüler rahatsızlığı olan kullanıcılar için prefers-reduced-motion sorgusunu ekle. Sitedeki tüm efektler bu sorguya saygı duyar; kendi kodunda da tek blokla halledebilirsin.
@media (prefers-reduced-motion: reduce) {
.nokta,
.yukleyici span {
animation: none;
}
}Katalogdan canlı örnekler
Aşağıdakiler @keyframes 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.
| Özellik | Tarayıcılar | Not |
|---|---|---|
| @keyframes / animation | Chrome 43+, Firefox 16+, Safari 9+, Edge 12+ | Öneksiz sürüm on yılı aşkın süredir her yerde çalışıyor; -webkit- öneki artık gereksiz. |
| steps(n, jump-start | jump-none) | Chrome 77+, Firefox 65+, Safari 14+ | Eski `steps(n, start | end)` yazımı hâlâ geçerli ve daha geniş desteklidir. |
| animation-composition | Chrome 112+, Firefox 115+, Safari 16+ | Aynı özelliği hedefleyen animasyonları toplama/çarpma ile birleştirir. Desteklenmeyen tarayıcı bildirimi yok sayar. |
| prefers-reduced-motion | Chrome 74+, Firefox 63+, Safari 10.1+ | İşletim sistemi ayarını okur; ayar kapalıysa sorgu hiç eşleşmez, kodun normal çalışır. |
Yaygın hatalar
İkinci animation bildirimi ilkini eziyor
Aynı seçicide iki
animationsatırı yazarsan ikincisi ilkini tamamen geçersiz kılar — birleşmezler. Birden fazla animasyon tek bildirimde virgülle sıralanır:animation: a 1s infinite, b 2s linear infinite;display: none olan eleman animasyon çalıştırmaz
Animasyon yalnızca render ağacındaki elemanlarda ilerler. Giriş animasyonu için
display: none'dandisplay: block'a geçmek yerineopacity+visibilityikilisini ya da@starting-stylekuralını kullan.fill-mode unutulduğu için eleman geri sıçrıyor
Varsayılan
animation-fill-mode: noneolduğundan animasyon bitince eleman son karesini değil kendi statik stilini gösterir. Bitiş durumunun kalması gerekiyorsaforwardsşarttır.@keyframes adları global bir isim alanında
Aynı ada sahip iki
@keyframesbloğu varsa, belge sırasında en sonda tanımlanan kazanır — özgüllük kuralları burada işlemez. Efektleri kendi projene taşırken adlara önek ver.Birimsiz sayı animasyonu bozar
transform: translateY(10)geçersizdir ve o kare bütünüyle atılır, hata da vermez. Uzunluk gerektiren her yerde birim yaz; sıfır için0kabul edilir.
Sıkça sorulan sorular
- @keyframes ile transition arasındaki fark nedir?
- transition iki durum arasında ve mutlaka bir tetikleyiciyle (hover, sınıf değişimi) çalışır; ara durum tanımlayamazsın. @keyframes istediğin kadar ara kareye sahiptir, tetikleyici gerektirmeden sayfa yüklenince başlar ve sonsuz tekrarlanabilir. Basit hover geçişleri için transition, sürekli hareket için @keyframes doğru seçim.
- Animasyonu JavaScript olmadan durdurabilir miyim?
- Evet. `animation-play-state: paused` animasyonu bulunduğu karede dondurur. `.kart:hover .ikon { animation-play-state: paused; }` yazarak fare üstüne gelince duran bir animasyon elde edersin. Bir onay kutusunun `:checked` durumuyla da aynı şey yapılabilir.
- Animasyon neden bittikten sonra ilk hâline dönüyor?
- Çünkü varsayılan doldurma modu `none`. Animasyon süresi dolduğunda tarayıcı anahtar kare stillerini bırakır ve elemanın kendi bildirimlerine geri döner. `animation-fill-mode: forwards` yazmak son karenin kalıcı olmasını sağlar.
- Kaç animasyonu aynı anda çalıştırabilirim?
- Teknik bir sınır yok; tek elemanda virgülle onlarca animasyon tanımlanabilir. Pratik sınır performanstır: yalnızca transform ve opacity animasyonlayan efektler compositor'da çalıştığı için düzinelercesi sorunsuz döner, layout tetikleyen animasyonlarda birkaç tanesi bile kare düşürebilir.
- Animasyonu ekrana girince başlatmanın saf CSS yolu var mı?
- `animation-timeline: view()` ile kaydırma ilerlemesine bağlı animasyon yazılabilir (Chrome 115+, Safari 26+). Firefox'ta henüz yok, dolayısıyla kritik içerikte IntersectionObserver ile sınıf eklemek hâlâ daha güvenli yöntem.
İlgili rehberler
- :hover:hover ve geçişlerle etkileşim efektleriFare üstüne gelme durumunu yakalamak, geçişleri doğru özelliklerde yumuşatmak ve dokunmatik ekranda takılan hover sorununu çözmek.
- ::before / ::after::before ve ::after ile katman kurmaTek bir elemanı üç katmana çıkaran sözde elemanlar: content kuralı, konumlandırma, z-index sırası ve nerede kullanılmayacağı.
- --custom-propertyCSS değişkenleriyle temalanabilir efekt yazmakEfektin ayarlanabilir yüzeyini değişkenlere çıkarmak: tek satırla tema değiştirmek, @property ile değişkeni animasyonlamak.
- perspective / transformperspective ve 3D dönüşümlerDüzlemsel elemanları uzaya yerleştirmek: perspektif noktası, 3D bağlam, arka yüz görünürlüğü ve kart çevirme kalıbı.
Son güncelleme:
Tüm rehberler