Creative Fullpage Tabs

Creative and responsive full page tabs with content animation and background SVG animation using HTML, CSS and JS.

 Yogesh    18 Nov, 2020    11


 Demo  Download

In this snippet, we will design the full page tabs using HTML, CSS, and JS. First, we will design the list items, then design the content section and then design and animate the background svg shape using Anime js

Let's get started with the list item design.

HTML markup of list items.

<!-- List items -->
<ul class="list">
  <li><a dd-tab="tab1" class="active" href="javascript:void(0);">Design</a></li>
  <li><a dd-tab="tab2" href="javascript:void(0);">Inspiration</a></li>
  <li><a dd-tab="tab3" href="javascript:void(0);">About</a></li>
  <li><a dd-tab="tab4" href="javascript:void(0);">Snippets</a></li>
</ul>

CSS(list item ul/li)

/* List items */
.list {
  display: flex;
  flex-direction: row;
  list-style: none;
  padding: 0;
  margin: 5rem 0;
  transition: all .75s cubic-bezier(.65, .05, .36, 1);
}
.list li a  {
  display: inline-block;
  font-family: var(--title-font);
  font-weight: var(--font-weight);
  font-size: calc(3rem + 2.5vw);
  text-align: center;
  text-decoration: none;
  margin: 1rem;
  -webkit-text-stroke-width: 1.25px;
  -webkit-text-stroke-color: var(--clr-black);
  -webkit-text-fill-color: transparent;
  background-repeat: no-repeat;
  background-clip: text;
  background-image: linear-gradient(125deg, var(--clr-black), var(--clr-black) 50%, transparent 50%);
  background-size: 0% 100%;
  -webkit-background-clip: text;
  color: transparent;
  transition: all .75s;
}
/* Selected/Active tab list item */
.list li a.active {
  background-size: 215% 100%;
}

Next, we will design the tabs and content section.

HTML Structure of Tabs

<div class="tabs">
      <!-- Tab 1 -->
      <div class="tab active" id="tab1">
      // content
      </div>
      <div class="tab" id="tab2">
      // content
      </div>
      .
      .
      .
</div>

CSS of the tabs

/* Tabs */
.tabs .tab {
  display: none;
  transition: transform .75s cubic-bezier(.75, .6, .3, 1);
}
.tabs .tab.active {
  display: inherit;
}
.tabs .tab.active.animate {
  opacity: 0;
  transform-origin: left;
  transform: translateY(3rem);
}

SVG background shape design and animation

HTML MArkup

<!-- Background SVG(/animation) -->
  <svg class="bg-blob" viewBox="0 0 85 100" fill="none" xmlns="http://www.w3.org/2000/svg">
    <path id="svg_path" class="blob-path" fill-rule="evenodd" clip-rule="evenodd" d="M32.4059 26.2721C44.6339 9.20485 18.7713 -4.80642 0 2.9239V88.3685C5.38695 97.509 11.5034 91.0179 13.4674 86.3814C33.3711 114.531 40.4022 94.3297 47.5567 84.3943C68.4108 106.317 69.4412 72.6374 58.9198 61.0461C118.885 91.3399 60.4852 -12.9197 32.4059 26.2721Z" fill="rgba(0, 0, 0, .5)"/>
  </svg>

CSS

.bg-blob {
  position: fixed;
  height: 100vh;
  left: -30vh;
  top: 0;
  z-index: -1;
}

Then we apply the javascript to activate and change the content of the tabs dynamically and update the shape of SVG using Anime js

Javascript

// Body Background class list(change dynamically on click)
    const bg = ['bg1', 'bg2', 'bg3', 'bg4'];
    // SVG path array list
    // It is required to have the same number of attributes/values of every SVG paths.
    const paths = [
      'M32.4059 26.2721C44.6339 9.20485 18.7713 -4.80642 0 2.9239V88.3685C5.38695 97.509 11.5034 91.0179 13.4674 86.3814C33.3711 114.531 40.4022 94.3297 47.5567 84.3943C68.4108 106.317 69.4412 72.6374 58.9198 61.0461C118.885 91.3399 60.4852 -12.9197 32.4059 26.2721Z',
      'M38.7343 28.916C53.3502 12.8808 14.7319 -19.9663 0 16.6749V87.2576C6.43894 95.8455 16.0974 97.0056 16.0974 85.3907C28.4478 112.978 56.8438 95.1265 56.8438 83.5237C87.3753 97.9451 98.0432 53.3173 63.4995 53.3173C103.817 44.577 72.297 -7.90594 38.7343 28.916Z',
      'M33.0166 24.1626C63.5462 17.9935 23.7262 5.48372 0 0V88.425C5.48847 97.8844 11.7202 91.1668 13.7212 86.3686C30.8726 112.69 41.1635 94.5942 48.4529 84.3122C84.8997 104.362 70.7498 72.1452 60.0301 60.1495C117.916 55.5227 60.7448 33.9305 33.0166 24.1626Z',
      'M32.1191 29.3137C44.2388 13.0652 53.899 -19.5838 0 16.9098V88.4311C5.33927 97.1331 32.1191 107.078 13.3482 86.5393C75.0441 116.638 52.6548 89.6794 52.6548 77.9223C108.213 77.9223 81.299 54.0394 52.6548 54.0394C80.0194 16.9098 59.9498 -7.99797 32.1191 29.3137Z'];
    // Get list item(ul)
    const list = document.querySelector('.list');
    // Position / Reposition list items
    function positionList() {
      let active_item = document.querySelector('.list .active');
      let list_width = list.clientWidth;
      let active_item_width = active_item.offsetWidth;
      // Transform list(x direction)
      let tx = ((list_width / 2) - active_item.offsetLeft - (active_item_width / 2));
      list.style.transform = 'translateX('+ (tx)+'px)';
    }
    // event: List item click
    let list_item = document.querySelectorAll('.list li a');
    list_item.forEach((item, key) => {
      item.addEventListener('click', function(){
        // Activate list item
        activeListItem(item, key);
        // Toggle tab content
        toggleTabs(item, key);
      });
    });
    // Activate list item and animate the svg
    function activeListItem(e, key) {
      body.className = bg[key];
      // Call anime lib function timline to animate the SVG
      let timeline = anime({
        duration: 1000,
        targets: '.bg-blob .blob-path',
        d: [{
          value: paths[key]
        }],
        easing: 'easeOutQuad',
      });

      list_item.forEach(item => {
        item.classList.remove('active');
      });
      e.classList.add('active');
      // Reposition list
      positionList();
    }
    // Activate tab(content)
    function toggleTabs(item, key) {
      let tab = item.attributes['dd-tab'].value;
      let tabs = document.querySelectorAll('.tabs .tab');
      tabs.forEach(tab => {
        tab.classList.remove('active');
      });
      let active_tab = document.getElementById(tab);
      active_tab.classList.add('active', 'animate');
      setTimeout(() => {
        active_tab.classList.remove('animate');
      }, 250);
    }
    // Initialize
    function init() {
      positionList();
    }
    // call the function on window resize
    window.onresize = positionList;
    // call the function on load
    window.onload = init;

Credits / Resources

  • Animation Library: Anime JS (https://animejs.com/)
  • Free Images: Unsplash(https://unsplash.com/)
  • Google Font: Alegreya Sans(https://fonts.google.com/specimen/Alegreya+Sans)



Related Snippets