With Tailwind's release of its Just-In-Time compiler, the peer
class has been introduced. The peer class is practical when changing an HTML element's behavior based on a previous sibling's state. Radio buttons chosen by label click are such a use-case.
How to choose radio by label click
A label click will select a radio by matching two attributes:
- radio button: id
- label: for
Tailwind Peer class
You can add peer behavior by adding two classes to the HTML.
- Add the
peer
class to the HTML tag you want to observe the state for. - Add the
peer-checked
class, followed by the desired behavior change, to a sibling element.
Single radio button
Let's start with a single radio button.
<input class="sr-only peer" type="radio" value="yes" name="answer" id="answer_yes">
<label class="flex p-5 bg-white border border-gray-300 rounded-lg cursor-pointer focus:outline-none hover:bg-gray-50 peer-checked:ring-green-500 peer-checked:ring-2 peer-checked:border-transparent" for="answer_yes">Yes</label>
<div class="absolute hidden w-5 h-5 peer-checked:block top-5 right-3">
👍
</div>
Once the input radio with a class peer
is chosen, its sibling label and div will change:
- The label gets a green border.
Due to
peer-checked:ring-green-500 peer-checked:ring-2 peer-checked:border-transparent
- The icon, initially hidden, appears.
Due to
peer-checked:block
Multiple radio buttons
A single radio button does not make much sense, so let's add in 2 other options and display the radio buttons in a grid.
<ul class="grid grid-cols-3 gap-x-5 m-10 max-w-md mx-auto">
<li class="relative">
<input class="sr-only peer" type="radio" value="yes" name="answer" id="answer_yes">
<label class="flex p-5 bg-white border border-gray-300 rounded-lg cursor-pointer focus:outline-none hover:bg-gray-50 peer-checked:ring-green-500 peer-checked:ring-2 peer-checked:border-transparent" for="answer_yes">Yes</label>
<div class="absolute hidden w-5 h-5 peer-checked:block top-5 right-3">
👍
</div>
<li class="relative">
<input class="sr-only peer" type="radio" value="no" name="answer" id="answer_no">
<label class="flex p-5 bg-white border border-gray-300 rounded-lg cursor-pointer focus:outline-none hover:bg-gray-50 peer-checked:ring-red-500 peer-checked:ring-2 peer-checked:border-transparent" for="answer_no">No</label>
<div class="absolute hidden w-5 h-5 peer-checked:block top-5 right-3">
👎
</div>
</li>
<li class="relative">
<input class="sr-only peer" type="radio" value="maybe" name="answer" id="answer_maybe">
<label class="flex p-5 bg-white border border-gray-300 rounded-lg cursor-pointer focus:outline-none hover:bg-gray-50 peer-checked:ring-yellow-500 peer-checked:ring-2 peer-checked:border-transparent" for="answer_maybe">Maybe</label>
<div class="absolute hidden w-5 h-5 peer-checked:block top-5 right-3">
🤔
</div>
</li>
</ul>
You can combine multiple peer classes into a single document as long as a parent class (in this case, the <li>
) acts as a separator.
That's it.
Purposeful radio buttons without any JS or a custom CSS class.
Top comments (7)
Thank you very much for this
thanks for this thread
thanks for your works.
It's worth noting that the ordering of elements is important, if the
label
is placed before theinput
it will not work.Thank you very very much... 😭
Thanks very helpful
Really helpful, thanks~~~