Tip 14/72

Use of `peer` Variant

Use `peer-{modifier}` to style an element based on the state of its sibling.

TailwindCSS’s peer-{modifier} variant is incredibly useful for styling elements based on the state of their sibling elements. Below are practical use cases demonstrating the power of the peer variant.

Input validation

Display an error message dynamically when the sibling input is invalid.

Type an invalid email and click away to see the error message.
<div class="space-y-2.5">
    <label 
        for="email" 
        class="text-gray-950 text-sm dark:text-white"
    >
        Your Email
    </label>
    <input 
        type="email" 
        id="email" 
        class="peer block w-full px-3 h-9 text-sm rounded-lg border shadow-sm shadow-gray-950/5 outline-hidden focus:ring-primary-600 focus:ring-2 dark:bg-gray-800/25 dark:border-gray-800" 
        placeholder="Enter your email" 
    />
    <div class="hidden text-sm text-danger-600 peer-[:user-invalid]:block dark:text-danger-400">Please enter a valid email</div>
</div>

Switch or Toggle

Highlight a toggle or switch UI when its associated input is checked.

<form>
    <label for="sw1" class="block relative h-5 w-8 bg-gray-100 rounded-full border border-gray-300 has-checked:bg-primary-600 has-checked:border-white/15 dark:border-gray-700/75 dark:bg-gray-800/50" >
        <input 
            id="sw1" 
            name="sw1"
            type="checkbox" 
            hidden 
            class="peer"
        />
        <div class="size-3 absolute border border-gray-300 left-1 shadow-xs inset-y-0 my-auto rounded-full bg-white duration-300 peer-checked:translate-x-2.5 dark:border-transparent peer-checked:border-transparent"></div>
    </label>
</form>

Radio

Highlight a radio indicator when its sibling input is checked.

<form>
    <label class="group flex relative size-5 bg-gray-100 rounded-full border border-gray-300 has-checked:bg-primary-600 has-checked:border-white/15 dark:border-gray-700/75 dark:bg-gray-800/50" for="radio">
        <input id="radio" type="radio" hidden className="peer"/>
        <div class="size-2 absolute inset-0 m-auto shadow-xs rounded-full opacity-0 scale-50 group-hover:opacity-100 group-hover:scale-100 bg-gray-200 duration-300 peer-checked:opacity-100 peer-checked:scale-100 peer-checked:bg-white dark:bg-gray-700"></div>
    </label>
</form>