Create a Hidden Sliding Navigation Bar Using CSS3 Transitions

Typically web developers have been using JavaScript to create dynamic page animations. Hidden menus and subnavigation are just a couple examples for how these techniques would be used on a live website. Thanks to the addition of CSS3 transitions we can now mimic these animations, with no JavaScript in sight.

In this tutorial I want to demonstrate how to build an inner hidden content bar which slides down when hovering. You can place this into your header, footer, or even somewhere inside the page content. It is a very flexible technique which does not require a whole lot of time to get working. Plus all the modern web browsers will support CSS3 transition effects.

Live DemoDownload Source Code

Creating the HTML

The main index.html page is very straightforward and we do not need to include any alternate libraries. jQuery is not even necessary unless you want to use other plugins. I will be storing all the main webpage CSS codes within a document called styles.css.

<!doctype html>
<html lang="en-US">
  <meta http-equiv="Content-Type" content="text/html;charset=utf-8">
  <title>Sliding Box with CSS3 Transitions</title>
  <meta name="author" content="Jake Rocheleau">
  <link rel="shortcut icon" href="">
  <link rel="icon" href="">
  <link rel="stylesheet" type="text/css" media="all" href="css/styles.css">

Now in order to get the hidden div bar to expand on hover, we need to have this nested within the main topbar. Whenever a user hovers an element in jQuery we can force another internal element to stay open with it. However when using CSS3 transitions they create hover events and non-hover events immediately. So as soon as the user moves their cursor away from the top bar, it would hide the div right away unless it’s nested inside.

  <div id="topbar"><a href="">Back to Design Shack</a>
    <div id="tophiddenbar">
    Other Links: <a href="">Articles List</a> - 
    <a href="">Design Gallery</a> - 
    <a href="">About Design Shack</a> - 
    <a href="">@designshack</a>

So I have created a new div with the ID #tophiddenbar. It is nested inside #topbar because as a child element, it will keep the hover state for all items. Hovering over the hidden bar is now also apart of #topbar and so the CSS transitions will not immediately hide away before you can read or click links. I didn’t bother to use an unordered list for the links but obviously this would be best practice when crafting your own HTML sub-navigations.

Document CSS

Typically we have the same resets and document styles as other similar tutorials. However there are some updates to the #topbar element which are crucial for getting this to work. Namely we need the overflow: hidden property to make sure extra content will not display after the page loads. You will need to use this on your own container element so that the hidden div is not displaying at first, then we increase the height value through a transition.

html, body, div, span, applet, object, iframe, h1, h2, h3, h4, h5, h6, p, blockquote, pre, a, abbr, acronym, address, big, cite, code, del, dfn, em, img, ins, kbd, q, s, samp, small, strike, strong, sub, sup, tt, var, b, u, i, center, dl, dt, dd, ol, ul, li, fieldset, form, label, legend, table, caption, tbody, tfoot, thead, tr, th, td, article, aside, canvas, details, embed, figure, figcaption, footer, header, hgroup, menu, nav, output, ruby, section, summary, time, mark, audio, video {
  margin: 0;
  padding: 0;
  border: 0;
  font-size: 100%;
  font: inherit;
  vertical-align: baseline;
  outline: none;
  -webkit-font-smoothing: antialiased;
  -webkit-text-size-adjust: 100%;
  -ms-text-size-adjust: 100%;
  -webkit-box-sizing: border-box;
  -moz-box-sizing: border-box;
  box-sizing: border-box;
html { height: 101%; }
body { 
  background: #f0f0f0 url('images/bg.gif'); 
  font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif;
  color: #313131;
  font-size: 62.5%; 
  line-height: 1; 

::selection { background: #a4dcec; }
::-moz-selection { background: #a4dcec; }
::-webkit-selection { background: #a4dcec; }

::-webkit-input-placeholder { /* WebKit browsers */
  color: #ccc;
  font-style: italic;
:-moz-placeholder { /* Mozilla Firefox 4 to 18 */
  color: #ccc;
  font-style: italic;
::-moz-placeholder { /* Mozilla Firefox 19+ */
  color: #ccc;
  font-style: italic;
:-ms-input-placeholder { /* Internet Explorer 10+ */
  color: #ccc !important;
  font-style: italic;  

br { display: block; line-height: 2.2em; } 

article, aside, details, figcaption, figure, footer, header, hgroup, menu, nav, section { display: block; }
ol, ul { list-style: none; }

/** page structure **/
#w {
  display: block;
  width: 750px;
  margin: 0 auto;
  padding-top: 30px;

#content {
  display: block;
  width: 100%;
  background: #fff;
  padding: 25px 20px;
  padding-bottom: 35px;
  -webkit-box-shadow: rgba(0, 0, 0, 0.1) 0px 1px 2px 0px;
  -moz-box-shadow: rgba(0, 0, 0, 0.1) 0px 1px 2px 0px;
  box-shadow: rgba(0, 0, 0, 0.1) 0px 1px 2px 0px;

If you are familiar with CSS transitions then it shouldn’t be difficult to grasp. Basically we setup a length of time for the animation to happen, along with the properties where we need transition effects. You do not need to include all the CSS resets as I’ve added above. They are just important for this demo, and they can offer an alternative starting point as opposed to other libraries such as Twitter Bootstrap.

Animating the Menu

The actual transition property will be applied onto the #topbar element since we are animating the height value. I am using a fixed height of 36px which increases to display the inner hidden div. And remember that initially this div can display right within the page order, it is only hidden because of the overflow property on the container #topbar element.

#topbar {
  background: #4f4a41;
  padding: 10px 0 10px 0;
  text-align: center;
  height: 36px;
  overflow: hidden;
  -webkit-transition: height 0.5s linear;
  -moz-transition: height 0.5s linear;
  transition: height 0.5s linear;
#topbar a {
  color: #fff;
  line-height: 1.25em;
  text-decoration: none;
  opacity: 0.5;
  font-weight: bold;
#topbar a:hover {
  opacity: 1;

#tophiddenbar {
  display: block;
  width: 100%;
  background: #4f4a41;
  color: #b09f82;
  font-weight: bold;
  padding: 8px 0; 
  font-size: 1.3em;
  text-align: center;
  text-shadow: 1px 1px 0 #444;
#tophiddenbar a {
  color: #fff;
  font-size: 1.0em;
  text-decoration: none;
  opacity: 0.5;
  text-shadow: none;
#tophiddenbar a:hover { opacity: 1; }

#topbar:hover { height: 60px; }

When hovering the top toolbar it will expand down to 60px in height. This is enough room to show off our new sub-navigation with links back onto pages from Design Shack. This typical design is really easy to fit into any other project you have. As long as the background can be lengthened vertically it can be used as a container element.

The CSS3 transition properties also have two vendor prefixes used in Mozilla and Webkit rendering engines. The linear keyword is just a type of animation style which may be omitted for the default value. This is called the transition timing function property and it does have a select number of alternate values which you may test out. Either way this animation is perfect for any website that needs to keep a bit of content hidden on the page.

Live DemoDownload Source Code


You will notice this technique does implement a few CSS techniques which are newer to the spectrum. However it is nothing overly confusing for typical frontend web developers. There are other possible methods such as using absolute positioning nested within an outer container. Having both divs next to each other in the HTML can sometimes lose focus when hovering over the hidden element, so it’s best to keep them nested inside. Feel free to share any other thoughts or questions about this tutorial in the post discussion area below.