Show Hide Menu Using CSS Only

I have already published a tutorial for a Show/Hide menu using CSS and JavaScript but this time I decided to show some example using only pure CSS as I had some requiestes for that.

Here I am going to show two different ways to create the effect. There are probably other possibilities but these are the ones I use most of the time because they are simple and they work quite well.

Demo 1 Explained

In Demo 1 I am using overflow: hidden; on a container which allows me to hide the navigation when I place it beyond the limits of the actual container.

Let’s see the code before going to further explanations.

HTML

<div id="menu-wrappe">
    <nav id="menu">
        <ul id="links">
            <li class="bt"><a href="home">HOME</a></li>
            <li class="bt"><a href="tutorials">TUTORIALS</a></li>
            <li class="bt"><a href="articles">ARTICLES</a></li>
        </ul>
    </nav>
    <div id="icon-menu" data-icon="&#xe601;"></div>
</div>

CSS

.bt {
    height: 40px;
    line-height: 40px;
    float: left;
    text-align: center;
}

ul li {
    list-style: none;
    background: #1d5b89;
    border-top: 1px solid #073356;
    border-bottom: 1px solid #073356;
    border-right: 1px solid #073356;
    background: #1b517c;
}

ul {
    padding: 0px;
}

#menu {
    width: auto;
    height: 0px;
    top: 0px;
    position: absolute;
    margin: 0;
    padding: 0;
    overflow: hidden;
}

#icon-menu {
    top: 0px;
    left: 50%;
    margin-left: -14px;
    cursor: default;
    color: #094069;
    font-size: 2em;
    position: absolute;
}

#links, #icon-menu, .bt a {
            transition:all 0.3s ease-out;
         -o-transition:all 0.3s ease-out;
       -moz-transition:all 0.3s ease-out;
    -webkit-transition:all 0.3s ease-out;
}

#menu-wrappe {
    width: 454px;
    text-align: center;
    position: relative;
}

#links {
    opacity: 0;
}
    
.bt a {
    color: #eaebeb;
    display: block;
    width: 150px;
    font-weight: bold;
    text-decoration: none;
    border-top: 1px solid #486A84;
    text-shadow: 1px 1px 0px rgba(0, 0, 0, .5);
    font-family: Arial, Helvetica, sans-serif;
}

.bt a:hover {
    background: rgba(54, 25, 25, .3);
}

#menu ul li:first-child{
    border-left: 1px solid #073356;
}

#menu-wrappe:hover #menu {
    height: 40px;
}

#menu-wrappe:hover #icon-menu {
    top: 40px;
    opacity: .5;
}

#menu-wrappe:hover #links {
    opacity: 1;
}

You might be thinking that you could use display: none; but transition won’t work with it. It’s either displayed or not. So how I have done that is on roll-over the menu element goes from top: 0px; to top: 40px; instantly whereas the opacity goes from 0 to 1 usinga transition of 0.3 seconds and this gives the illusion that the menu is always at the same position.

Demo 2 Explained

Now here is the code for the second menu.

HTML

<div id="nav-wrap">
    <nav id="second-menu">
        <a href="portfolio">Portfolio</a>
        <a href="about">About</a>
        <a href="contact">Contact</a>
    </nav>
    <div id="icon-menu" data-icon="&#xe600;"></div>
</div>

CSS

#nav-wrap {
    top: 25px;
    height: 50px;
    width: 300px;
    margin: 0 30px;
    overflow: hidden;
    position: relative;
    text-align: center;
    border-top: 1px solid #A1CFEA;
}

#icon-down-open, #menu-second {
            transition: all 0.5s ease;
         -o-transition: all 0.5s ease;
       -moz-transition: all 0.5s ease;
    -webkit-transition: all 0.5s ease;
}

#menu-second {
    top: -14px;
    width: 100%;
    line-height: 0;
    position: absolute;
    font-size: 1.3em;
    font-family: Arial,Helvetica,sans-serif;
}

#menu-second a:link, #menu-second a:visited, #menu-second a:hover, #menu-second a:active {
    color: #49738D;
    outline: 0 none;
    font-size: 1.2em;
    text-shadow: 1px 1px 1px rgba(0, 0, 0, 0.6);
}

#menu-second a:link {
    text-decoration: none;
}

#menu-second a {
    z-index: 1;
    position: relative;
}

#icon-down-open {
    font-size: 2em;
    color: #49738D;
    cursor: default;
    text-shadow: 2px 2px 2px rgba(0, 0, 0, 0.8);
}

#nav-wrap:hover #menu-second {
    top: -12px;
    color: #575858;
    padding-top: 25px;
}

#nav-wrap:hover #icon-down-open {
    opacity: .0;
}

Here I’m also using overflow: hidden; to hide the menu but instead of the opacity it’s on the position of the element I apply the transition what gives a nice sliding out effect. Compare to the first menu where you really have to hover the icon here you have the whole with of the menu what makes it more accessible.

For those interested here is the CSS for the font icons I’m using.

@font-face {
    font-family: 'icomoon';
    src:url('font/icomoon.eot');
    src:url('font/icomoon.eot?#iefix') format('embedded-opentype'),
        url('font/icomoon.woff') format('woff'),
        url('font/icomoon.ttf') format('truetype'),
        url('font/icomoon.svg#icomoon') format('svg');
    font-weight: normal;
    font-style: normal;
}

[data-icons]:before {
    content: attr(data-icons);
    font-family: 'icomoon';
    font-variant: normal;
    font-weight: normal;
    line-height: 1;
    text-transform: none;
}

Note

I am using free font icons from icomoon.io where you can find many more. You can also use images instead font icons but this is up to you.

Hope you enjoyed this tutorial. Make sure to share this article.

Leave a Reply

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