Site icon Sir Codex

How to Build a CSS3 Sliding Menu

There are various solutions throughout the web, but I struggled to find one matching my requirements:

  1. It must use clean semantic HTML5 with no superfluous tags.
  2. It must not rely on JavaScript.
  3. It must not require additional graphics.
  4. It must work on mobile and tablet touch devices.
  5. It must degrade gracefully in older browsers (IE7+) or when specific CSS3 properties are not supported.
  6. It must look great!

Open your favorite editor and let’s get coding…

The HTML

No surprises here — we have an HTML5 document, the IE shim, a link to our stylesheet, a nav element for the menu, and an article for our body text:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>Revealing CSS3 Menu</title>
<!--[if lt IE 9]>
<![endif]-->
<link rel="stylesheet" media="all" href="styles.css" />
</head>
<body>
    <!-- menu -->
    <nav>
        <ul>
            <li><a href="http://www.sitepoint.com/">SitePoint.com</a></li>
            <li><a href="http://www.sitepoint.com/css3-sliding-menu/">Revealing CSS3 Menu</a></li>
        </ul>
    </nav>
    <!-- main article -->
    <article>
        <h1>Revealing CSS3 Menu</h1>
        <p>body text</p>
    </article>
</body>
</html>

CSS: Article Styles

The article is a little unusual because we want to apply a 3D effect when the menu slides into place. It’s given a fixed position so it matches the dimensions of the body:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
article
{
    position: fixed;
    width: 70%;
    left: 0;
    top: 0;
    right: 0;
    bottom: 0;
    padding: 30px 15%;
    background-color: #fff;
    overflow: auto;
    z-index: 0;
    -webkit-transform-origin: 0 50%;
    -moz-transform-origin: 0 50%;
    -ms-transform-origin: 0 50%;
    -o-transform-origin: 0 50%;
    transform-origin: 0 50%;
}

We’ve also defined the transform-origin to the middle of the left-hand edge. Even though the transform doesn’t occur until hover, Chrome becomes upset if we attempt to set the origin in the :hover styles.

We also require a shadow overlay when the page rotates — the right-hand edge will be darker, so we can do that with a gradient applied to a pseudo element attached to the article:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
article:after
{
    position: absolute;
    content: ' ';
    left: 100%;
    top: 0;
    right: 0;
    bottom: 0;
    background-image: -webkit-linear-gradient(right, rgba(0,0,0,0.2) 0%, transparent 100%);
    background-image: -moz-linear-gradient(right, rgba(0,0,0,0.2) 0%, transparent 100%);
    background-image: -ms-linear-gradient(right, rgba(0,0,0,0.2) 0%, transparent 100%);
    background-image: -o-linear-gradient(right, rgba(0,0,0,0.2) 0%, transparent 100%);
    background-image: linear-gradient(right, rgba(0,0,0,0.2) 0%, transparent 100%);
    pointer-events: none;
}

The element is fixed as a zero-width block on the right-hand edge of the screen which is resized when the menu slides out. Note the pointer-events property

CSS: Navigation Styles

The main navigation block is fixed to the left of the screen. The content has a width of 16em, so we move it off to the left with -16em. However, the 50px right border will be shown. We can also apply a pseudo element to create a CSS triangle:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
nav
{
    position: fixed;
    left: -16em;
    top: 0;
    bottom: 0;
    background-color: #654;
    border-right: 50px solid #765;
    box-shadow: 4px 0 5px rgba(0,0,0,0.2);
    z-index: 1;
    cursor: pointer;
}
nav:after
{
    position: absolute;
    content: ' ';
    width: 0;
    height: 0;
    right: -70px;
    top: 50%;
    border-width: 15px 10px;
    border-style: solid;
    border-color: transparent transparent transparent #765;
}

The menu styling is nothing unusual. The outer ul is given a width of 14em and padding of 1em which determines the 16em total:

1
2
3
4
5
6
7
nav ul
{
    width: 14em;
    list-style-type: none;
    margin: 0;
    padding: 1em;
}

CSS: The Animation

This is where it gets interesting. First, let’s apply transitions to the article, nav and menu items:

1
2
3
4
5
6
7
8
article, article:after, nav, nav *
{
    -webkit-transition: all 600ms ease;
    -moz-transition: all 600ms ease;
    -ms-transition: all 600ms ease;
    -o-transition: all 600ms ease;
    transition: all 600ms ease;
}

Moving the menu into place is simple — we move it from -16em to 0 when the user hovers over the element:

1
2
3
4
nav:hover
{
    left: 0;
}

The page effect is applied to any article sibling following the hovered nav. The translateX moves it by 16em to the right to make room for the menu. The perspective and rotateY apply a 3D transformation:

1
2
3
4
5
6
7
8
nav:hover ~ article
{
    -webkit-transform: translateX(16em) perspective(600px) rotateY(10deg);
    -moz-transform: translateX(16em) perspective(600px) rotateY(10deg);
    -ms-transform: translateX(16em) perspective(600px) rotateY(10deg);
    -o-transform: translateX(16em) perspective(600px) rotateY(10deg);
    transform: translateX(16em) perspective(600px) rotateY(10deg);
}

Finally, the shadow gradient applied to the article’s pseudo element has the left hand edge moved from 100% to 60%. In other words, it grows to 40% of the page width:

1
2
3
4
nav:hover ~ article:after
{
    left: 60%;
}

An that’s it. Even with vendor prefixes, the return on coding investment is far higher than you’d expect.

 

The page works in most browsers. Firefox is perfect, although:

Source Link: http://www.sitepoint.com/css3-sliding-menu/

Exit mobile version