:hover ve geçişlerle etkileşim efektleri
:hover, işaretleme aygıtının bir elemanın üzerinde durduğu anı yakalayan sözde sınıftır. Tek başına yalnızca stil değiştirir; hareketi yumuşatan şey transition özelliğidir. İkisi birlikte, JavaScript'e hiç dokunmadan yükselen kartlar, dolan butonlar, açılan alt çizgiler ve kayan ikon şeritleri üretir.
Bu rehber :hover'ın hangi durumlarda tetiklendiğini, geçişin hangi özelliklerde ucuz hangilerinde pahalı olduğunu, üst elemana bakarak alt elemanı değiştirmeyi ve dokunmatik cihazlarda hover'ın neden ekranda "takılı kaldığını" anlatıyor.
Temel: durum değişimi ve geçiş
:hover seçicisi elemanın normal hâlindeki bildirimlerin üzerine yazar. Geçiş bildirimi ise normal hâle konur — :hover bloğuna değil. Bunun sebebi şudur: geçiş, stilin değiştiği anda elemanda hangi transition değeri geçerliyse ona göre çalışır. Geçişi sadece :hover içinde tanımlarsan fare üstüne gelirken yumuşak, çekilirken ani bir hareket elde edersin. Bu bazen kasıtlı bir tercihtir (hızlı çıkış, yavaş giriş) ama çoğu zaman gözden kaçmış bir hatadır.
transition kısayolu dört parça alır: hangi özellik, ne kadar sürede, hangi eğriyle, ne kadar gecikmeyle. Birden fazla özelliği virgülle sıralayabilirsin ve her birine ayrı süre verebilirsin.
- transition-property
allyazmak kolaydır ama tarayıcıyı her değişen özelliği izlemeye zorlar ve beklenmedik animasyonlara yol açar. Özellikleri tek tek saymak hem hızlı hem öngörülebilir.- transition-duration
- Hover geri bildirimi için 120–250 ms aralığı doğal hissettirir. 400 ms üstü tembel, 80 ms altı ani görünür.
- transition-delay
- Açılır menülerde küçük bir gecikme (80–150 ms) fare menüden çıkarken menünün hemen kapanmasını engeller.
.buton {
padding: 0.7rem 1.4rem;
border-radius: 0.75rem;
background: #1d4ed8;
color: #fff;
/* Geçiş burada: hem giriş hem çıkış aynı eğriyle yumuşasın */
transition:
transform 180ms ease,
box-shadow 180ms ease,
background-color 180ms ease;
}
.buton:hover {
transform: translateY(-2px);
background: #2563eb;
box-shadow: 0 12px 30px rgb(37 99 235 / 0.35);
}
.buton:active {
transform: translateY(0); /* basınca yere otursun */
}Üst elemandan alt elemanı sürmek
Karmaşık hover efektlerinin çoğu tek elemanda değil, bir kabın üzerine gelindiğinde birden fazla çocuğun aynı anda tepki vermesiyle kurulur. Bunun için :hover'ı kaba uygular, alt elemanları alt seçicilerle hedeflersin. Her çocuk kendi süresini ve gecikmesini alabilir; küçük gecikme farkları hareketi sıralı ve pahalı gösterir.
Kabın kendisi değil de bir kardeş elemanın hover'ı önemliyse ~ (genel kardeş) ve + (bitişik kardeş) birleştiricileri kullanılır. Yeni tarayıcılarda :has() ile ters yönde de çalışabilirsin: .kart:has(.buton:hover) yazmak, kartın içindeki butona gelindiğinde kartın kendisini stillendirir.
<article class="kart">
<img class="kart-gorsel" src="/kapak.jpg" alt="" />
<div class="kart-govde">
<h3>Başlık</h3>
<p class="kart-aksiyon">Devamını oku</p>
</div>
</article>.kart {
overflow: hidden; /* büyüyen görsel köşelerden taşmasın */
border-radius: 1rem;
}
.kart-gorsel {
transition: transform 400ms ease;
}
.kart-aksiyon {
opacity: 0;
transform: translateY(6px);
transition: opacity 220ms ease 60ms, transform 220ms ease 60ms;
}
.kart:hover .kart-gorsel { transform: scale(1.06); }
.kart:hover .kart-aksiyon { opacity: 1; transform: translateY(0); }Dokunmatik ekranda takılı kalan hover
Telefonda bir elemana dokunduğunda tarayıcı :hover durumunu tetikler ve parmak kalktıktan sonra da bu durumu elemanın üzerinde bırakır. Başka bir yere dokunana kadar buton "hover'da" görünür. Kartın üstüne çıkan bir katman varsa bu, içeriği kalıcı olarak kapatabilir.
Çözüm hover medya özelliğidir. @media (hover: hover) yalnızca gerçek işaretleme aygıtı bulunan cihazlarda eşleşir; dokunmatik ekranlarda blok hiç uygulanmaz. pointer: fine ile birleştirmek fare/kalem hassasiyetini de şart koşar. Hover efektlerini bu sorgunun içine almak, mobilde temiz bir statik görünüm bırakır.
Hover'ın asla tek başına bilgi taşımaması gerektiğini de unutma. Fare kullanmayan, klavyeyle gezen kullanıcı :hover'ı hiç görmez. Aynı stilleri :focus-visible ile birlikte tanımlamak hem erişilebilirliği hem klavye kullanımını kurtarır.
/* Dokunmatikte uygulanmaz — takılı hover sorunu ortadan kalkar */
@media (hover: hover) and (pointer: fine) {
.kart:hover .kart-katman { opacity: 1; }
}
/* Klavye kullanıcısı aynı bilgiyi görsün */
.kart:focus-within .kart-katman { opacity: 1; }
.buton:focus-visible {
outline: 2px solid #60a5fa;
outline-offset: 3px;
}Performans ve yaygın kalıplar
Hover efektleri sayfada onlarca kez tekrar ettiği için hangi özelliği geçirdiğin doğrudan kare hızına yansır. transform, opacity ve filter compositor'da çalışır. width, height, padding, margin, top, left ise layout'u yeniden hesaplatır; uzun bir listede tek hover bile gözle görülür takılma yaratabilir.
Çerçeve kalınlığını hover'da değiştirmek klasik bir tuzaktır: border-width layout'u kaydırır ve komşu elemanları oynatır. Bunun yerine kalınlığı sabit tutup rengi değiştir, ya da box-shadow: 0 0 0 2px ile sahte bir çerçeve çiz — gölge yerleşimi etkilemez.
Arka planı sol taraftan doldurmak gibi klasik kalıplar da width yerine transform: scaleX() ile yazılabilir. transform-origin başlangıç kenarını belirler, ::before katmanı gerçek içeriğin altında durur.
.bag {
position: relative;
text-decoration: none;
color: #e2e8f0;
}
.bag::after {
content: "";
position: absolute;
left: 0;
bottom: -2px;
width: 100%;
height: 2px;
background: #60a5fa;
transform: scaleX(0);
transform-origin: right; /* kapanırken sağa doğru toplansın */
transition: transform 240ms ease;
}
.bag:hover::after,
.bag:focus-visible::after {
transform: scaleX(1);
transform-origin: left; /* açılırken soldan gelsin */
}Katalogdan canlı örnekler
Aşağıdakiler :hover 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 |
|---|---|---|
| :hover | Tüm tarayıcılar | CSS1'den beri var. Eski IE'de yalnızca bağlantılarda çalışırdı; bugün böyle bir kısıt yok. |
| transition | Chrome 26+, Firefox 16+, Safari 6.1+, Edge 12+ | Öneksiz sürüm her yerde geçerli. `discrete` geçiş davranışı yalnızca yeni sürümlerde. |
| @media (hover: hover) / (pointer: fine) | Chrome 38+, Firefox 64+, Safari 9+ | Hibrit cihazlarda (dokunmatik dizüstü) birincil aygıta bakar; harici fare takılınca değer değişebilir. |
| :has() | Chrome 105+, Firefox 121+, Safari 15.4+ | Üst elemanı çocuğa göre seçer. Desteklenmediğinde kural bütünüyle atlanır, o yüzden yalnızca iyileştirme olarak kullan. |
| :focus-visible | Chrome 86+, Firefox 85+, Safari 15.4+ | Odak halkasını yalnızca klavye kullanımında gösterir; fareyle tıklamada görünmez. |
Yaygın hatalar
transition'ı :hover bloğuna yazmak
Geçiş
:hoveriçinde tanımlanırsa fare çekilirken geçiş kuralı artık geçerli olmaz ve eleman anında eski hâline atlar. Geçişi her zaman normal duruma yaz.transition: all kullanmak
Tarayıcı animasyonlanabilir her özelliği izler; sonradan eklediğin
heightya dabackground-imagegibi bir bildirim beklenmedik şekilde animasyonlanır. Özellikleri açıkça listele.outline: none ile odak halkasını silmek
Klavyeyle gezen kullanıcı nerede olduğunu tamamen kaybeder. Halkayı kaldıracaksan yerine
:focus-visibleile görünür bir alternatif koy.Hover'da eleman boyutunu büyütüp komşuları kaydırmak
paddingveyawidthartırmak düzeni yeniden akıtır. Görsel büyüme içintransform: scale()kullan — geometri sabit kalır, sadece boyanan piksel değişir.Sadece hover'da görünen kritik bilgi
Fiyat, açıklama veya bağlantı hedefi yalnızca hover'da görünüyorsa dokunmatik ve klavye kullanıcıları o bilgiye hiç ulaşamaz. Hover'ı süs olarak kullan, taşıyıcı olarak değil.
Sıkça sorulan sorular
- Hover efekti mobilde neden ekranda kalıyor?
- Dokunmatik tarayıcılar dokunma anında :hover durumunu tetikler ve parmak kalktığında temizlemez; kullanıcı başka bir yere dokunana kadar durum sürer. Hover kurallarını `@media (hover: hover) and (pointer: fine)` içine alarak dokunmatik cihazlarda hiç uygulanmamasını sağlayabilirsin.
- transition ile animation arasında ne zaman hangisini seçmeliyim?
- Bir durumdan diğerine geçiş varsa ve tetikleyici kullanıcı etkileşimiyse transition daha az kod ister. Ara kareler gerekiyorsa, hareket tekrarlanacaksa veya tetikleyici olmadan başlamalıysa @keyframes gerekir.
- Alt elemana gelince üst elemanı nasıl stillendiririm?
- `:has()` ile: `.kart:has(.buton:hover) { border-color: #60a5fa; }`. Chrome 105, Safari 15.4 ve Firefox 121'den itibaren çalışır. Desteklenmeyen tarayıcıda kural sessizce atlanır, o yüzden temel görünümün ona bağlı olmamalı.
- Hover geçişi kaç milisaniye olmalı?
- Küçük geri bildirimler (renk, gölge, 2-3 px kayma) için 120–200 ms; katman açılması, dönme veya kayan panel gibi büyük hareketler için 250–400 ms doğal hissettirir. Aynı arayüzde süreleri iki üç değerle sınırlamak tutarlılık sağlar.
- Hover efektim neden takılıyor?
- Büyük ihtimalle layout tetikleyen bir özelliği geçiriyorsun. width, height, padding, margin, top ve left geçişleri her karede yeniden yerleşim hesaplatır. Aynı görsel sonucu transform ve opacity ile üretmek işi GPU'ya taşır.
İlgili rehberler
- @keyframes@keyframes ile CSS animasyonuAnahtar kare tanımlamaktan zamanlama fonksiyonlarına, gecikme zincirlerinden compositor performansına kadar CSS animasyonunun tamamı.
- ::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ğı.
- 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ı.
- backdrop-filterbackdrop-filter ile cam efektiElemanın arkasındaki pikselleri bulanıklaştırmak: cam panel kalıbı, filter ile farkı ve mobil cihazlardaki gerçek maliyeti.
Son güncelleme:
Tüm rehberler