hover: cuma bereaksi ke elemen itu sendiri. Kadang yang kamu mau lain: kursor di atas card, tapi judul di dalamnya yang berubah warna. Atau checkbox dicentang, tapi teks di sebelahnya yang berubah. Untuk itu Tailwind punya group dan peer: kamu menandai elemen pemicunya, lalu elemen lain bereaksi ke keadaan si pemicu. Bayangin barisan upacara. Kalau komandan regu memberi aba-aba, semua anggota di dalam regunya bereaksi: itu group, parent memicu, anak-anaknya bereaksi. Anggota barisan juga meniru teman di depannya: yang di depan jongkok, yang di belakangnya ikut jongkok. Tapi gak ada yang bisa melihat ke belakang: itu peer, saudara di depan memicu saudara di belakangnya.
🧪 Tebakan cepat:
<label class="peer-checked:text-green-700">ditulis sebelum<input type="checkbox" class="peer">. Begitu dicentang, label-nya jadi hijau? Tebak dulu, jawabannya ada di bagian "peer: saudara di depan memicu yang di belakang".
group: parent memicu, anak bereaksi
Tandai parent dengan class group. Anak mana pun di dalamnya (anak, cucu, dan seterusnya) bisa memakai group-hover: dan bereaksi saat parent itu di-hover.
<div id="card" class="group p-4 rounded-lg border border-gray-200 cursor-pointer">
<h3 id="heading" class="font-semibold group-hover:text-blue-600">Belajar Tailwind</h3>
<p id="info" class="text-sm text-gray-400 group-hover:text-gray-600">23 materi, dari utility sampai proyek</p>
</div>
groupgak menghasilkan gaya apa pun. Dia cuma penanda: "aku pemicunya".p-4= padding 16px,rounded-lg= border-radius 8px,border= garis 1px,cursor-pointer= kursor tangan, tanda card-nya bisa diklik.font-semibold= font-weight 600.group-hover:text-blue-600membuat judul biru, tapi cuma selama kursor ada di atas.group.text-gray-400 group-hover:text-gray-600: deskripsi abu muda, lalu jadi abu tua saat card di-hover.
| Keadaan | Judul #heading |
Deskripsi #info |
|---|---|---|
| Kursor di luar card | hitam | abu muda (gray-400) |
| Kursor di mana pun di atas card | biru (blue-600) | abu tua (gray-600) |
Kursor di atas card, tapi group dihapus |
hitam | abu muda |
Satu hover di parent, dua anak berubah sekaligus. Kursornya gak perlu tepat di atas judul, cukup di mana saja di dalam card. Tanpa group, group-hover: gak punya pemicu, jadi gak ada yang berubah.
peer: saudara di depan memicu yang di belakang
Tandai elemen pemicunya dengan class peer. Saudara (elemen dengan parent yang sama) yang ditulis sesudahnya bisa memakai peer-checked:, peer-focus:, dan seterusnya.
<div class="flex flex-wrap items-center gap-2">
<input id="setuju" type="checkbox" class="peer">
<label for="setuju" class="text-gray-500 peer-checked:font-semibold peer-checked:text-green-700">Aku setuju dengan aturan kelas</label>
<p class="hidden w-full text-sm text-green-700 peer-checked:block">Siap, pendaftaranmu bisa dikirim.</p>
</div>
peerdi checkbox: dia pemicunya.peer-checked:text-green-700di label: hijau selama checkbox dicentang.hidden peer-checked:blockdi paragraf: tersembunyi (display none), lalu muncul (display block) saat dicentang. Pesan muncul tanpa satu baris JavaScript pun.
| Urutan di HTML | Dicentang? | Label | Pesan |
|---|---|---|---|
| input, label, p | belum | abu | tersembunyi |
| input, label, p | ya | hijau tebal | muncul |
| label, input, p | ya | tetap abu | muncul |
Baris terakhir: label-nya gak jadi hijau. peer cuma menjangkau saudara yang ditulis sesudahnya, persis kayak barisan yang cuma bisa melihat ke depan. Label yang ada di depan input gak kena, tapi pesan di belakangnya tetap muncul. Itu jawaban tebakannya. Mau label tampil di kiri? Tetap tulis input-nya duluan di HTML, lalu pindahkan tampilannya dengan CSS, misalnya order-first di label.
Bedanya dalam satu kalimat: group untuk parent dan anak (atas ke bawah), peer untuk saudara (kiri ke kanan, cuma ke yang sesudahnya).
Keadaan lain dan has-*
Keadaan apa pun yang dikenal hover: dan teman-temannya bisa dipakai di belakang group- atau peer-:
group-hover:,group-focus:,group-focus-within:(ada elemen di dalam parent yang sedang fokus).peer-checked:,peer-focus:,peer-invalid:(misalnya pesan errorinvisible peer-invalid:visibledi bawah input email yang isinya gak valid).
peer gak bisa mengubah parent. Kalau yang mau diubah justru pembungkusnya, pakai has-*: di parent itu: <label class="border has-checked:border-blue-600"> membuat border label biru saat ada checkbox atau radio yang dicentang di dalamnya.
📌 Group bertingkat: kasih nama
group-hover: bereaksi ke .group mana pun di atasnya. Kalau ada group di dalam group, hover di group luar ikut memicu semua anak di group dalam. Kasih nama dengan garis miring supaya jelas group yang mana:
<ul class="group/list">
<li class="group/item">
<span class="group-hover/item:text-blue-600">Flexbox</span>
</li>
</ul>
group-hover/item: cuma bereaksi saat li bernama item itu yang di-hover, bukan seluruh list.
📌 Di balik layar: CSS-nya
Tailwind v4 menerjemahkan dua class tadi jadi CSS ini:
@media (hover: hover) {
.group-hover\:text-blue-600:is(:where(.group):hover *) { color: var(--color-blue-600); }
}
.peer-checked\:text-green-700:is(:where(.peer):checked ~ *) { color: var(--color-green-700); }
:where(.group):hover *artinya "elemen ini ada di dalam.groupyang sedang di-hover".~artinya "saudara mana pun sesudah.peer". CSS gak punya selector ke saudara sebelumnya, makanya urutan HTML penting.@media (hover: hover): sejak v4, semua varian hover cuma aktif di perangkat yang punya kursor. Di HP, tap gak memicugroup-hover:.
⚠️ Jebakan yang sering ketemu
- Lupa
groupdi parent.group-hover:di anak gak bereaksi apa pun. Gak ada error, cuma diam. peerditulis sesudah targetnya. Label di depan checkbox gak pernah berubah. Taruhpeerpaling depan.- Target bukan saudara.
peercuma kena elemen dengan parent yang sama. Kalau input-nya dibungkusdivsendiri, label di luardivitu gak kena. - Info penting cuma muncul saat hover. Di HP gak ada hover, jadi tombol atau teks yang cuma tampil lewat
group-hover:gak pernah terlihat.
TL;DR: group di parent + group-hover: (atau group-focus:) di anak: anak bereaksi saat parent di-hover. peer di satu elemen + peer-checked: (atau peer-focus:, peer-invalid:) di saudara sesudahnya: saudara itu bereaksi ke keadaan si peer. Group = parent-anak, peer = saudara, dan peer harus ditulis duluan. Group bertingkat? Kasih nama: group/item + group-hover/item:. Mau mengubah parent dari keadaan anaknya? has-checked:. Card latihan: group p-4 rounded-lg border cursor-pointer (padding 16px, radius 8px, kursor tangan), judul font-semibold group-hover:text-blue-600 (weight 600).