shou2017.com
JP

Implementing a Dropdown Menu with CSS Only

Wed Sep 18, 2019
Sat Aug 10, 2024

I tried to implement a dropdown menu with CSS only, and after Googling various methods, I found them overly complex. So I’m making a note of my approach here.

Here’s the complete code:

<ul class="basic-menu-list">
    <li class="basic-menu-item">
        <span href="#" class="basic-menu-link">This is a dropdown</span>
        <ul class="child-menu">
            <li class="basic-menu-item"><a href="#">My Page</a></li>
            <li class="basic-menu-item"><a href="#">Login</a></li>
            <li class="basic-menu-item"><a href="#">Logout</a></li>
        </ul>
    </li>
</ul>

CSS file:

/*drop-down-menu*/
ul {
    list-style: none;
}
a {
    text-decoration: none;
}
.basic-menu-list {
    border: 2px solid #f00;
}
/*Hidden by default*/
ul.child-menu {
    display: none;
    opacity: 0;
}
/*Switch to display*/
li.basic-menu-item:hover ul.child-menu {
    display: block;
    animation: show 2s;
    opacity: 1;

}
/*Animation*/
@keyframes show{
    from{
        opacity: 0;
    }
    to{
        opacity: 1;
    }
}

The implementation method is simple: normally hide with display: none;, then detect when the cursor hovers over it using the dynamic pseudo-class :hover, and display it with display: block;.

You can also hide elements using visibility: hidden instead of display: none;, but in this case, the element still exists in the layout, resulting in unnecessary white space. With display: none;, you can make the element invisible and exclude it from the layout.

Reference: developer.mozilla

It’s important to note how to animate display: none;. The following approach won’t work:

/*Hidden by default*/
ul.child-menu {
    display: none;
    opacity: 0;
    transition: opacity 1s;
}
/*Switch to display*/
li.basic-menu-item:hover ul.child-menu {
    display: block;
    opacity: 1;
}

The transition property can create animations between two points - the start and end. However, in this case, the DOM is generated at the display: block; timing, which means there’s no starting point for the transition property.

Property Type of Animation
transition Animation between start and end points

Therefore, we use the animation property here.

Property Type of Animation
animation Animation using keyframes
/*Animation*/
@keyframes show{
    from{
        opacity: 0;
    }
    to{
        opacity: 1;
    }
}

HTML5&CSS3デザイン 現場の新標準ガイド【第2版】

Tags
CSS
See Also