- Published on
Tailwind CSS: Combining focus-within and focus-visible Effectively
- Authors
- Name
- Ripal & Zalak
Tailwind CSS: How to Combine focus-within and focus-visible
When working with interactive elements in Tailwind CSS, you may want to style a container (e.g., a div) when an inner element (like a button) is focused, but only for keyboard focus (not mouse clicks). While focus-within covers all types of focus, we need to combine it with focus-visible for accessibility and keyboard-specific styles.
Unfortunately, there’s no native focus-within-visible pseudo-class in CSS. But there are workarounds using Tailwind's utilities and modern CSS techniques.
Problem
Here’s the scenario:
- A
divcontainer should be styled when a nestedbuttonis focused. - The focus should only apply for keyboard users (
focus-visible), not mouse clicks.
Solution 1: Use :has with :focus-visible
Modern browsers support the :has selector, which allows us to check if a child element matches a condition (e.g., :focus-visible). You can implement this in Tailwind CSS using arbitrary variants.
<div
class="rounded-lg bg-green-100 px-20 py-20 [&:has(:focus-visible)]:ring-4 [&:has(:focus-visible)]:ring-blue-300"
>
<button class="bg-green-200 px-6 py-3 focus:outline-none">Focusable Button</button>
</div>
Explanation:
[&:has(:focus-visible)]is an arbitrary variant in Tailwind that applies the style when any child element matches:focus-visible.- In this example, the
divgets a blue ring when its childbuttonis keyboard-focused.
Note: Check browser support for the :has selector on Can I Use.
Solution 2: Use peer and absolute Positioning
If :has isn’t an option, you can achieve similar functionality using Tailwind's peer utility.
<div class="flex h-screen items-center justify-center">
<div class="relative rounded-lg bg-green-100 px-20 py-20">
<button class="peer relative z-[1] bg-green-200 px-6 py-3 focus:outline-none">
Focusable Button
</button>
<div
class="absolute inset-0 z-[0] rounded-lg peer-focus-visible:ring-4 peer-focus-visible:ring-blue-300"
></div>
</div>
</div>
Explanation:
- The
buttonis marked as apeer. - The
divwithpeer-focus-visiblestyles the container when thebuttonis keyboard-focused. - Setting
z-indexensures thebuttonremains interactive and thedivis styled correctly.
Try this example on Tailwind Play.
FAQs
1. Can I use focus-within and focus-visible directly together?
No, CSS doesn’t support focus-within-visible natively. You’ll need to use alternatives like :has or peer utilities in Tailwind CSS.
2. What if my browser doesn’t support :has?
You can use the peer approach, which works universally without requiring modern browser features like :has.
3. Why is peer-focus-visible better for accessibility?
peer-focus-visible ensures that styles are only applied during keyboard focus, improving the user experience for keyboard and assistive technology users.
4. How do I debug Tailwind focus states?
Use browser dev tools to inspect elements and toggle focus states manually. Tailwind's JIT mode also makes it easier to see applied classes in real-time.
