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.