2 Blocks Template

2 Blocks Template

A template split in 2 animated blocks of content, inspired by dropbox.com/guide.

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 BSD-3-Clause license. You can support our project with a Paypal donation 🙌

Today's nugget is a simple template inspired by the awesome Dropbox Guide website. On bigger devices, the content is split in two main containers. When the user surfs through the content using the navigation, new content overlaps the old one. On smaller devices, we have a simple gallery of projects, with a slide-in panel containing additional project information.

Images: Unsplash

Creating the structure

The html structure is composed by two unordered lists, one (.cd-images-list) containing the project images (set as background-image of the .cd-images-list > li items), the other containing the project descriptions, both wrapped in two different <div> elements.
An additional ul.block-navigation has been used to create the project navigation.

<div class="cd-image-block">
   <ul class="cd-images-list">
      <li class="is-selected">
         <a href="#0">
            <h2>2 Blocks Template</h2>
         </a>
      </li>

      <li>
         <a href="#0">
<h2>Project Two</h2> </a> </li> <!-- other list items here --> </ul> </div> <!-- .cd-image-block --> <div class="cd-content-block"> <ul> <li class="is-selected"> <div> <h2>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Facere, illo!</h2> <!-- additional content here --> </div> </li> <li> <div> <h2>Lorem ipsum dolor sit amet, consectetur.</h2> <!-- additional content here --> </div> </li> <!-- other list items here --> </ul> <button class="cd-close">Close</button> </div> <!-- .cd-content-block --> <ul class="block-navigation"> <li><button class="cd-prev inactive">&larr; Prev</button></li> <li><button class="cd-next">Next &rarr;</button></li> </ul> <!-- .block-navigation -->

Adding Style

On the mobile version, the .cd-content-block element (containing the project descriptions) is in fixed position and translated outside the viewport (to the right) so that only project images are visible. When the user taps/clicks one of the projects, the .cd-content-block is translated back into the viewport (using the .is-visible class), while the .is-selected class is assigned to the list item containing the selected project information (its opacity and visibility properties are set, respectively, to 1 and visible).

.cd-content-block {
  /* move the block outside the viewport (to the right) - mobile only */
  position: fixed;
  z-index: 1;
  top: 0;
  left: 0;
  transform: translateX(100%);
  transition: transform 0.3s;
}
.cd-content-block.is-visible {
  transform: translateX(0);
}
.cd-content-block > ul > li {
  position: absolute;
  height: 100%;
  overflow-y: scroll;
  opacity: 0;
  visibility: hidden;
}
.cd-content-block > ul > li.is-selected {
  /* this is the selected content */
  position: relative;
  opacity: 1;
  visibility: visible;
}

On bigger devices (viewport width bigger than 768px), both the .cd-image-block (images container) and .cd-content-block (descriptions container) have  a width: 50%, an height: 100% and an overflow: hidden (this way children elements which are outside this area won't be visible).

By default, both .cd-image-block > ul > li and .cd-content-block > ul > li are translated to the right (translateX(100%)), so that they are not visible due to their parents overflow value.

When a project is selected, the two corresponding list items (one for the project image and the other for the project info) are moved back (using the .is-selected class) so that they become visible.

@media only screen and (min-width: 768px) {
  .cd-image-block,
  .cd-content-block {
    /* slider style - desktop version only */
    width: 50%;
    float: left;
    height: 100vh;
    overflow: hidden;
  }
  .cd-image-block > ul,
  .cd-content-block > ul {
    position: relative;
    height: 100%;
  }
  .cd-image-block > ul > li,
  .cd-content-block > ul > li {
    position: absolute;
    top: 0;
    left: 0;
    height: 100%;
    width: 100%;
    /* by default, the items are moved to the right - relative to their parent elements */
    transform: translateX(100%);
    transition: transform 0.5s;
  }
  .cd-image-block > ul > li.is-selected,
  .cd-content-block > ul > li.is-selected {
    /* this is the visible item */
    position: absolute;
    transform: translateX(0);
  }
  .cd-image-block > ul > li.move-left,
  .cd-content-block > ul > li.move-left {
    /* this is the item hidden on the left */
    transform: translateX(-100%);
  }
}

Events handling

We used jQuery to implement the project navigation (both keyboard and previous/next navigation) and to detect click events on the .cd-images-list > li > a elements (mobile version) to open the slide-in panel.

The updateBlock() function has been defined to update the visible project, and it is triggered both on mobile (when the user clicks/taps a project image) and desktop version (when the user surfs through projects using the navigation/keyboard).

function updateBlock(n, device) { //n is the index of the selected project 
   var imageItem = imagesList.eq(n), //imageList contains the .cd-images-list > li elements
       contentItem = contentList.eq(n); //contentList contains the .cd-content-block > ul > li elements

   //this function assigns the is-selected class to the 2 selected list items, removing it from their siblings
   classUpdate($([imageItem, contentItem])); 

   if( device == 'mobile') {
      //on mobile version
      contentItem.scrollTop(0);
      //add a cover layer to the images
      $('.cd-image-block').addClass('content-block-is-visible');
      //move the slide-in panel back into the viewport
      contentWrapper.addClass('is-visible');
   } else {
      //hide scrolling bar while changing project content
      contentList.addClass('overflow-hidden');
      contentItem.one('webkitTransitionEnd otransitionend oTransitionEnd msTransitionEnd transitionend', function(){
         //wait for the end of the animation
         contentItem.siblings().scrollTop(0);
         contentList.removeClass('overflow-hidden');
      });
   }

   //this function updates the visibility of the .block-navigation buttons according to visible project
   updateBlockNavigation(n);
}

Join our newsletter

Get our monthly recap with the latest CodyHouse news