Grid navigation concept

In this example below you will see how to do a Grid navigation concept with some HTML / CSS and Javascript

Fully personalizable grid sliding navigation concept. Works with animate.css library for slide animations.

Thumbnail
This awesome code was written by arnaudpaul, you can see more from this user in the personal repository.
You can find the original code on Codepen.io
Copyright arnaudpaul ©
  • HTML
  • CSS
  • JavaScript
<!DOCTYPE html>
<html lang="en" >

<head>
  <meta charset="UTF-8">
  <title>Grid navigation concept</title>
  
  
  <link rel='stylesheet prefetch' href='https://cdnjs.cloudflare.com/ajax/libs/animate.css/3.5.2/animate.min.css'>

      <link rel="stylesheet" href="css/style.css">

  
</head>

<body>

    <div id="container" class="container">
    <div class="controls">
      <div class="top">
        <div class="content">
          <span class="fleche">&lt;</span>
          <span class="short-title-container"></span>
        </div>
      </div>
      <div class="right">
        <div class="content">
          <span class="fleche">&gt;</span>
          <span class="short-title-container"></span>
        </div>
      </div>
      <div class="bottom">
        <div class="content">
          <span class="fleche">&gt;</span>
          <span class="short-title-container"></span>
        </div>
      </div>
      <div class="left">
        <div class="content">
          <span class="fleche">&lt;</span>
          <span class="short-title-container"></span>
        </div>
      </div>
    </div>
    <div id="slidesContainer" class="slide_container">

      <ul data-row="0">
        <li data-column="0" style="background-image: url('https://images.pexels.com/photos/421759/pexels-photo-421759.jpeg?w=1260&h=750&auto=compress&cs=tinysrgb');"><span class="short-title">1-1</span></li>
        <li data-column="1" style="background-image: url('https://i.vimeocdn.com/video/328943729_1280x720.jpg');"><span class="short-title">1-2</span></li>
        <li data-column="2" style="background-image: url('https://images.pexels.com/photos/421655/pexels-photo-421655.jpeg?w=1260&h=750&auto=compress&cs=tinysrgb');"><span class="short-title">1-3</span></li>
        <li data-column="3" style="background-image: url('https://s.iha.com/00114565916/New-york-city-New-york-city.jpeg');"><span class="short-title">1-4</span></li>
      </ul>
      <ul data-row="1">
        <li data-column="0" style="background-image: url('https://static.pexels.com/photos/4986/city-night-skyline.jpg');"><span class="short-title">2-1</span></li>
        <li data-column="1" style="background-image: url(https://static.pexels.com/photos/5443/city-lights-night-rooftop.jpg);"><span class="short-title">2-2</span></li>
        <li data-column="2" style="background-image: url('https://static.pexels.com/photos/412537/pexels-photo-412537.jpeg');"><span class="short-title">Portfolio</span></li>
        <li data-column="3" style="background-image: url('https://upload.wikimedia.org/wikipedia/commons/c/c8/Taj_Mahal_in_Midnight_with_City_Lights_illuminating_the_background.jpg');"><span class="short-title">2-4</span></li>
      </ul>
      <ul data-row="2">
        <li data-column="0" style="background-image: url('https://upload.wikimedia.org/wikipedia/commons/4/48/Yerevan_2012_February.JPG');"><span class="short-title">3-1</span></li>
        <li data-column="1" style="background-image: url('https://images.pexels.com/photos/418225/pexels-photo-418225.jpeg?w=1260&h=750&auto=compress&cs=tinysrgb');"><span class="short-title">3-2</span></li>
        <li data-column="2" style="background-image: url('http://www.publicdomainpictures.net/pictures/180000/velka/eiffel-tower-and-fountains.jpg');"><span class="short-title">3-3</span></li>
        <li data-column="3" style="background-image: url('https://images.pexels.com/photos/418281/pexels-photo-418281.jpeg?w=1260&h=750&auto=compress&cs=tinysrgb');"><span class="short-title">3-4</span></li>
        <li data-column="4" style="background-image: url('https://images.pexels.com/photos/418288/pexels-photo-418288.jpeg?w=1260&h=750&auto=compress&cs=tinysrgb');"><span class="short-title">3-5</span></li>
      </ul>

    </div>


  </div>
  
  

    <script  src="js/index.js"></script>




</body>

</html>

/*Downloaded from https://www.codeseek.co/arnaudpaul/grid-navigation-concept-WGOkbR */
    body {
      margin: 0;
      padding: 0;
    }

    .container {

      margin: 0 0;
      padding: 0;
      position: relative;
      background-color: rgb(26,26,26);
    }
    .container .controls .right, .container .controls .left,.container .controls .bottom, .container .controls .top {
      position: absolute;
      background-color: rgba(255,255,255,0.2);
      z-index: 1000;
      color: white;

      font-size: 5vw;
      text-align: center;
    }
    .container .controls .right.hidden, .container .controls .left.hidden {
      width: 0;
      min-width: 0;
      transition: width 0.1s ease;
      overflow: hidden;
    }
    .container .controls .bottom.hidden, .container .controls .top.hidden{
      height: 0;
      min-height: 0;
      transition: height 0.1s ease;
      overflow: hidden;
    }

    .container .controls>div:hover{
      background-color: rgba(255,255,255,0.3);
      cursor: pointer
    }
    .container .controls .top .content,.container .controls .bottom .content {
      max-width: 300px;
      margin: auto;
      width: 100%;
      position: relative;
    }
    .container .controls .top .short-title-container,.container .controls .bottom .short-title-container {
      position: absolute;
      font-size: 20px;
      bottom: -22px;
      line-height: 22px;
      left: 5%;
      width: 90%;
    }
    
    
    .container .controls .right {
        right: 10px;
        top: calc(50% - 25px);
        width: 50px;
        height: 50px !important;
        line-height: 50px !important;
        border-radius: 50%;
        text-align: center;
        font-size: 30px;
    }

    .container .controls .left {
        left: 10px;
        top: calc(50% - 25px);
        width: 50px;
        height: 50px !important;
        line-height: 50px !important;
        border-radius: 50%;
        text-align: center;
        font-size: 30px;
    }
    .container .controls .top {
      top: 10px;
      left: calc(50% - 25px);
      width: 50px !important;
      height: 50px ;
      line-height: 50px !important;
      border-radius: 50%;
      text-align: center;
      font-size: 30px;
    }
    .container .controls .top .fleche,.container .controls .bottom .fleche {
      transform: rotate(90deg);
      display: inline-block;
      margin-left: 5px;
    }
    .container .controls .bottom {
      bottom: 10px;
      left: calc(50% - 25px);
      width: 50px  !important;
      height: 50px;
      line-height: 50px !important;
      border-radius: 50%;
      text-align: center;
      font-size: 30px;
    }

    .container .controls .left .content,.container .controls .right .content {position: relative;}

    .container .controls .left .content .short-title-container,.container .controls .right .content .short-title-container {
      position: absolute;
      top: calc(50% - 5px);
      font-size: 20px;
      display: block;
      min-width: 5vw;
      line-height: 22px;
    }

    .container .controls .left .content .short-title-container {
      left: 60px;
    }

    .container .controls .right .content .short-title-container {
      right: 60px;
    }
    .container .controls .top .content .short-title-container {
      top: 60px;
    }

    .container .controls .bottom .content .short-title-container {
      bottom: 60px;
    }


    .slide_container ul {
      padding: 0;
      width: 0vw;
      position: relative;
      height: 0vh;
      display: block;
      margin:0;
      list-style:none;
      padding: 0;
    }
    .slide_container ul li {
      width: 0vw;
      height: 0vh;
      float: left;
      display: block;
      text-align: center;
      
      color: white;
      opacity: 0;
      background-size: cover;
      background-position: center;

    }
    .slide_container ul li.animated {
      opacity: 1;
    }
    .slide_container ul li .short-title{
      font-size: 70px
    }

/*Downloaded from https://www.codeseek.co/arnaudpaul/grid-navigation-concept-WGOkbR */
  var grd = {
    config:{
      mainContainerId: '#container',
      slidesContainerId: '#slidesContainer',
      slideAnimation:'slide',
      startRow:1,
      startColumn:2,
      slideHeight:'100vh',
      slideWidth: '100vw',
      horizontalTransitionSpeed: 900,
      verticalTransitionSpeed: 700,
      controlTitleFadeTime:400,
      slideTitleSelector:'.short-title',
      controlTitleSelector:'.short-title-container'
    },
    init:function(options = {}){
      let actual = Object.assign({}, grd.config, options);
      grd.config = actual;
      var initSlide = document.querySelectorAll(grd.config.slidesContainerId+' ul[data-row="'+grd.config.startRow+'"] li[data-column="'+grd.config.startColumn+'"]');
      if (initSlide[0].classList)
        initSlide[0].classList.add('animated');
      else
        initSlide[0].className += ' animated';

      grd.initStyles();
      grd.bindEvents();
      grd.updateControls();
    },
    initStyles:function(){
      var mainContainer = document.querySelectorAll(grd.config.mainContainerId);
      mainContainer[0].style.width = grd.config.slideWidth

      var controlLeftRight = document.querySelectorAll(grd.config.mainContainerId+' .controls .left,'+grd.config.mainContainerId+' .controls .right')
      controlLeftRight[0].style.height = grd.config.slideHeight
      controlLeftRight[0].style.lineHeight= grd.config.slideHeight
      controlLeftRight[1].style.height = grd.config.slideHeight
      controlLeftRight[1].style.lineHeight= grd.config.slideHeight

      var controlTopBottom = document.querySelectorAll(grd.config.mainContainerId+' .controls .top,'+grd.config.mainContainerId+' .controls .bottom')
      controlTopBottom[0].style.width = grd.config.slideWidth
      controlTopBottom[1].style.width = grd.config.slideWidth

      var slidesContainer = document.querySelectorAll(grd.config.slidesContainerId)
      slidesContainer[0].style.width = grd.config.slideWidth
      slidesContainer[0].style.overflow = 'hidden'
      slidesContainer[0].style.height = grd.config.slideHeight

      var lis = document.querySelectorAll(grd.config.mainContainerId+' ul li')

      for(var i = 0; i < lis.length;i++){
        lis[i].style.lineHeight = grd.config.slideHeight
      }
      var active = document.querySelectorAll(grd.config.mainContainerId+' ul li.animated')

      active[0].style.width = grd.config.slideWidth

      active[0].style.height = grd.config.slideHeight


      var controlTitles = document.querySelectorAll(grd.config.mainContainerId+' .controls '+grd.config.controlTitleSelector);
      for(var i = 0; i < controlTitles.length;i++){
        controlTitles[i].style.transition = 'opacity '+grd.config.controlTitleFadeTime+'ms ease';
      }

    },
    bindEvents:function(){

      var left = document.querySelectorAll('.left');
      for (var i = 0; i < left.length; i++) {
        left[i].addEventListener('click', function(event) {
          grd.move('left', grd.config.horizontalTransitionSpeed)

        });
      }
      var right = document.querySelectorAll('.right');
      for (var i = 0; i < right.length; i++) {
        right[i].addEventListener('click', function(event) {
          grd.move('right', grd.config.horizontalTransitionSpeed)

        });
      }
      var top = document.querySelectorAll('.top');
      for (var i = 0; i < top.length; i++) {
        top[i].addEventListener('click', function(event) {
          grd.move('top', grd.config.verticalTransitionSpeed)

        });
      }
      var bottom = document.querySelectorAll('.bottom');
      for (var i = 0; i < bottom.length; i++) {
        bottom[i].addEventListener('click', function(event) {
          grd.move('bottom', grd.config.verticalTransitionSpeed)

        });
      }


      window.addEventListener('keyup',function(e){

        if(e.code == "ArrowUp"){

          top[0].click()

        }
        else if(e.code == "ArrowDown"){
          bottom[0].click()
        }
        else if(e.code == "ArrowRight"){
          right[0].click()
        }
        else if(e.code == "ArrowLeft"){
          left[0].click()
        }
      });
    },
    move: function(direction,speed, jump = 1){
      var active = document.querySelectorAll(grd.config.slidesContainerId+' li.animated');
      var currentColumn = parseInt(active[0].getAttribute('data-column'));
      var currentRow= parseInt(active[0].parentNode.getAttribute('data-row'));
      var currentRowColumnNb = document.querySelectorAll(grd.config.slidesContainerId+' ul[data-row="'+currentRow+'"] li').length;
      var rowNb = document.querySelectorAll(grd.config.slidesContainerId+' ul').length;

      var newRow,newColumn,newSlide;
      switch (direction){
        case 'left':
        newRow = currentRow;
        if(currentColumn > jump - 1){
          newColumn = currentColumn - jump;
          newSlide =  document.querySelectorAll(grd.config.slidesContainerId+' ul[data-row="'+newRow+'"] li[data-column="'+newColumn+'"]');

          newSlide[0].style.height = grd.config.slideHeight;

          addClass(newSlide[0],grd.config.slideAnimation+'InLeft');
          newSlide[0].style.animationDuration = speed/2+'ms';
          addClass(active[0],grd.config.slideAnimation+'OutRight');
          active[0].style.animationDuration = speed/2+'ms';
          newSlide[0].style.width= grd.config.slideWidth;
          active[0].style.width = '0';
          rmClass(active[0],'animated');
          addClass(newSlide[0],'animated');
          grd.updateControls();
          setTimeout(function(){
            rmClass(newSlide[0],grd.config.slideAnimation+'InLeft')
            newSlide[0].style.removeProperty('animation-duration')
            rmClass(active[0],grd.config.slideAnimation+'OutRight')
            active[0].style.removeProperty('animation-duration')
            active[0].style.height = '0';
          },speed);

        }

        break;
        case 'right':
        newRow = currentRow;
        if(currentColumn < currentRowColumnNb - jump){
          newColumn = currentColumn + jump;
          newSlide =  document.querySelectorAll(grd.config.slidesContainerId+' ul[data-row="'+newRow+'"] li[data-column="'+newColumn+'"]');

          newSlide[0].style.height = grd.config.slideHeight;
          newSlide[0].style.width= grd.config.slideWidth;
          addClass(newSlide[0],grd.config.slideAnimation+'InRight');
          newSlide[0].style.animationDuration = speed/2+'ms';
          addClass(newSlide[0],'animated');

          active[0].style.width = '0';
          active[0].style.height = '0';
          addClass(active[0],grd.config.slideAnimation+'OutLeft');
          active[0].style.animationDuration = speed/2+'ms';
          rmClass(active[0],'animated');


          grd.updateControls();
          setTimeout(function(){
            rmClass(newSlide[0],grd.config.slideAnimation+'InRight')
            newSlide[0].style.removeProperty('animation-duration')
            rmClass(active[0],grd.config.slideAnimation+'OutLeft')
            active[0].style.removeProperty('animation-duration')


          },speed);

        }

        break;
        case 'top':
        newColumn = currentColumn;

        if(currentRow> jump - 1){
          newRow = currentRow - jump;
          newSlide =  document.querySelectorAll(grd.config.slidesContainerId+' ul[data-row="'+newRow+'"] li[data-column="'+newColumn+'"]');

          while(newSlide.length == 0){
            newColumn = parseInt(newColumn) - jump;
            newSlide =  document.querySelectorAll(grd.config.slidesContainerId+' ul[data-row="'+newRow+'"] li[data-column="'+newColumn+'"]');
          }

          newSlide[0].style.width = grd.config.slideWidth;

          addClass(newSlide[0],grd.config.slideAnimation+'InDown');
          newSlide[0].style.animationDuration = speed/2+'ms';
          addClass(active[0],grd.config.slideAnimation+'OutUp');
          active[0].style.animationDuration = speed/2+'ms';
          newSlide[0].style.height= grd.config.slideHeight;
          active[0].style.height = '0';
          rmClass(active[0],'animated');
          addClass(newSlide[0],'animated');
          grd.updateControls();
          setTimeout(function(){
            rmClass(newSlide[0],grd.config.slideAnimation+'InDown')
            newSlide[0].style.removeProperty('animation-duration')
            rmClass(active[0],grd.config.slideAnimation+'OutUp')
            active[0].style.removeProperty('animation-duration')

            active[0].style.width = '0';




          },speed);

        }

        break;
        case 'bottom':
        newColumn = currentColumn;
        if(currentRow<rowNb - jump){
          newRow = currentRow + jump;
          newSlide =  document.querySelectorAll(grd.config.slidesContainerId+' ul[data-row="'+newRow+'"] li[data-column="'+newColumn+'"]');

          while(newSlide.length == 0){
            newColumn = parseInt(newColumn) -jump;
            newSlide =  document.querySelectorAll(grd.config.slidesContainerId+' ul[data-row="'+newRow+'"] li[data-column="'+newColumn+'"]');
          }

          newSlide[0].style.width = grd.config.slideWidth;


          addClass(newSlide[0],grd.config.slideAnimation+'InUp');
          newSlide[0].style.animationDuration = speed/2+'ms';
          addClass(active[0],grd.config.slideAnimation+'OutDown');
          active[0].style.animationDuration = speed/2+'ms';
          newSlide[0].style.height= grd.config.slideHeight;
          active[0].style.height = '0';
          rmClass(active[0],'animated');
          addClass(newSlide[0],'animated');
          grd.updateControls();
          setTimeout(function(){
            rmClass(newSlide[0],grd.config.slideAnimation+'InUp')
            newSlide[0].style.removeProperty('animation-duration')
            rmClass(active[0],grd.config.slideAnimation+'OutDown')
            active[0].style.removeProperty('animation-duration')

            active[0].style.width = '0';



          },speed);

        }

        break;
      }


    },
    updateControls: function(){
      var active = document.querySelectorAll(grd.config.slidesContainerId+' li.animated');
      var currentColumn = parseInt(active[0].getAttribute('data-column'));
      var currentRow= parseInt(active[0].parentNode.getAttribute('data-row'));
      var currentRowColumnNb = document.querySelectorAll(grd.config.slidesContainerId+' ul[data-row="'+currentRow+'"] li').length;
      var rowNb = document.querySelectorAll(grd.config.slidesContainerId+' ul').length;

      var controlTopTitles = document.querySelectorAll(grd.config.mainContainerId+' .controls .top '+grd.config.controlTitleSelector)
      for (var i = controlTopTitles.length - 1; i >= 0; i--) {
        var controlTopTitle = controlTopTitles[i];
      }
      var controlRightTitles = document.querySelectorAll(grd.config.mainContainerId+' .controls .right '+grd.config.controlTitleSelector)
      for (var i = controlRightTitles.length - 1; i >= 0; i--) {
        var controlRightTitle = controlRightTitles[i];
      }
      var controlBottomTitles = document.querySelectorAll(grd.config.mainContainerId+' .controls .bottom '+grd.config.controlTitleSelector)
      for (var i = controlBottomTitles.length - 1; i >= 0; i--) {
        var controlBottomTitle = controlBottomTitles[i];
      }
      var controlLeftTitles = document.querySelectorAll(grd.config.mainContainerId+' .controls .left '+grd.config.controlTitleSelector)
      for (var i = controlLeftTitles.length - 1; i >= 0; i--) {
        var controlLeftTitle = controlLeftTitles[i];
      }


      var topSlide = document.querySelectorAll(grd.config.slidesContainerId+' ul[data-row="'+(currentRow-1)+'"] li[data-column="'+currentColumn+'"] '+grd.config.slideTitleSelector);
      var bottomSlide = document.querySelectorAll(grd.config.slidesContainerId+' ul[data-row="'+(currentRow+1)+'"] li[data-column="'+currentColumn+'"] '+grd.config.slideTitleSelector);
      var leftSlide = document.querySelectorAll(grd.config.slidesContainerId+' ul[data-row="'+currentRow+'"] li[data-column="'+(currentColumn-1)+'"] '+grd.config.slideTitleSelector);
      var rightSlide = document.querySelectorAll(grd.config.slidesContainerId+' ul[data-row="'+currentRow+'"] li[data-column="'+(currentColumn+1)+'"] '+grd.config.slideTitleSelector);

      controlTopTitle.style.opacity = 0;
      controlBottomTitle.style.opacity = 0;
      controlLeftTitle.style.opacity = 0;
      controlRightTitle.style.opacity = 0;

      setTimeout(function(){
        if(topSlide.length>0){
          controlTopTitle.textContent = topSlide[0].textContent;
          controlTopTitle.style.opacity = 1;
          rmClass(document.querySelectorAll(grd.config.mainContainerId+' .controls .top')[0],'hidden');
        }
        else{
          controlTopTitle.textContent = '';
          addClass(document.querySelectorAll(grd.config.mainContainerId+' .controls .top')[0],'hidden');

        }
        if(bottomSlide.length>0){
          controlBottomTitle.textContent = bottomSlide[0].textContent;
          controlBottomTitle.style.opacity = 1;
          rmClass(document.querySelectorAll(grd.config.mainContainerId+' .controls .bottom')[0],'hidden');
        }
        else{
          controlBottomTitle.textContent = '';
          addClass(document.querySelectorAll(grd.config.mainContainerId+' .controls .bottom')[0],'hidden');
        }
        if(leftSlide.length>0){
          controlLeftTitle.textContent = leftSlide[0].textContent;
          controlLeftTitle.style.opacity = 1;
          rmClass(document.querySelectorAll(grd.config.mainContainerId+' .controls .left')[0],'hidden');
        }
        else{
          controlLeftTitle.textContent = '';
          addClass(document.querySelectorAll(grd.config.mainContainerId+' .controls .left')[0],'hidden');
        }
        if(rightSlide.length>0){
          controlRightTitle.textContent = rightSlide[0].textContent;
          controlRightTitle.style.opacity = 1;
          rmClass(document.querySelectorAll(grd.config.mainContainerId+' .controls .right')[0],'hidden');
          
        }
        else{
          controlRightTitle.textContent = '';
          addClass(document.querySelectorAll(grd.config.mainContainerId+' .controls .right')[0],'hidden');
        }
      },grd.config.controlTitleFadeTime);

    },

  };

  grd.init({ 
    mainContainerId: '#container',
    slidesContainerId: '#slidesContainer',
    slideAnimation:'slide',
    startRow:1,
    startColumn:2,
    slideHeight:'100vh',
    slideWidth: '100vw',
    horizontalTransitionSpeed: 700,
    verticalTransitionSpeed: 700,
    controlTitleFadeTime:400,
    slideTitleSelector:'.short-title',
    controlTitleSelector:'.short-title-container'
  });




  function rmClass(el,className){
    if (el.classList)
      el.classList.remove(className);
    else
      el.className = el.className.replace(new RegExp('(^|\\b)' + className.split(' ').join('|') + '(\\b|$)', 'gi'), ' ');
  }
  function addClass(el,className){
    if (el.classList)
      el.classList.add(className);
    else
      el.className += ' ' + className;
  }

Comments