With the growth of mobile ready webpages, menus and navigations have rapidly evolved into tons of creative and different styles. More and more websites are ditching the boring top-of-the-page site menu with side navigations, menu reveals, and other types of unique methods for navigating a website.

This article will cover how to build these complex and responsive menus using almost nothing but CSS3 techniques. The only JavaScript involved is used for toggling a class on the body element. We choose to toggle the body class because that gives you free reign to manipulate any element on the web page when you want the menu to be shown - giving you an extra edge level of control for getting creative with just CSS.

This technique is simple for beginners and effective for seasoned developers. Once you understand the concept involved here, you can start to build extremely creative, high performant, and complex menus with very little JavaScript.

The Basics to the CSS

The method described in this tutorial is going to use as much CSS3 as possible. This is great because it means there's little overhead, performance will be fantastic on desktop and mobile, and you really don't need to know JavaScript to build these complex menus. Here's the various CSS stuff we'll be using:

2D Transforms

3D Transforms

Transitions

CSS3 Transitions

For transitions, we'll be using mostly the standard ease timing function since I personally think it's the smoothest. You can tweak this however you like and choose between linear , ease , ease-in , ease-out , ease-in-out , and cubic-bezier(P1x,P1y,P2x,P2y) . Here's some examples:

/* Format */ transition: property || duration || timing-function || delay /* Various Examples */ transition: all 300ms ease 0; transition: all 0.5s ease-in-out 0; transition: background 300ms cubic-bezier(.61,-0.67,0,1.45) 0; transition: opacity 100ms ease 0, background 200ms ease-in-out 0, transform 200ms ease-out 0; /* Cross Browser Prefixes */ -webkit-transition: all 300ms ease 0; -moz-transition: all 300ms ease 0; -o-transition: all 300ms ease 0; transition: all 300ms ease 0;

CSS3 Transforms

Any movement we do on the webpage will be done via 3D Transforms. 3D Transforms leverage the computer's GPU so everything will be extremely performant and smooth for the user. We'll also be using 2D transforms as a fallback if the browser doesn't support 3D transforms. Here's a full list of supported browsers for the technique.

This article won't cover how to do a JavaScript fallback if 2D Transforms aren't supported. For that, you could use Modernizr to detect the browser support and fallback to jQuery's Animate function in most cases though. If you don't want to write custom JavaScript, you can always use our Scotch Panels which basically does all of this for you. Here's what the transforms CSS code will generally look like:

-webkit-transform: translate(0, 0); -moz-transform: translate(0, 0); -ms-transform: translate(0, 0); -o-transform: translate(0, 0); transform: translate(0, 0); -webkit-transform: translate3d(0, 0, 0); -moz-transform: translate3d(0, 0, 0); -ms-transform: translate3d(0, 0, 0); -o-transform: translate3d(0, 0, 0); transform: translate3d(0, 0, 0);

The Basics to the JS

All we're doing is toggling a class on the body called show-nav . When the class is active, we'll show the menu. When the class isn't active, we'll hide the menu in this simple process. Here's the JavaScript for doing this (assuming jQuery is also included):

// Wait for the DOM to be ready (all elements printed on page regardless if loaded or not) $(function() { // Bind a click event to anything with the class "toggle-nav" $('.toggle-nav').click(function() { // Toggle the Body Class "show-nav" $('body').toggleClass('show-nav'); // Deactivate the default behavior of going to the next page on click return false; }); });

I'm also going to bind the toggling of the show-nav class to hitting the escape key. Typically you should probably only do this for closing of the nav, but it actually feels really natural to me to have it toggle it open and closed. For some projects, I actually leave this in production code. I added in the comment block below the code if you want it to just close the nav. Feel free to skip this entirely though.

Upgrade Your JS Go from vanilla JavaScript 👉 React

Watch for FREE

// Toggle with hitting of ESC $(document).keyup(function(e) { if (e.keyCode == 27) { $('body').toggleClass('show-nav'); // $('body').removeClass('show-nav'); } });

Advanced (but optional) JavaScript

In some of the demos, we'll also be adding a very short-lived class to the body while it is closing. This gives us an extra level of control to work with in our CSS. This is really good for doing custom things while the navigation is closing. This isn't necessary in most cases of creating these menus, but it can help sometimes while doing advanced techniques. Watch out in some of the complex demos for this snippet of code instead.

$('.toggle-nav').click(function() { if ($('body').hasClass('show-nav')) { $('body').removeClass('show-nav').addClass('hide-nav'); setTimeout(function() { $('body').removeClass('hide-nav'); }, 500); } else { $('body').removeClass('hide-nav').addClass('show-nav'); } return false; });

Basic Example

Now that we know the basics, let's build a simple reveal menu demo. I've already built a ton of demos for you to check out, but here's the step-by-step process. All of them are generally the same with the same principles but have some minor differences. Feel free to change styles, speeds, transitions, and anything else you want to get the hang of the idea behind how to build these custom menus. Let's go over the important stuff.

Create Your Markup

The first step is to create a wrapper. This wrapper usually contains everything and hides everything outside of it. You'll also need to place a "push" wrapper inside of it that you will use to slide (transform) everything in some direction.

<div class="site-wrap"> <div class="push-wrap"> ... </div> </div>

The next step is to create your menu. For the reveal, we're going to place our nav inside the site wrapper but outside the push wrapper.

<div class="site-wrap"> <nav> <ul> <li><a href="#">Home</a></li> <li><a href="#">About</a></li> <li><a href="#">Services</a></li> <li><a href="#">Contact</a></li> </ul> </nav> <div class="push-wrap"> ... </div> </div>

Now, let's apply the necessary styles. This is going to skip over things like colors and stuff, but it will cover all the necessary essentials like positioning, overflows, transitions, and transforms.

/* Hides everything pushed outside of it */ .site-wrap { overflow: hidden; width: 100%; height: 100%; } /* Adds a transition and the resting translate state */ .push-wrap { -webkit-transition: all 300ms ease 0; -moz-transition: all 300ms ease 0; -o-transition: all 300ms ease 0; transition: all 300ms ease 0; -webkit-transform: translate(0, 0); -moz-transform: translate(0, 0); -ms-transform: translate(0, 0); -o-transform: translate(0, 0); transform: translate(0, 0); -webkit-transform: translate3d(0, 0, 0); -moz-transform: translate3d(0, 0, 0); -ms-transform: translate3d(0, 0, 0); -o-transform: translate3d(0, 0, 0); transform: translate3d(0, 0, 0); } /* Will animate the content to the right 275px revealing the hidden nav */ .show-nav .push-wrap { -webkit-transform: translate(275px, 0); -moz-transform: translate(275px, 0); -ms-transform: translate(275px, 0); -o-transform: translate(275px, 0); transform: translate(275px, 0); -webkit-transform: translate3d(275px, 0, 0); -moz-transform: translate3d(275px, 0, 0); -ms-transform: translate3d(275px, 0, 0); -o-transform: translate3d(275px, 0, 0); transform: translate3d(275px, 0, 0); } /* Positions the nav fixed below the push wrapper */ nav { width: 275px; height: 100%; position: fixed; top: 0; left: 0; }

Lastly, add the Javascript to toggle the body class show-nav as we discussed earlier.

$(function() { $('.toggle-nav').click(function() { $('body').toggleClass('show-nav'); return false; }); });

That's it! We just built a "reveal" side menu in the most simple and easy way possible. Below is a CodePen of our creation with some styles added. Feel free to go in and tweak things like positions, styles, and the direction to get a better understanding of it.

See the Pen Body Class Demo by Nicholas Cerminara (@ncerminara) on CodePen.

Awesome Demos

We have a ton of demos for you to play around with and to stir up some ideas! It's important to note that not all of these have been tested for cross-browser. Although these were built for responsive layouts, some of them aren't 100% friendly to mobile or desktop. Lastly, although full screen menus are cool, try to think about usability and the user. Each of these have unique use cases for being used on just mobile or desktop. The demos try to represent all screen sizes however, but these demos are mostly for illustrative purposes of the concept involved in making them.

Reveals

Pushes

Overs

Parallaxers

Fullscreens

Scales

Angles

Misc / Insane

A Fair Warning About Transforms

As you can see, transforms are extremely powerful at allowing you to move your content and manipulate your webpage. It's even performant and snappy on mobile. However, there are some fair concerns you should watch out for.

DOM Repainting Issues

Sometimes when using transforms or other GPU / hardware accelerated CSS techniques, you can repainting issues on elements. Things like a flicker or elements that aren't simply showing up. Usually you can fix this by adding this property to the effected element:

-webkit-backface-visibility: hidden; -moz-backface-visibility: hidden; -ms-backface-visibility: hidden; -o-backface-visibility: hidden; backface-visibility: hidden;

If that doesn't work, you can try to force GPU acceleration on the element by doing:

-webkit-transform: translateZ(0); -moz-transform: translateZ(0); -ms-transform: translateZ(0); -o-transform: translateZ(0); transform: translateZ(0);

Fixed Parent Elements

If you transform a parent element of a fixed element, the fixed element is going to stop working. This is something to be careful about. Here's an insightful discussion about it on StackOverflow.

Blurry Text and Images

Sometimes when doing a 3D Transform, text or an image might appear blurry. This is because of the way that transforms work. If this is happening, you can try the following code on the blurry element:

-webkit-backface-visibility: hidden; -moz-backface-visibility: hidden; -ms-backface-visibility: hidden; -o-backface-visibility: hidden; backface-visibility: hidden; -webkit-transform: translateZ(0); -moz-transform: translateZ(0); -ms-transform: translateZ(0); -o-transform: translateZ(0); transform: translateZ(0);

CPU Resources

The last thing to watch out for is overusing 3D Transforms. If you do too many of these on a single page, there's a good chance that when a user visits the page that things will start to lag for them and their computer's fan will start howling.

Conclusion

This is a super simple CSS technique that let's you get real creative with your sites and apps. Be sure to check out our demos. You can easily make any or all of these work only on mobile by using media queries - especially since this is where they make the most sense. When building your menus, keep in mind usability so that users aren't confused by your menu.

Like this article? Follow @whatnicktweets on Twitter