Varianti group e peer
Utilizzi i pattern group e peer per stilizzare gli elementi figli in base allo stato di un elemento genitore o fratello.
Varianti group e peer è una lezione Tailwind CSS Academy gratuita su CoddyKit. Questa è la lezione 4 di 4. Puoi leggere la lezione completa qui gratuitamente — poi esercitati direttamente nel browser con un editor di codice integrato e un tutor IA disponibile 24/7. Fa parte del percorso di apprendimento Tailwind CSS Academy, e i tuoi progressi si sincronizzano tra il web e l'app CoddyKit. Il corso Tailwind CSS Academy include 4 lezioni in totale.
Parti di questa lezione non sono ancora state tradotte e vengono mostrate in inglese.
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.
Domande Frequenti
La lezione «Varianti group e peer» è gratuita?
Sì — il testo completo di «Varianti group e peer» è gratuito qui sul web. Per esercitarvi in modo interattivo (un editor di codice integrato e un tutor IA 24/7) e sbloccare il resto del corso Tailwind CSS Academy, passa a CoddyKit PRO. Il corso Tailwind CSS Academy include 4 lezioni in totale.
Cosa imparerò in «Varianti group e peer»?
Utilizzi i pattern group e peer per stilizzare gli elementi figli in base allo stato di un elemento genitore o fratello. Eserciti Tailwind CSS Academy con codice pratico che esegui direttamente nel browser, e un tutor IA 24/7 risponde alle tue domande mentre lavori sulla lezione.
Ho bisogno di esperienza per iniziare Tailwind CSS Academy?
Non è richiesta alcuna esperienza precedente. Tailwind CSS Academy su CoddyKit è strutturato per principianti e studenti avanzati, quindi puoi iniziare da qui o dall'inizio e procedere al tuo ritmo. Questa è la lezione 4 di 4.
Quanto tempo richiede la lezione «Varianti group e peer»?
La maggior parte delle lezioni CoddyKit richiede circa 5–10 minuti. Ogni lezione è breve e interattiva, quindi fai progressi costanti e riprendi esattamente da dove hai lasciato su web e app.
Posso scrivere ed eseguire codice in questa lezione Tailwind CSS Academy?
Sì. Ogni lezione Tailwind CSS Academy include un editor di codice integrato, quindi scrivi ed esegui codice reale direttamente nel tuo browser e ricevi feedback istantaneo dall'IA — nessuna configurazione locale necessaria.
Tutte le lezioni di questo corso
- Varianti hover e active
- Varianti focus e focus-visible
- Varianti disabled e placeholder
- Varianti group e peer