Checkout my CSS Grid By Example and Getting Started With React video courses on Skillshare. Sign up now and get one free month of Skillshare.

Making a dropdown menu example with CSS :focus-within

In today's example will build a pure CSS dropdown menu using the :focus-within pseudo-class.

You can see in the video below the working example:

How does the :focus-within CSS pseudo selector work

The :focus-within selects an element if that element contains any children that are focused.

It is related to the :focus pseudo class, just that it will fire if something that is contained within that element is selected.

Unlike :focus, which is applied directly to the element itself the :focus-within rules are applied to the parent of the focused element.

Making a dropdown CSS menu with :focus-within

In order to build the menu we will start with a basic HTML structure like the one below:

 <div class="menu-container">
    <div class="menu" tabindex="0">
        <p>☰ Dropdown menu</p>
        <div class="menu-content">
            <a href="#">πŸ’Ό Services</a>
            <a href="#">πŸ’° Business</a>
        </div>
    </div>
</div> 

Will add just a bit of CSS to make the initial look of the menu:

.menu-container {
    display: inline-flex;
    flex-direction: row;
    border: solid 2px #000000;
    cursor: pointer;
}

.menu {
    position: relative;
    padding: 0rem 0.5rem;
}

.menu > .menu-content {
    display: none;
}

At this moment we will just have just the menu shown but without the working dropdown:

dropdown menu not working yet

The reason why we need to use tabindex="0" is so that the menu will be selectable id the user navigates with a keyboard.

In order to add the dropdown will add the extra rules based on the :focus-within pseudo-class:

.menu > .menu-content {
    display: none;
    position: absolute;
    border: solid 2px #000000;
}

.menu:focus-within > .menu-content {
    display: flex;
    flex-direction: column;
}

.menu a {
    padding: 0.5rem;
    display: inline-block;
    color: #000000;
}

At this point, if we click on the menu we will see the dropdown working.

If we would have just .menu:focus > .menu-content the dropdown menu would have closed while navigating the items from that dropdown. Therefore the need to use :focus-within.
dropdown menu done with the focus-within property in css

Check out the full working codepen here.

Adding nested dropdown menus

One nice thing about this approach is that we can just include the HTML for a submenu:

 <div class="menu-container">
    <div class="menu" tabindex="0">
        <p>☰ Dropdown menu</p>
        <div class="menu-content">
            <a href="#">πŸ’Ό Services</a>
            <a href="#">πŸ’° Business</a>
            <div class="menu" tabindex="0">
              <p>πŸ“š Books menu</p>
              <div class="menu-content">
                <a href="#">πŸ“• Red</a>
                <a href="#">πŸ“— Green</a>
              </div>
            </div>
        </div>
    </div>
</div> 

And it will work as expected:

multi level dropdown menu implemented with the focus-within property in css

Check out the full working codepen here and also you can see here another exmple of how we canΒ use focus-within with forms.

The browser support for :focus-within

Overall the browser support is great for the :focus-within pseudo-class, so we should not have any compatibility issues.

Home Screencasts Best of Newsletter Search X