CSS :focus-within

By  on  

Using :hover to display additional information or elements is a very useful technique but a big drawback to using the hover pseudo-class is that they are usually not accessibility-friendly. Not everyone uses a mouse and some users have visual impairments, so they rely on screen readers or the keyboard -- two functionality that don't technically hover.

Luckily the CSS spec gives us a gift to pair with :hover: :focus-within. With :focus-within developers can modify styles of elements when an element or its children has keyboard focus!

Consider the following HTML template with default CSS styling:

<ul id="sports">
  <li>
    <label>
      <input type="checkbox" name="sports[]">
      Soccer
      <button class="remove">Remove</button>
    </label>
    <!-- ... -->
  </li>
</ul>
#sports .remove {
  display: none;
}

#sports li:hover .remove {
  display: inline-block;
}

With the code above, hovering over a list item would show the "remove" button. That's great for mouse users but totally useless for keyboard users. Let's fix that using :focus-within:

#sports .remove {
  display: none;
}

#sports li:hover .remove,
#sports li:focus-within .remove {
  display: inline-block;
}

Once focus hits the checkbox, the focus is technically within the list item and thus we can employ :focus-within to show the "remove" button.

Accessibility is something that gets considered last but shouldn't be an afterthought; in a way, :focus-within is a useful ally even when accessibility was an afterthought. Even when considering accessibility up front, :focus-within should be in every developer's toolbox!

Recent Features

  • By
    Vibration API

    Many of the new APIs provided to us by browser vendors are more targeted toward the mobile user than the desktop user.  One of those simple APIs the Vibration API.  The Vibration API allows developers to direct the device, using JavaScript, to vibrate in...

  • By
    How to Create a RetroPie on Raspberry Pi &#8211; Graphical Guide

    Today we get to play amazing games on our super powered game consoles, PCs, VR headsets, and even mobile devices.  While I enjoy playing new games these days, I do long for the retro gaming systems I had when I was a kid: the original Nintendo...

Incredible Demos

  • By
    MooTools Accordion: Mouseover Style

    Everyone loves the MooTools Accordion plugin but I get a lot of requests from readers asking me how to make each accordion item open when the user hovers over the item instead of making the user click. You have two options: hack the original plugin...

  • By
    CSS Rounded Corners

    The ability to create rounded corners with CSS opens the possibility of subtle design improvements without the need to include images.  CSS rounded corners thus save us time in creating images and requests to the server.  Today, rounded corners with CSS are supported by all of...

Discussion

  1. I think there’s a missing :hover part of your demonstration above. The remove button will never show on hover as the code is currently written.

    I love demo’s – so I put one together here:
    https://codepen.io/aaronsaray/pen/mZMwRo

  2. The second declaration in this selector:

    #sports li:hover .remove,
    #sports li:focus-within .remove {
      display: inline-block;
    }
    

    …will cause the hover (the one it does support) to not work at all in Internet Explorer 11 — a browser still used by many folks who rely on JAWS or cannot afford new equipment or are trapped in old locked-down corporate environments.

    May be best to split those up into two declarations and perhaps script a thing for IE11 that puts a class (maybe named focus-within) on the container:

    #sports li:hover .remove,
    #sports li.focus-within .remove {
      display: inline-block;
    }
    
    #sports li:focus-within .remove {
      display: inline-block;
    }
    
  3. Maria Blair

    It’s a great CSS rule, thank you for sharing it, but unfortunately it’s not supported in EI or Edge… or many other mobile browsers: https://caniuse.com/#search=%3Afocus-within
    I usually combine my :hover rules with :focus.

  4. That’s pretty cool! It’s a shame that IE11 and even some version of Edge don’t support this – it’s really helpful. I had never heard of it before.

  5. Brandon

    Hi!
    I’m going to be using focus-within to address some accessibility concerns. In order to support IE11, I’m going to try this polyfill: https://www.npmjs.com/package/focus-within-polyfill

    Thank you for your article!

Wrap your code in <pre class="{language}"></pre> tags, link to a GitHub gist, JSFiddle fiddle, or CodePen pen to embed!