İçeriğe geç
LibraryCSS
:hoverBaşlangıç2.879 efektte kullanılıyor

: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
all yazmak 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.
cssYükselen buton — geçiş normal hâlde tanımlı
.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>
cssTek hover, üç ayrı tepki
.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.

cssHover yalnızca fare varsa, odak her yerde
/* 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.

cssSoldan dolan alt çizgi — scaleX ile, width ile değil
.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.

ÖzellikTarayıcılarNot
:hoverTüm tarayıcılarCSS1'den beri var. Eski IE'de yalnızca bağlantılarda çalışırdı; bugün böyle bir kısıt yok.
transitionChrome 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-visibleChrome 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ş :hover iç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 height ya da background-image gibi 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-visible ile görünür bir alternatif koy.

  • Hover'da eleman boyutunu büyütüp komşuları kaydırmak

    padding veya width artırmak düzeni yeniden akıtır. Görsel büyüme için transform: 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

Son güncelleme:

Tüm rehberler