How to Build a CSS3 Sliding Menu

Craig Buckler

It’s often best to put things away until you need them. Navigation menus are a good example. If I’m reading an article, I don’t want a large proportion of screen real estate taken with links — especially on a mobile device.

In this article, we’re going to build a slide-out menu using CSS alone. If you’re using a modern browser, it will also show a lovely 3D page effect. This is what we’ll achieve:

View the CSS3 sliding menu demonstration…

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…


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:

<!DOCTYPE html>
<html lang="en">
<meta charset="UTF-8" />
<title>Revealing CSS3 Menu</title>
<!--[if lt IE 9]>
<script src=""></script>
<link rel="stylesheet" media="all" href="styles.css" />

	<!-- menu -->
			<li><a href=""></a></li>
			<li><a href="">Revealing CSS3 Menu</a></li>

	<!-- main article -->

		<h1>Revealing CSS3 Menu</h1>

		<p>body text</p>



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:

	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:

	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 — I said it would come in useful!

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:

	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;

	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:

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:

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:

	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:

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:

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.

View the CSS3 sliding menu demonstration…

View the full stylesheet…

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

  • The page shadow appears instantly rather than expanding over time in Chrome and Safari (webkit does not support pseudo element animation).
  • Opera does not support the 3D page transforms — the menu slides out over the page.
  • IE does not support transform so the menu covers the page. Few of the effects are shown in IE7 and 8, but the menu can be used.
  • Mobile browsers such as Android, Dolphin and Firefox Mobile work well although performance might be an issue on slower devices.

Let me know if you apply similar effects to your site.

And if you enjoyed reading this post, you’ll love Learnable; the place to learn fresh skills and techniques from the masters. Members get instant access to all of SitePoint’s ebooks and interactive online courses, like Learn CSS3.

Comments on this article are closed. Have a question about CSS3? Why not ask it on our forums?