Tailwind CSS'te bir stili yalnızca fareyle üzerine gelindiğinde, odaklanıldığında ya da tıklanırken uygulamak için sınıfın başına durum varyantını yazarsınız: hover:bg-sky-700, focus-visible:outline-2, active:bg-sky-800, disabled:opacity-50. Varsayılan durum bu sınıflardan etkilenmez; varyant yalnızca ilgili sözde sınıf (:hover, :focus-visible, :active, :disabled) geçerliyken devreye girer. v4'te hover: ayrıca @media (hover: hover) sorgusuyla sarılır, yani yalnızca birincil giriş aygıtı üzerine gelmeyi destekliyorsa çalışır.

Bu yazıda en sık kullanılan etkileşim varyantlarının ürettiği CSS'i, dokunmatik ekranlardaki hover davranışını, focus ile focus-visible arasındaki farkı, varyantların hangi sırayla yığıldığını, not-* varyantını ve tam bir buton örneğini v4.3.5 ile derlenmiş gerçek çıktılarla inceliyoruz. Bir ebeveynin ya da kardeşin durumuna göre stil vermek (group-hover, peer-checked) group ve peer kullanımı yazısında, form durumları form stilleri: invalid, checked, placeholder yazısında; serinin tamamı Tailwind öğrenme rehberinde.

Temel etkileşim varyantları ve ürettikleri CSS

Temel etkileşim varyantları ve ürettikleri CSS: hover, focus, focus-visible, focus-within
VaryantÜretilen CSS koşuluNe zaman geçerli
hover@media (hover: hover) ve :hoverFare üzerindeyken, hover destekleyen aygıtta
focus:focusÖğe odaktayken (fare, klavye, dokunma)
focus-visible:focus-visibleTarayıcı odak göstergesini göstermeyi uygun gördüğünde
focus-within:focus-withinÖğenin kendisi veya bir alt öğesi odaktayken
active:activeÖğe basılıyken
visited:visitedBağlantı daha önce ziyaret edildiyse
disabled:disabledForm öğesi devre dışıyken
enabled:enabledForm öğesi etkinken

Tablodaki eşlemeler resmî durum sayfasının hızlı başvuru tablosuyla ve v4.3.5 derlemesiyle aynıdır. Skill'deki kısa listede de hover, focus, active, disabled ve visited bu biçimde gösterilir. Resmî sayfaya göre bu varyantlar herhangi bir utility ile kullanılabilir; yani renk dışında boyut, gölge, dönüşüm ya da görünürlük de bir duruma bağlanabilir.

v4'te hover neden (hover: hover) içinde?

Upgrade guide'a göre v4'te hover varyantı, yalnızca birincil giriş aygıtı üzerine gelmeyi destekliyorsa uygulanacak şekilde değiştirildi. Derlenen CSS bunu açıkça gösterir.

html
<a class="text-sky-700 visited:text-purple-700 hover:underline">Bağlantı</a>

v4.3.5 ile derlenen CSS:

css
/* (kısaltıldı) */
@layer utilities {
  .text-sky-700 {
    color: var(--color-sky-700);
  }
  .visited\:text-purple-700:visited {
    color: var(--color-purple-700);
  }
  @media (hover: hover) {
    .hover\:underline:hover {
      text-decoration-line: underline;
    }
  }
}

:visited doğrudan seçiciye eklenirken :hover kuralı bir medya sorgusunun içine girdi. Pratik sonucu şudur: birincil girişi dokunmatik ekran olan bir telefonda hover: stilleri dokunmayla tetiklenmez. Upgrade guide, sitesini dokunuşta hover tetiklenmesine göre kurmuş projeler için bunun sorun çıkarabileceğini söyler ve eski davranışı geri getirmek için hover varyantını kendi tanımınızla ezmeyi gösterir.

css
@import "tailwindcss" source(none);
@source inline("hover:underline");

@custom-variant hover (&:hover);

v4.3.5 ile derlenen CSS:

css
/* (kısaltıldı) */
@layer utilities {
  .hover\:underline:hover {
    text-decoration-line: underline;
  }
}

Bu tanımla medya sorgusu kalkar ve kural her aygıtta :hover seçicisiyle çalışır. Ancak upgrade guide genel öneri olarak hover'ı bir iyileştirme olarak görmeyi, sitenin çalışmasının ona bağlı olmamasını tavsiye eder, çünkü dokunmatik aygıtlar gerçekten üzerine gelemez. Bir menü yalnızca hover ile açılıyorsa, dokunmatik kullanıcı için tıklama veya odakla açılan bir yol da sunun. @custom-variant direktifinin kendisi @custom-variant ve keyfi varyantlar yazısında, dokunmatikte hover sorununun teşhisi Tailwind class çalışmıyor yazısında anlatılıyor.

focus, focus-visible ve focus-within farkı

focus: öğe hangi yolla odaklanırsa odaklansın çalışır; fareyle bir butona tıklamak da onu odağa alabilir. focus-visible: ise tarayıcının odak göstergesini göstermeyi uygun gördüğü durumlarda, skill'deki ifadeyle klavye odağında çalışır. Bu yüzden butonlarda odak halkası için genellikle focus-visible: tercih edilir: klavye kullanıcısı nerede olduğunu görür, fare kullanıcısı tıkladıktan sonra halka görmez. focus-within: ise öğenin kendisi ya da içindeki herhangi bir öğe odaktayken eşleşir; bir arama kutusunu saran çerçeveyi vurgulamak için kullanışlıdır.

html
<div class="rounded-md border border-gray-300 focus-within:border-sky-500">
  <input class="outline-none">
</div>

v4.3.5 ile derlenen CSS:

css
/* (kısaltıldı) */
@layer utilities {
  .rounded-md {
    border-radius: var(--radius-md);
  }
  .border {
    border-style: var(--tw-border-style);
    border-width: 1px;
  }
  .border-gray-300 {
    border-color: var(--color-gray-300);
  }
  .outline-none {
    --tw-outline-style: none;
    outline-style: none;
  }
  .focus-within\:border-sky-500:focus-within {
    border-color: var(--color-sky-500);
  }
}

İçteki input odaklanınca dış div'in kenarlık rengi --color-sky-500 (oklch(68.5% 0.169 237.323)) olur. Burada input'un kendi outline'ı kaldırıldığı için odak göstergesi görevini dış çerçeve üstlenir; outline'ı kaldırıp yerine hiçbir şey koymamak klavye kullanıcılarını yönsüz bırakır. Erişilebilir odak halkaları erişilebilirlik: sr-only ve focus-visible yazısında, halka ve outline sınıfları shadow ve ring yazısında.

Uygulamalı örnek: tüm durumları olan bir buton

Uygulamalı örnek: tüm durumları olan bir buton

Gerçek bir buton genellikle beş durumu birlikte taşır: normal, üzerine gelme, klavye odağı, basılı ve devre dışı. Aşağıdaki buton skill'deki buton kalıbının yapısını izler, odak için outline sınıflarını kullanır.

html
<button class="rounded-lg bg-sky-600 px-4 py-2 text-white hover:bg-sky-700 focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-sky-600 active:bg-sky-800 disabled:opacity-50 disabled:hover:bg-sky-600">Kaydet</button>

v4.3.5 ile derlenen CSS:

css
/* (kısaltıldı) */
@layer utilities {
  .rounded-lg {
    border-radius: var(--radius-lg);
  }
  .bg-sky-600 {
    background-color: var(--color-sky-600);
  }
  .px-4 {
    padding-inline: calc(var(--spacing) * 4);
  }
  .py-2 {
    padding-block: calc(var(--spacing) * 2);
  }
  .text-white {
    color: var(--color-white);
  }
  @media (hover: hover) {
    .hover\:bg-sky-700:hover {
      background-color: var(--color-sky-700);
    }
  }
  .focus-visible\:outline-2:focus-visible {
    outline-style: var(--tw-outline-style);
    outline-width: 2px;
  }
  .focus-visible\:outline-offset-2:focus-visible {
    outline-offset: 2px;
  }
  .focus-visible\:outline-sky-600:focus-visible {
    outline-color: var(--color-sky-600);
  }
  .active\:bg-sky-800:active {
    background-color: var(--color-sky-800);
  }
  .disabled\:opacity-50:disabled {
    opacity: 50%;
  }
  @media (hover: hover) {
    .disabled\:hover\:bg-sky-600:disabled:hover {
      background-color: var(--color-sky-600);
    }
  }
}

Bu çıktının en öğretici yanı sıralamadır. Varyantlı kurallar öneksiz kuralların arkasında ve sabit bir sırayla dizilir: önce hover, sonra focus-visible, sonra active, en sonda disabled. Aynı seçicilik düzeyinde sonra gelen kazandığı için butona basılı tutarken fare de üzerindeyse active:bg-sky-800, hover:bg-sky-700 kuralını ezer; kullanıcı basma anında daha koyu rengi görür. Devre dışı butonda ise üzerine gelince renk değişmesin diye disabled:hover:bg-sky-600 eklendi; bu kural :disabled:hover seçicisiyle hem daha seçici hem de daha sonradır. Tema değerleri: --color-sky-600 oklch(58.8% 0.158 241.966), --color-sky-800 oklch(44.3% 0.11 240.79), --radius-lg 0.5rem.

Bu sıra HTML'de sınıfları hangi sırada yazdığınızdan bağımsızdır. active: sınıfını listenin başına koysanız da CSS'te hover'ın arkasına yerleşir. Bu yüzden durum stillerini "son yazan kazanır" mantığıyla değil, derleyicinin sabit sırasıyla düşünün. Kart, input ve rozet gibi diğer bileşen kalıpları kart, buton ve input örnekleri yazısında.

Varyantları yığmak: sıra ne zaman önemli?

Varyantlar birbirine eklenebilir: md:hover:, dark:focus:, disabled:hover: gibi. Upgrade guide'a göre v3'te yığılmış varyantlar sağdan sola uygulanırken v4'te CSS sözdizimine benzesin diye soldan sağa uygulanır. İki sözde sınıfın yığıldığı durumda sıra yalnızca seçicideki yazılış sırasını değiştirir; aşağıdaki girdide hover:focus:underline ve focus:hover:underline birlikte derlendi.

css
/* (kısaltıldı) */
@layer utilities {
  @media (hover: hover) {
    .focus\:hover\:underline:focus:hover {
      text-decoration-line: underline;
    }
    .hover\:focus\:underline:hover:focus {
      text-decoration-line: underline;
    }
  }
}

İki seçici de aynı anda hem odakta hem üzerinde olan öğeyi seçer, sonuç aynıdır. Fark, seçici yapısını değiştiren varyantlarda ortaya çıkar. Upgrade guide'daki örnek, alt öğeleri seçen * varyantıyla first varyantının yer değiştirmesidir.

html
<ul class="py-4 *:first:pt-0 first:*:pt-0"><li></li></ul>

v4.3.5 ile derlenen CSS:

css
/* (kısaltıldı) */
@layer utilities {
  .py-4 {
    padding-block: calc(var(--spacing) * 4);
  }
  :is(.\*\:first\:pt-0 > *):first-child {
    padding-top: 0px;
  }
  :is(.first\:\*\:pt-0:first-child > *) {
    padding-top: 0px;
  }
}

*:first:pt-0 "listenin ilk çocuğu" anlamına gelir ve v4'te istenen davranış budur. first:*:pt-0 ise "liste kendi ebeveyninin ilk çocuğuysa, onun bütün çocukları" anlamına gelir; tamamen farklı bir seçicidir. v3'ten taşınan projelerde bu tür yığmaların ters çevrilmesi gerekir; geçişin geri kalanı Tailwind CSS v4 yenilikleri yazısında.

Durumları koyu mod ve kırılma noktalarıyla birleştirmek

Resmî durum sayfası yığmanın ne kadar ileri gidebileceğini dark:md:hover:bg-fuchsia-600 örneğiyle gösterir: arka plan rengi yalnızca koyu modda, md ve üstündeki ekranlarda ve fare üzerindeyken değişir. Bu sınıfı derlediğimizde üç koşul iç içe yerleşti.

css
/* (kısaltıldı) */
@layer utilities {
  @media (prefers-color-scheme: dark) {
    @media (width >= 48rem) {
      @media (hover: hover) {
        .dark\:md\:hover\:bg-fuchsia-600:hover {
          background-color: var(--color-fuchsia-600);
        }
      }
    }
  }
}

Dıştan içe sıra, sınıf adındaki soldan sağa sırayla birebir aynıdır: önce dark (varsayılan olarak prefers-color-scheme sorgusu), sonra md genişlik sorgusu, sonra hover'ın medya sorgusu ve en içte :hover seçicisi. Tüm koşullar "ve" ile bağlandığından, kural yalnızca hepsi aynı anda doğruysa uygulanır. Pratikte bu kadar uzun yığmalara nadiren ihtiyaç duyarsınız; ama aynı mantık md:hover:underline gibi kısa kombinasyonlarda da geçerlidir. --color-fuchsia-600 değeri oklch(59.1% 0.293 322.896)'dir. Koyu modu sınıf veya veri özniteliğiyle yönetmek Tailwind dark mode yazısında, genişlik önekleri responsive tasarım yazısında anlatılıyor.

not-* ile koşulu tersine çevirmek

Resmî sayfaya göre not-* varyantı bir koşul doğru değilken stil uygular. Örnekteki hover:not-focus:bg-indigo-700 sınıfı, öğe üzerine gelinmiş ama odakta değilken arka planı değiştirir. not-disabled: ise yalnızca etkin öğelere stil vermenin kısa yoludur.

html
<button class="hover:not-focus:bg-indigo-700 not-disabled:cursor-pointer"></button>

v4.3.5 ile derlenen CSS:

css
/* (kısaltıldı) */
@layer utilities {
  .not-disabled\:cursor-pointer:not(:disabled) {
    cursor: pointer;
  }
  @media (hover: hover) {
    .hover\:not-focus\:bg-indigo-700:hover:not(:focus) {
      background-color: var(--color-indigo-700);
    }
  }
}

İlginç bir ayrıntı not-hover: varyantında görülür. not-hover:opacity-75 derlendiğinde iki kural çıktı: biri .not-hover\:opacity-75:not(:hover) seçicisiyle, diğeri @media not (hover: hover) sorgusunun içinde. Yani hover desteklemeyen aygıtlarda bu stil her zaman uygulanır; bu, hover'ın medya sorgusuyla sarılmasının tutarlı bir sonucudur. not-* medya ve özellik sorgularını da tersine çevirebilir: not-supports-[display:grid]:flex derlendiğinde @supports not (display:grid) üretti.

Yapısal varyantlar: first, last, odd, even

Durum sayfasında etkileşim varyantlarıyla birlikte anlatılan yapısal varyantlar, öğenin kardeşleri arasındaki konumuna göre stil verir. Derlenen seçiciler şöyledir: first:pt-0 :first-child, last:pb-0 :last-child, odd:bg-white :nth-child(odd), even:bg-gray-50 :nth-child(even), only: :only-child, empty:hidden :empty ve nth-3: :nth-child(3). Tablo satırlarını sırayla renklendirmek ya da listenin ilk ve son öğesinin boşluğunu sıfırlamak için JavaScript gerekmez. Bunlar etkileşim varyantlarıyla da yığılabilir: odd:hover:bg-gray-100 derlendiğinde @media (hover: hover) içinde .odd\:hover\:bg-gray-100:nth-child(odd):hover seçicisi oluştu. Yani yalnızca tek sıradaki satırlar, üzerine gelindiğinde açık gri arka plan alır; çift satırlar bu kuraldan hiç etkilenmez. Tablo satırlarına hover vurgusu vermek istiyorsanız, satırların hepsine aynı sınıfı verip yapısal varyantı yalnızca zebra deseni için kullanmak daha sade bir sonuç verir.

Aynı özelliği yazan iki sınıf

Durum varyantları çakışmayı çözmez, sadece koşul ekler. Bir öğede hem bg-sky-500 hem bg-red-500 varsa, derlenen dosyada .bg-red-500 önce, .bg-sky-500 sonra geldi; dolayısıyla HTML'de hangisini sona yazarsanız yazın normal durumda gök mavisi kazanır. Hover rengi ise ayrı bir kural olduğu için bundan etkilenmez. Normal durumda tek bir arka plan sınıfı bırakın; konunun ayrıntısı ve ! important işareti çakışan sınıflar ve important yazısında.

Sık yapılan hatalar

Sık yapılan hatalar: Dokunmatikte hover beklemek, Butonlarda focus: ile halka göstermek, Outline'ı kaldırıp yerine bir şey koymamak, HTML sırasına güvenmek
  • Dokunmatikte hover beklemek: v4'te hover: yalnızca (hover: hover) aygıtlarda çalışır. Önemli işlevleri hover'a bağlamayın.
  • Butonlarda focus: ile halka göstermek: Fareyle tıklayınca da halka görünür. Klavye odağı için focus-visible: daha uygundur.
  • Outline'ı kaldırıp yerine bir şey koymamak: outline-none tek başına odak göstergesini yok eder.
  • HTML sırasına güvenmek: active: ile hover: arasındaki öncelik derleyicinin sabit sırasından gelir, sınıf listesindeki konumdan değil.
  • v3 alışkanlığıyla ters yığmak: v4'te varyantlar soldan sağa uygulanır; first:*: ile *:first: farklı seçicilerdir.
  • Devre dışı butonda hover'ı unutmak: disabled:opacity-50 rengi soldurur ama hover rengini durdurmaz; gerekiyorsa disabled:hover: ile ezin veya disabled:pointer-events-none kullanın.

Sık Sorulan Sorular

Tailwind hover mobilde neden çalışmıyor?

v4'te hover: kuralları @media (hover: hover) içinde üretilir. Birincil girişi dokunmatik olan aygıtlar bu sorguyu karşılamadığı için kural uygulanmaz. Eski davranış gerekiyorsa @custom-variant hover (&:hover); tanımlanabilir, ama önerilen yol hover'ı yalnızca bir iyileştirme olarak kullanmaktır.

focus ve focus-visible hangisini kullanmalıyım?

Form alanlarında odak her zaman görünür olmalıysa focus:, butonlar ve bağlantılarda yalnızca klavye odağında halka istiyorsanız focus-visible: uygundur.

Birden çok varyantı aynı sınıfta kullanabilir miyim?

Evet. dark:md:hover:bg-fuchsia-600 gibi yığmalar çalışır; derlemede koyu mod, genişlik ve hover sorguları iç içe oluşur. Soldaki varyant dıştaki sarmalayıcıdır.

hover ile group-hover arasındaki fark nedir?

hover: öğenin kendi üzerine gelinmesine bakar. group-hover: ise group sınıflı bir ataya gelinmesine bakar; derlendiğinde :is(:where(.group):hover .group-hover\:...) gibi bir soy seçici üretir. Böylece kartın tamamına gelinince içindeki başlığın rengi değişebilir. Ayrıntısı group ve peer kullanımı yazısında.

Hover efektine geçiş animasyonu nasıl eklenir?

Durum varyantı yalnızca son değeri belirler; yumuşak geçiş için öğeye transition ve duration-* sınıfları eklenir. Bu sınıflar transition, duration ve ease yazısında.

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: Tailwind öğrenme rehberi · group ve peer · Form durumları · Erişilebilirlik ve focus-visible · Transition ve duration · Responsive tasarım