Go to homepage

Projects /

Sliding Panels Template

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

Sliding Panels Template
Check our new component library →

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

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

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;
      });
   }
}

Project duplicated

Project created

Globals imported

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