Go to homepage

Projects /

3D Bold Navigation

A bold navigation that slides in when active, replacing the current content in a 3D space.

3D Bold Navigation
Check our new component library →

Today’s resource is a strong approach to showing a website navigation. Bear in mind, though, it doesn’t have to be the “main” navigation. You could have, for example, a product gallery and you’d like to create a smooth transition while switching from one product category to the other.

To increase the focus on the menu, we pushed the main content along the z-axis (by using CSS transformations we actually scale down the content size, we don’t use 3D translations, but the result is the same).

The interesting bit: when you select a new category, we switch the content in the background, then move it back to the original position, hiding the navigation.

Now let’s dive into the code!

Inpiration: chulakov.com.

The icons used in the demo are from our Nucleo icons application.

👋 A new version of this component is available. Download now →.

Creating the structure

The HTML is structured in 3 main elements: a .cd-nav-trigger used to create the menu icon, a .cd-section element containing the page main content and a .cd-nav-container for the main navigation.

<a href="#cd-nav" class="cd-nav-trigger">
   Menu<span><!-- used to create the menu icon --></span>
</a> <!-- .cd-nav-trigger -->

   <section class="cd-section index cd-selected">
         <div class="cd-title">
            <h2><!--  title here  --></h2>
            <p><!--  brief description here  --></p>
         </div> <!-- .cd-title -->

      <div class="cd-content">
         <!-- your content here -->
   </section> <!-- .cd-section -->

<nav class="cd-nav-container" id="cd-nav">
      <a href="#0" class="cd-close-nav">Close</a>

   <ul class="cd-nav">
      <li class="cd-selected" data-menu="index">
         <a href="index.html">
               <!-- svg icon here -->

            <em><!--  title here  --></em>

      <li data-menu="projects">
         <!-- .... -->

      <!-- other list items here -->
   </ul> <!-- .cd-3d-nav -->

An additional div.cd-overlay has been used to create a shadow layer, visible only when navigation is active.

Adding style

To realise our animation, we used CSS3 Transformations applied to the <main> and <nav> elements.
By default, the navigation has a position fixed and is translated to the right, outside the viewport (translateX(100%)). When user clicks the menu icon, the class .is-visible is added to the <nav> element which is moved back into the viewport (translateX(0)), while the .scale-down class is added to the <main> element to scale it down (scale(.9)). And of course we have used CSS3 Transitions to achieve a smooth animation!

.cd-nav-container {
  position: fixed;
  top: 0;
  right: 0;
  width: 80%;
  height: 100%;
  transform: translateX(100%);
  transition: transform 0.4s;
.cd-nav-container.is-visible {
  transform: translateX(0);

main {
  transition: transform 0.4s;
main.scale-down {
  transform: scale(0.9);

When user selects an item from the navigation, a new .cd-section element is created and inserted in the DOM (more details in the 'Events handling' section).

The .cd-selected class is then assigned to this new inserted .cd-section element, while it is removed from the old .cd-section (the content originally visible in the page). This way the new section element (which is initially translated to the right, outside the viewport) is moved back (translateX(0)), covering the old content (z-index: 2).

One note: during this animation you don't see the old section moving to the right (translateX(100%)) because we set a delay for the .cd-section transition on transformations (it will move after .4s).

.cd-section {
  position: absolute;
  z-index: 1;
  top: 0;
  left: 0;
  height: 100%;
  width: 100%;
  overflow-y: auto;
  transform: translateX(100%);
  transition: transform 0s 0.4s;
.cd-section.cd-selected {
  position: relative;
  z-index: 2;
  transform: translateX(0);
  transition: transform 0.4s 0s;


Events handling

The index.html file contains only the 'Intro' content. A different html file has been created for each section (projects.html, careers.html, ..) with exactly the same structure, but with different .cd-section content.
When user selects a new item from the navigation, a new <section> element is created and inserted in the DOM (loadNewContent function).
The load() function is then used to load the specific section content (we used a data-menu attribute assigned to the navigation list item to determine the file content to be loaded).
Once the new html content has been inserted, we assign the .cd-selected class to the new section and close the navigation.

$('.cd-nav li').on('click', function(event){
   var target = $(this),
   //detect which section user has chosen
       sectionTarget = target.data('menu');
   if( !target.hasClass('cd-selected') ) {
      //if user has selected a section different from the one alredy visible
      //update the navigation -> assign the .cd-selected class to the selected item
      //load the new section
   } else {
      // otherwise close navigation
function loadNewContent(newSection) {
   //create a new section element and insert it into the DOM
   var section = $('<section class="cd-section '+newSection+'"></section>').appendTo($('main'));
   //load the new content from the proper html file
   section.load(newSection+'.html .cd-section > *', function(event){
      //add the .cd-selected to the new section element -> it will cover the old one
      section.addClass('cd-selected').one('webkitTransitionEnd otransitionend oTransitionEnd msTransitionEnd transitionend', function(){
         //close navigation

   $('main').one('webkitTransitionEnd otransitionend oTransitionEnd msTransitionEnd transitionend', function(){
      //once the navigation is closed, remove the old section from the DOM

   if( $('.no-csstransitions').length > 0 ) {
      //detect if browser supports transitions

One note: we implemented a simple load() function to upload the new html content, but you may wanna replace it with a proper $.ajax call in order to proper handle errors, beforeSend request etc. according to your project.

Project duplicated

Project created

Globals imported

There was an error while trying to export your project. Please try again or contact us.