Back

Hover menu using CSS

A step-by-step tutorial on how to create a menu with submenus that appears on hover using only CSS.

HTML

For HTML we have a div element with class "menu_item", which represent one menu item. Inside "menu_item", first element is a span element with title. For now I'll just put one menu item: "Shop", later I'll add the others. Beneath title, we have a div element with "submenu" class. Here goes submenus which won't be seen until hover. And inside "submenu", we'll place all our submenus as span elements.
It should look something like this:

    <div class="menu_item">
      <span>Shop</span> <!--  title  -->

      <div class="submenu"> <!--  submenus  -->
        <span>Shirts</span>
        <span>Shoes</span>
        <span>Bags</span>
      </div>
    </div>
      

CSS

"menu_item" class will be used just to align everything.
    .menu_item {
        width: 80px;
        display: flex;
        flex-direction: column;
        justify-content: center;
        align-items: center;
    }
      
All span elements inside element with "menu_item" class will have 1px transparent border, because we'll color it later on hover, and we don't want our height to change. And we'll just add the transition, pointer, paddings (5px top and bottom, 0 left and right), and we'll align text to center.
    .menu_item span {
        border: 1px solid transparent;
        transition: .3s;
        padding: 5px 0;
        cursor: pointer;
        width: 100%;
        text-align: center;
    }
      
On hover, using '>' selector, we'll select direct child, which is the title, and color top and bottom border, as mentioned before. Of course, we'll add transition property, so that the border changes it's color smoothly.
    .menu_item:hover > span {
        border-color: #000 transparent;
        transition: .3s;
    }
      
We'll decrease the font of all submenu items and align them in columns. We'll set the width to 0, and then back to 80px on hover, so we'll have a nice appearing effect. Let's also hide everything that overflows. And, of course, the transition, so that the appearing effect, mentioned before, we'll be smooth.
    .submenu {
        font-size: 14px;
        display: flex;
        flex-direction: column;
        width: 0px;
        overflow: hidden;
        transition: .3s;
    }
      
Now simply on hover just set width back to 80px and add transition.
    .menu_item:hover .submenu {
        width: 80px;
        transition: .3s;
    }
      
Now we'll set the cursor property to pointer for submenu items.
    .submenu:hover {
        cursor: pointer;
    }
      
And add top and bottom paddings to each submenu and align text to center.
    .submenu span {
        padding: 5px 0;
        text-align: center;
    }
      
On hover, just change the background color. I'll set transparent black.
    .submenu span:hover {
        background-color: rgba(0, 0, 0, .1);
    }
      
And that is it. We can now add more elements to our menu. For menu items that have submenus, just copy and paste the same html code. As for menu items that don't have submenus, just add the new menu_item with title, and without submenu element.

    <!--  New menu item without submenus  -->
    <div class="menu_item">
      <span>Home</span> <!--  title  -->
    </div>

    <div class="menu_item">
      <span>Shop</span> <!--  title  -->

      <div class="submenu"> <!--  submenus  -->
        <span>Shirts</span>
        <span>Shoes</span>
        <span>Bags</span>
      </div>
    </div>

    <!--  New menu item with submenus  -->
    <div class="menu_item">
      <span>Settings</span> <!--  title  -->

      <div class="submenu"> <!--  submenus  -->
        <span>Account</span>
        <span>Password</span>
        <span>Security</span>
      </div>
    </div>
      

Video tutorial

You can find the video with step-by-step guide on youtube:

Whole code

<div class="container">
  <div class="menu_item">
    <span>Home</span>
  </div>
  <div class="menu_item">
    <span>Shop</span>
    <div class="submenu">
      <span>Shirts</span>
      <span>Shoes</span>
      <span>Bags</span>
    </div>
  </div>
  <div class="menu_item">
    <span>Settings</span>
    <div class="submenu">
      <span>Account</span>
      <span>Password</span>
      <span>Security</span>
    </div>
  </div>
</div>

<style>
.container {
  display: flex;
  align-items: start;
}
.menu_item {
  width: 80px;
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
}
.menu_item span {
  border: 1px solid transparent;
  transition: .3s;
  padding: 5px 0;
  cursor: pointer;
  width: 100%;
  text-align: center;
}
.menu_item:hover > span {
  border-color: #000 transparent;
  transition: .3s;
}
.menu_item:hover .submenu {
  width: 80px;
  transition: .3s;
}
.submenu {
  font-size: 14px;
  display: flex;
  flex-direction: column;
  width: 0px;
  overflow: hidden;
  transition: .3s;
}
.submenu:hover {
  cursor: pointer;
}
.submenu span {
  padding: 5px 0;
  text-align: center;
}
.submenu span:hover {
  background-color: rgba(0, 0, 0, .1);
}
</style>
      
Thank you for reading this article.

More menus

Similar

See also