πŸ“• LangChain for JavaScript developers is now out!
Build 5 Next.js apps with ChatGPT integrated features using LangChain.

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.

πŸ“– 50 Javascript, React and NextJs Projects

Learn by doing with this FREE ebook! Not sure what to build? Dive in with 50 projects with project briefs and wireframes! Choose from 8 project categories and get started right away.

πŸ“– 50 Javascript, React and NextJs Projects

Learn by doing with this FREE ebook! Not sure what to build? Dive in with 50 projects with project briefs and wireframes! Choose from 8 project categories and get started right away.


Leave a Reply

Your email address will not be published. Required fields are marked *