Don’t comma-separate :focus-within if you need deep browser support

Avatar of Chris Coyier
Chris Coyier on

UGURUS offers elite coaching and mentorship for agency owners looking to grow. Start with the free Agency Accelerator today.

I really like :focus-within. It’s a super useful selector that allows you to essentially select a parent element when any of its children are in focus.

Say you wanted to reveal some extra stuff when a <div> is hovered…

div:hover .extra-stuff {
  /* reveal it */
}

That’s not particularly keyboard-friendly. But if something in .extra-stuff is tab-able anyway (meaning it can be focused), that means you could write it like this to make it a bit more accessible:

div:hover .extra-stuff,
div:focus-within .extra-stuff {
  /* reveal it */
}

That’s nice, but it causes a tricky problem.

Browsers ignore entire selectors if it doesn’t understand any part of them. So, if you’re dealing with a browser that doesn’t support :focus-within then it would ignore the CSS example above, meaning you’ve also lost the :hover state.

Instead:

div:hover .extra-stuff {
  /* reveal it */
}
div:focus-within .extra-stuff {
  /* reveal it */
}

That is safer. But it’s repetitive. If you have a preprocessor like Sass…

@mixin reveal {
  .extra-stuff {
     transform: translateY(0);
  }
}
div:hover {
  @include reveal;
}
div:focus-within {
  @include reveal;
}

See the Pen
Mixing for :focus-within without comma-separating
by Chris Coyier (@chriscoyier)
on CodePen.

I’d say it’s a pretty good use-case for having native CSS mixins.