Menu

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

July 24th, 2019

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.