Style a Child Based on Parent or Sibling State
Group & Peer
The group variant styles children when an ancestor is interacted with, and peer styles an element based on a previous sibling.
What you'll learn
- Use group with group-hover and group-focus
- Use peer with peer-checked and peer-invalid
- Disambiguate with named groups and peers
Sometimes a child should react to its parent’s state, or an element should react to a sibling’s state. The group and peer markers make this possible with pure CSS.
group: React to an Ancestor
Mark an ancestor with class="group", then prefix child utilities with group-hover:, group-focus:, and friends:
<a href="#" class="group block rounded-lg border p-4">
<h3 class="font-semibold group-hover:text-blue-600">Card title</h3>
<span class="opacity-0 group-hover:opacity-100 transition">
Read more →
</span>
</a> Hovering anywhere on the card reveals the call to action and recolors the title. This powers dropdowns, hover cards, and reveal-on-hover affordances without a line of script.
peer: React to a Sibling
Mark an element class="peer" and a following sibling can respond with peer-checked:, peer-invalid:, peer-focus:, and so on:
<input type="email" required
class="peer border rounded px-3 py-2">
<p class="hidden peer-invalid:block text-sm text-red-600">
Please enter a valid email.
</p> The error message appears only when the input is invalid. The peer must come before the styled element in the markup because CSS sibling selectors only look backward.
Named Groups and Peers
When groups nest, give them names so the right ancestor is targeted:
<li class="group/item">
<button class="group/btn">
<span class="group-hover/item:underline">label</span>
<svg class="opacity-50 group-hover/btn:opacity-100">...</svg>
</button>
</li> group/item and group/btn create distinct scopes, so group-hover/item: reacts to the list item while group-hover/btn: reacts to the button. Named peers work the same way with peer/name and peer-checked/name:.