- 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
div
container should be styled when a nestedbutton
is focused. - The focus should only apply for keyboard users (
focus-visible
), not mouse clicks.
:has
with :focus-visible
Solution 1: Use 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
div
gets a blue ring when its childbutton
is keyboard-focused.
Note: Check browser support for the :has
selector on Can I Use.
peer
and absolute
Positioning
Solution 2: Use 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
button
is marked as apeer
. - The
div
withpeer-focus-visible
styles the container when thebutton
is keyboard-focused. - Setting
z-index
ensures thebutton
remains interactive and thediv
is styled correctly.
Try this example on Tailwind Play.
FAQs
focus-within
and focus-visible
directly together?
1. Can I use No, CSS doesn’t support focus-within-visible
natively. You’ll need to use alternatives like :has
or peer
utilities in Tailwind CSS.
:has
?
2. What if my browser doesn’t support You can use the peer
approach, which works universally without requiring modern browser features like :has
.
peer-focus-visible
better for accessibility?
3. Why is 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.