Varian Group dan Peer
Gunakan pola group dan peer untuk menata elemen anak berdasarkan keadaan elemen induk atau elemen saudara.
Varian Group dan Peer adalah pelajaran Tailwind CSS Academy gratis di CoddyKit. Ini adalah pelajaran 4 dari 4. Kamu bisa membaca pelajaran lengkapnya di bawah secara gratis — lalu praktikkan langsung di browser dengan editor kode bawaan dan tutor AI 24/7. Ini adalah bagian dari jalur belajar Tailwind CSS Academy, dan progresmu tersinkronisasi di web dan aplikasi CoddyKit. Kursus Tailwind CSS Academy mencakup 4 pelajaran total.
Bagian dari pelajaran ini belum diterjemahkan dan ditampilkan dalam bahasa Inggris.
Styling Children Based on Parent State
A common UI challenge is needing to style a child element based on the state of its parent. In plain CSS, this requires the parent-child combinator and custom class names. Tailwind's group and group-* variants solve this cleanly: mark the parent with the group class and prefix any child utility with group-hover:, group-focus:, or other group variants to apply those styles when the parent enters that state.
<!-- Arrow icon appears only on card hover -->
<div class="group flex items-center gap-3 bg-white border rounded-xl p-4 hover:border-blue-500 cursor-pointer transition-colors">
<div class="flex-1">
<h3 class="font-semibold">Settings</h3>
<p class="text-sm text-gray-500">Manage your account</p>
</div>
<!-- Arrow is invisible by default, visible on group hover -->
<span class="text-gray-400 group-hover:text-blue-500 group-hover:translate-x-1 transition-all">
→
</span>
</div>How group Works
The group class on a parent element creates a grouping scope. All descendants can then reference this scope using group-{variant}: prefixes. The magic happens via Tailwind's generated CSS: group-hover:text-blue-500 compiles to .group:hover .group-hover\:text-blue-500. This means the child's style changes only when the ancestor with the group class is hovered — not when any ancestor is hovered.
<!-- How group generates CSS -->
<!-- The group class on parent enables hover detection -->
<div class="group">
<!-- group-hover: applies when the group div above is hovered -->
<h2 class="text-gray-700 group-hover:text-blue-600 transition-colors">
Title changes when parent is hovered
</h2>
<p class="text-gray-500 group-hover:text-gray-700 transition-colors">
Description also changes
</p>
</div>group-hover for Card Overlays
A popular use case for group-hover is revealing an overlay or action buttons on a card when the user hovers over the entire card, not just the button. By making the card a group and the overlay opacity-0 group-hover:opacity-100, the overlay appears precisely when the cursor enters the card boundary — creating an elegant reveal effect without JavaScript.
<!-- Image card with hover overlay revealed via group -->
<div class="group relative w-48 h-48 rounded-xl overflow-hidden cursor-pointer">
<!-- Background image -->
<div class="absolute inset-0 bg-gradient-to-br from-purple-500 to-pink-600"></div>
<!-- Overlay: invisible by default, visible on group hover -->
<div class="absolute inset-0 bg-black/60 opacity-0 group-hover:opacity-100 transition-opacity flex items-center justify-center">
<button class="bg-white text-gray-900 px-4 py-2 rounded-lg font-medium text-sm">
View Details
</button>
</div>
</div>Named Groups for Nested Scopes
When you have nested groups, Tailwind's named group feature prevents ambiguity. Apply group/name to mark a group with an identifier, and use group-hover/name: on children to reference that specific ancestor. Without named groups, group-hover: always references the nearest ancestor with the group class, which may not be what you want in deeply nested structures.
<!-- Named groups prevent ambiguity in nested structures -->
<div class="group/card border rounded-xl p-4 hover:shadow-md transition-shadow">
<h3 class="font-bold group-hover/card:text-blue-600 transition-colors">Card Title</h3>
<!-- Inner list item group -->
<ul class="mt-3 space-y-2">
<li class="group/item flex items-center gap-2 cursor-pointer rounded px-2 py-1 hover:bg-gray-50">
<span class="text-sm group-hover/item:font-medium">First item</span>
<span class="ml-auto text-gray-400 opacity-0 group-hover/item:opacity-100 transition-opacity">→</span>
</li>
<li class="group/item flex items-center gap-2 cursor-pointer rounded px-2 py-1 hover:bg-gray-50">
<span class="text-sm group-hover/item:font-medium">Second item</span>
<span class="ml-auto text-gray-400 opacity-0 group-hover/item:opacity-100 transition-opacity">→</span>
</li>
</ul>
</div>group-focus for Interactive Parents
group-focus: triggers when the parent receives keyboard focus. This is particularly useful for custom file upload components, color pickers, and any compound widget where the container is the focusable element but inner labels or icons need to change appearance. The result is an accessible compound widget that shows focus cues on all its parts simultaneously.
<!-- Custom file upload with group-focus styling -->
<label class="group flex flex-col items-center justify-center border-2 border-dashed border-gray-300 rounded-xl p-8 cursor-pointer hover:border-blue-400 focus-within:border-blue-500 focus-within:ring-2 focus-within:ring-blue-500/20 transition-all">
<input type="file" class="sr-only" />
<div class="text-4xl mb-3 group-hover:scale-110 transition-transform">📁</div>
<p class="font-medium text-gray-600 group-hover:text-blue-600 transition-colors">Click to upload</p>
<p class="text-sm text-gray-400 mt-1">or drag and drop</p>
</label>Peer Variant Introduction
While group works parent-to-child, peer works sibling-to-sibling. Mark one element with the peer class, then use peer-{state}: on a following sibling to style it based on the peer's state. Critically, peer selectors only work with following siblings in the DOM — the peer element must appear before the styled element in the HTML source order.
<!-- Checkbox peer controls a sibling label's appearance -->
<label class="flex items-center gap-3 cursor-pointer">
<!-- Peer: the checkbox -->
<input type="checkbox" class="peer sr-only" />
<!-- Custom checkbox visual -->
<div class="w-5 h-5 border-2 border-gray-400 rounded peer-checked:bg-blue-500 peer-checked:border-blue-500 flex items-center justify-center transition-all">
<svg class="w-3 h-3 text-white opacity-0 peer-checked:opacity-100 transition-opacity" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="3" d="M5 13l4 4L19 7" />
</svg>
</div>
<!-- Label changes on peer check -->
<span class="text-gray-700 peer-checked:text-blue-600 peer-checked:font-medium transition-colors">
I agree to the terms
</span>
</label>peer for Form Validation Labels
The peer pattern shines for showing validation messages that react to the input's state. An input with the required attribute can be paired with a sibling error message using peer-invalid:visible. When the field is invalid (empty on submit or contains a malformed value), the sibling error message becomes visible — all without JavaScript event listeners.
<!-- Input with CSS-only validation message via peer -->
<div class="max-w-sm space-y-1">
<label class="block text-sm font-medium">Email</label>
<!-- peer: marks the input -->
<input
type="email"
required
placeholder="Enter valid email"
class="peer w-full border border-gray-300 rounded-lg px-4 py-2 focus:outline-none focus:ring-2 focus:ring-blue-500 invalid:border-red-400 invalid:ring-red-400/20"
/>
<!-- Sibling error: hidden until peer is invalid -->
<p class="hidden peer-invalid:flex text-sm text-red-500 gap-1 items-center">
⚠ Please enter a valid email address
</p>
</div>peer-focus for Floating Labels
The floating label pattern — where a placeholder rises to become a label when the input is focused — can be built with peer and peer-focus:. The input gets the peer class, and the label (appearing after the input in the DOM) uses peer-focus:-translate-y-6 peer-focus:text-xs peer-focus:text-blue-500 to float upward when the input is focused.
<!-- Floating label with peer-focus -->
<div class="relative max-w-sm">
<input
type="text"
placeholder=" "
class="peer w-full border border-gray-300 rounded-lg px-4 pt-6 pb-2 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-blue-500"
/>
<!-- Label floats when input is focused or has content -->
<label class="absolute left-4 top-4 text-gray-400 text-sm transition-all peer-focus:top-1.5 peer-focus:text-xs peer-focus:text-blue-500 peer-[:not(:placeholder-shown)]:top-1.5 peer-[:not(:placeholder-shown)]:text-xs pointer-events-none">
First Name
</label>
</div>Named Peers for Multiple Siblings
Like named groups, you can create named peers with peer/name and reference them with peer-checked/name:. This lets you have multiple peer elements on the same level and style different siblings based on different peers. Without named peers, peer-checked: would reference the most recent previous sibling with the peer class.
<!-- Named peers for radio-controlled tabs -->
<div class="space-y-2">
<!-- Radio inputs as peers -->
<input type="radio" name="tab" id="tab1" class="peer/tab1 sr-only" checked />
<input type="radio" name="tab" id="tab2" class="peer/tab2 sr-only" />
<!-- Tab labels react to their specific peer -->
<div class="flex border-b">
<label for="tab1" class="px-4 py-2 cursor-pointer border-b-2 border-transparent peer-checked/tab1:border-blue-500 peer-checked/tab1:text-blue-600 font-medium transition-colors">
Overview
</label>
<label for="tab2" class="px-4 py-2 cursor-pointer border-b-2 border-transparent peer-checked/tab2:border-blue-500 peer-checked/tab2:text-blue-600 font-medium transition-colors">
Settings
</label>
</div>
</div>group-checked for List Selection
Custom selection lists where clicking a row selects it benefit greatly from group combined with checkboxes. Mark each list row as a group, hide the actual checkbox input with sr-only, and use group-has-[:checked]: (Tailwind v3.4+) or JavaScript class toggling to change the row's background. This creates keyboard-accessible, visually rich selection lists without complex event handling.
<!-- Selectable list rows using group -->
<ul class="divide-y border rounded-xl overflow-hidden max-w-sm">
<li class="group flex items-center gap-3 px-4 py-3 has-[:checked]:bg-blue-50 has-[:checked]:border-l-4 has-[:checked]:border-l-blue-500 cursor-pointer transition-colors">
<input type="checkbox" class="w-4 h-4 text-blue-600 rounded" />
<span class="font-medium">Alice Johnson</span>
<span class="ml-auto text-sm text-gray-400">Admin</span>
</li>
<li class="group flex items-center gap-3 px-4 py-3 has-[:checked]:bg-blue-50 has-[:checked]:border-l-4 has-[:checked]:border-l-blue-500 cursor-pointer transition-colors">
<input type="checkbox" class="w-4 h-4 text-blue-600 rounded" />
<span class="font-medium">Bob Smith</span>
<span class="ml-auto text-sm text-gray-400">Editor</span>
</li>
</ul>Real Group and Peer Use Case
Here is a feature-rich pricing card that uses both group and highlighting. When you hover the card, the CTA button changes color (group-hover), and when checked as the recommended plan, the entire card updates its border and background. This combination of group, peer, and state variants creates interactive UI without any JavaScript.
<!-- Pricing card with group-hover on CTA -->
<div class="group bg-white border-2 border-gray-200 hover:border-blue-500 rounded-2xl p-6 max-w-xs transition-all duration-300 cursor-pointer">
<div class="mb-4">
<span class="text-sm font-medium text-blue-600 bg-blue-50 px-3 py-1 rounded-full">Popular</span>
</div>
<h3 class="text-xl font-bold">Pro Plan</h3>
<p class="text-4xl font-bold mt-2">$29<span class="text-base font-normal text-gray-500">/mo</span></p>
<ul class="mt-4 space-y-2 text-sm text-gray-600">
<li>✓ Unlimited projects</li>
<li>✓ Priority support</li>
<li>✓ Custom domain</li>
</ul>
<!-- CTA changes on card hover using group-hover -->
<button class="mt-6 w-full bg-gray-100 group-hover:bg-blue-600 group-hover:text-white text-gray-700 font-semibold py-2.5 rounded-xl transition-all duration-300">
Get Started
</button>
</div>Quick Check
Test your understanding of Tailwind CSS Mastery concepts from this lesson.
Lesson Recap
In this lesson you learned: group marks a parent and group-hover: / group-focus: style descendants based on the parent's state, peer marks a sibling and peer-hover: / peer-focus: / peer-checked: style following siblings based on the peer's state, and named groups and peers like group/card and peer/tab avoid ambiguity in nested or multiple-peer layouts. Next up we explore Tailwind's responsive breakpoint system.
Pertanyaan yang Sering Diajukan
Apakah pelajaran “Varian Group dan Peer” gratis?
Ya — teks lengkap “Varian Group dan Peer” gratis dibaca di sini di web. Untuk praktiknya secara interaktif (editor kode bawaan dan tutor AI 24/7) dan buka sisa kursus Tailwind CSS Academy, upgrade ke CoddyKit PRO. Kursus Tailwind CSS Academy mencakup 4 pelajaran total.
Apa yang akan aku pelajari di “Varian Group dan Peer”?
Gunakan pola group dan peer untuk menata elemen anak berdasarkan keadaan elemen induk atau elemen saudara. Kamu berlatih Tailwind CSS Academy dengan kode praktik yang langsung kamu jalankan di browser, dan tutor AI 24/7 menjawab pertanyaanmu saat kamu mengerjakan pelajaran ini.
Apakah aku perlu pengalaman untuk memulai Tailwind CSS Academy?
Tidak diperlukan pengalaman sebelumnya. Tailwind CSS Academy di CoddyKit dirancang untuk pemula hingga pelajar tingkat lanjut, jadi kamu bisa memulai di sini atau dari awal dan belajar sesuai kecepatan kamu sendiri. Ini adalah pelajaran 4 dari 4.
Berapa lama pelajaran “Varian Group dan Peer” memakan waktu?
Sebagian besar pelajaran CoddyKit memakan waktu sekitar 5–10 menit. Setiap pelajaran ringkas dan interaktif, jadi kamu membuat kemajuan stabil dan melanjutkan dari tempat kamu tinggalkan di web dan aplikasi.
Bisakah aku menulis dan menjalankan kode dalam pelajaran Tailwind CSS Academy ini?
Ya. Setiap pelajaran Tailwind CSS Academy menyertakan editor kode bawaan, jadi kamu menulis dan menjalankan kode nyata langsung di browser dan mendapatkan umpan balik AI instan — tidak diperlukan penyiapan lokal.
Semua pelajaran dalam kursus ini
- Varian Hover dan Aktif
- Varian Fokus dan Fokus Terlihat
- Varian Nonaktif dan Placeholder
- Varian Group dan Peer