Sliding Panels Template

Sliding Panels Template

A simple portfolio template, with project preview images that slide out to reveal the selected project.

Nucleo icons

Sponsored by Nucleo, a free application to collect, customize and export all your icons as icon font and SVG symbols. Made by the CodyHouse folks!

All the resources available on CodyHouse are released under the MIT license. You can support our project with a Paypal donation 🙌

We’re not new to experimenting with portfolio templates. This time, we’ve been playing around with the idea of moving blocks of content as a way to transition from the main/gallery page to the project page. All panels move along the y-axis (x-axis on smaller devices), and the movement is triggered by whether the user wants to learn more about a project, or wants to access the navigation.

Images: unsplash.com

Creating the structure

The HTML structure is composed of two unordered lists, the ul.cd-projects-previews for the project preview images and the ul.cd-projects for the project details, and a nav.cd-primary-nav wrapping the main navigation.

<div class="cd-projects-container">
   <ul class="cd-projects-previews">
      <li>
         <a href="#0">
            <div class="cd-project-title">
               <h2>Project 1</h2>
               <p>Brief description of the project here</p>
            </div>
         </a>
      </li>

      <li>
         <!-- project preview here -->
      </li>

      <!-- other project previews here -->
   </ul> <!-- .cd-projects-previews -->

   <ul class="cd-projects">
      <li>
         <div class="preview-image">
            <div class="cd-project-title">
               <h2>Project 1</h2>
               <p>Brief description of the project here</p>
            </div> 
         </div>

         <div class="cd-project-info">
            <!-- project description here -->
         </div> <!-- .cd-project-info -->
      </li>

      <!-- projects here -->
   </ul> <!-- .cd-projects -->

   <button class="scroll cd-text-replace">Scroll</button>
</div> <!-- .cd-project-container -->

<nav class="cd-primary-nav" id="primary-nav">
   <ul>
      <li class="cd-label">Navigation</li>
      <li><a href="#0">The team</a></li>
      <!-- navigation items here -->
   </ul>
</nav> <!-- .cd-primary-nav -->

Adding style

On small devices, each project preview <li> has width equal to the viewport width and height equal to one-fourth of the viewport height (4 projects in our demo). The project preview image is set as background-image of its <a> child element; it has height equal to the viewport height and is translated to the top to cover the entire viewport.

.cd-projects-previews li {
  height: 25%;
  width: 100%;
  overflow: hidden;
  transition: transform 0.5s;
}
.cd-projects-previews a {
  display: block;
  height: 100vh;
  width: 100%;
  opacity: 0;
  transition: opacity 0.5s;
  transform: translateY(0%);
}
.cd-projects-previews li:nth-of-type(2) a {
  transform: translateY(-25%);
}
.cd-projects-previews li:nth-of-type(3) a {
  transform: translateY(-50%);
}
.cd-projects-previews li:nth-of-type(4) a {
  transform: translateY(-75%);
}

As for the project details (.cd-projects > li), each list item has an absolute position, a width and height equal to the viewport width and height respectively and is hidden by default.

.cd-projects > li {
  position: absolute;
  top: 0;
  left: 0;
  height: 100%;
  width: 100%;
  opacity: 0;
  transition: opacity 0.3s;
}

When a user selects a project, the .selected class is added to the corresponding .cd-projects > li, while the .slide-out class is added to the project previews (in a random order and with a delay to create the slide-out effect).

.cd-projects-previews li.slide-out {
  transform: translateX(-100%);
}

.cd-projects > li.selected {
  z-index: 1;
  opacity: 1;
  transition: opacity 0s;
}

On bigger devices (viewport width bigger than 1024px), the project previews height is set to 100% and its width to one-fourth of the viewport width while the <a> child is translated to the left to cover the entire viewport.

@media only screen and (min-width: 1024px) {
  .cd-projects-previews li {
    display: inline-block;
    height: 100%;
    width: 25%;
    float: left;
  }
  .cd-projects-previews li.slide-out {
    transform: translateY(-100%);
  }
  .cd-projects-previews a {
    /* width equal to window width */
    width: 400%;
  }
  .cd-projects-previews li:nth-of-type(2) a {
    transform: translateX(-25%);
  }
  .cd-projects-previews li:nth-of-type(3) a {
    transform: translateX(-50%);
  }
  .cd-projects-previews li:nth-of-type(4) a {
    transform: translateX(-75%);
  }
}

As for the full-page navigation, the .cd-primary-nav is placed below the .cd-projects-container; when the user clicks the .cd-nav-trigger, the .slide-out class is added to the project previews to reveal the navigation.

.cd-primary-nav {
  position: absolute;
  z-index: 1;
  top: 0;
  left: 0;
  height: 100%;
  width: 100%;
  overflow: auto;
  text-align: center;
  opacity: 0;
  transition: opacity 0.6s;
}
.cd-primary-nav.nav-visible {
  opacity: 1;
}

About the projects number: if you need to create more than 4 projects, you then need to update width/height of the project previews (and translate value of its <a> children). If you use SASS, though, you can update the $items variable inside partials > _variables.scss.

Events handling

We used jQuery to detect click events on project previews and .cd-nav-trigger element.
When a user selects a project/opens the main navigation, the slideToggleProjects() function takes care of sliding-in/out the projects, while the makeUniqueRandom() function is used to extract random numbers (between 1 and 4) for the projects exit order.

function slideToggleProjects(projectsPreviewWrapper, projectIndex, index, bool) {
   var randomProjectIndex = makeUniqueRandom();
  
   if( index < numRandoms - 1 ) {
      projectsPreviewWrapper.eq(randomProjectIndex).toggleClass('slide-out', bool);
      setTimeout( function(){
         //animate next preview project
         slideToggleProjects(projectsPreviewWrapper, projectIndex, index + 1, bool);
      }, 150);
   } else {
      //this is the last project preview to be animated 
      projectsPreviewWrapper.eq(randomProjectIndex).toggleClass('slide-out', bool).one('webkitTransitionEnd otransitionend oTransitionEnd msTransitionEnd transitionend', function(){
         // ...
         animating = false;
      });
   }
}

Join our newsletter

Get our monthly recap with the latest CodyHouse news

We use cookies to give you the best possible website experience. By using CodyHouse, you agree to our Privacy Policy.