TikTok Tutorial #53- How to create an Animated bottom bar using CSS transitions only

Learn with us how to create an Animated bottom bar using CSS transitions only!

If you found us on TikTok on the following post, check out this article and copy-paste the full code!

Happy coding! 😻

@creative.tim Ready, Set, Code! Check the link in bio for the How to #53 full code 😎 #css #webdev #devtok #coding #programming ♬ original sound - Creative Tim

1. HTML Code

<div class="container stage">
  <div class="container">
    <div class="tabbar tab-style2">
      <ul class="flex-center">
        <li class="home active" data-where="home"><span class="material-icons-outlined">
            home
          </span></li>
        <li class="products" data-where="products"><span class="material-icons-outlined">
            shopping_bag
          </span></li>
        <li class="services" data-where="services"><span class="material-icons-outlined">
            plumbing
          </span></li>
        <li class="about" data-where="about"><span class="material-icons-outlined">
            business
          </span></li>
        <li class="help" data-where="help"><span class="material-icons-outlined">
            help_outline
          </span></li>
      </ul>
    </div>
  </div>

  <div class="container">
    <div class="tabbar tab-style1">
      <ul class="flex-center">
        <li class="home active" data-where="home"><span class="material-icons-outlined">
            home
          </span></li>
        <li class="products" data-where="products"><span class="material-icons-outlined">
            shopping_bag
          </span></li>
        <li class="services" data-where="services"><span class="material-icons-outlined">
            plumbing
          </span></li>
        <li class="about" data-where="about"><span class="material-icons-outlined">
            business
          </span></li>
        <li class="help" data-where="help"><span class="material-icons-outlined">
            help_outline
          </span></li>
        <li class="follow">&nbsp;</li>
      </ul>
    </div>
  </div>
</div>

2. CSS Code

@import url("https://fonts.googleapis.com/css2?family=Roboto&display=swap");

@import url("https://fonts.googleapis.com/icon?family=Material+Icons+Outlined");

:root {
  --accent-color: #55d6be;
  --accent-color-fg: #fefefe;
  --backdrop-color: #89d4fe;
  --app-content-background-color: #c0d8ec;
  --inset-shadow: rgba(7, 43, 74, 0.3);
  --outset-shadow: rgba(223, 240, 255, 0.25);
  --clay-box-shadow: rgba(7, 43, 74, 0.3);
  --clay-background-color: #c0d8ec;
  --clay-fg-color: #444;
}

body {
  background-color: #4b4a67;
  font-size: 10px;
  font-family: "Roboto", sans-serif;
}

.flex-center {
  display: flex;
  justify-content: space-around;
  align-items: center;
}

.container {
  padding: 1rem 1rem 1.5rem;
}

// start here

.stage {
  max-width: 400px;
  width: 400px;
  margin: 1rem auto 2rem;
}

.home {
  &.active {
    color: #e0a458;
  }

  &-style {
    --app-content-background-color: #c0d8ec;
  }
}

.products {
  &.active {
    --outset-shadow: rgba(247, 167, 103, 0.45);
    --inset-shadow: rgba(149, 62, 8, 0.45);
    --clay-box-shadow: rgba(211, 69, 20, 0.4);
    --clay-background-color: #d34514;
    --clay-fg-color: #f1f2f3;

    color: #e0a458;
  }

  &-style {
    --app-content-background-color: #a1c5e3;
  }
}

.services {
  &.active {
    --outset-shadow: rgba(255, 159, 40, 0.45);
    --inset-shadow: rgba(88, 54, 13, 0.45);
    --clay-box-shadow: rgba(88, 54, 13, 0.4);
    --clay-background-color: #ed9426;
    --clay-fg-color: #f1f2f3;

    color: #e0a458;
  }

  &-style {
    --app-content-background-color: #81b2d9;
  }
}

.about {
  &.active {
    --outset-shadow: rgba(93, 255, 85, 0.45);
    --inset-shadow: rgba(28, 78, 26, 0.45);
    --clay-box-shadow: rgba(28, 78, 26, 0.4);
    --clay-background-color: #4dd146;
    --clay-fg-color: #f1f2f3;

    color: #e0a458;
  }

  &-style {
    --app-content-background-color: #629fd0;
  }
}

.help {
  &.active {
    --outset-shadow: rgba(230, 230, 230, 0.45);
    --inset-shadow: rgba(81, 81, 81, 0.45);
    --clay-box-shadow: rgba(81, 81, 81, 0.4);
    --clay-background-color: #a3a3a3;
    --clay-fg-color: #f1f2f3;

    color: #e0a458;
  }

  &-style {
    --app-content-background-color: #438bc7;
  }
}

.tabbar {
  background-color: var(--app-content-background-color);
  border-bottom-left-radius: 1rem;
  border-bottom-right-radius: 1rem;
  box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.2);
  height: 120px;
  display: flex;
  flex-direction: column;
  box-sizing: content-box;
  position: relative;
  overflow: hidden;
  transition: background-color 0.4s;

  ul,
  li {
    list-style-type: none;
    margin: 0;
    padding: 0;
  }

  ul {
    position: absolute;
    bottom: 0;
    width: 100%;
    background-color: #f9f8fa;
    align-self: flex-end;
    justify-content: center;
    height: 50px;
  }
  li {
    display: flex;
    justify-content: center;
    align-items: center;
    font-size: 1rem;
    margin-right: 5px;
    transition: all 0.4s;
    background-color: #f9f8fa;
    width: 60px;
    height: 60px;
    position: relative;
    color: #888;
    cursor: pointer;

    &:last-child {
      margin-right: 0;
    }
  }
}

.tab-style1 {
  ul {
    justify-content: center;
  }

  li {
    display: flex;
    justify-content: center;
    align-items: center;
    top: 1px;
    left: 0;
    width: 60px;
    height: 50px;
    transition: top 0.2s ease-out, width 0.4s, border-radius 0.4s,
      box-shadow 0.4s;

    &.follow {
      position: absolute;
      border-radius: 100%;
      content: " ";
      width: 60px;
      height: 60px;
      border: 10px solid var(--app-content-background-color);
      background-color: var(--app-content-background-color);
      top: -3rem;
      transition: left 0.4s ease-in, background-color 0.4s, border-color 0.4s;

      &:before,
      &:after {
        content: " ";
        position: absolute;
        top: 27px;
        right: -27px;
        border-top: 11px solid var(--app-content-background-color);
        background-color: #f9f8fa;
        width: 20px;
        height: 20px;
        box-sizing: border-box;
        transition: border-color 0.4s;
      }

      &::after {
        border-top-left-radius: 100%;
      }

      &:before {
        left: -27px;
        right: unset;
        border-top-right-radius: 100%;
      }
    }

    &:nth-child(1).active ~ .follow {
      left: 12px;
    }

    &:nth-child(2).active ~ .follow {
      left: 75px;
    }

    &:nth-child(3).active ~ .follow {
      left: 140px;
    }

    &:nth-child(4).active ~ .follow {
      left: 205px;
    }

    &:nth-child(5).active ~ .follow {
      left: 270px;
    }
  }

  .active {
    z-index: 100;
    width: 60px;
    height: 60px;
    top: -2rem;
    border-radius: 100%;
    box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.2), 0 8px 16px 0 rgba(0, 0, 0, 0.2);
  }
}

.tab-style2 {
  ul {
    justify-content: center;
  }

  li {
    border-top-left-radius: 100%;
    border-top-right-radius: 100%;
    display: flex;
    justify-content: center;
    align-items: center;
    top: 1px;
    left: 0;
    width: 60px;
    height: 50px;
  }

  .active {
    width: 60px;
    height: 60px;
    top: -1rem;

    span {
      font-size: 2rem;
    }

    &:before,
    &:after {
      position: absolute;
      content: " ";
      width: 13px;
      height: 13px;
      border-bottom: 4px solid #f9f8fa;
      top: 8px;
    }

    &:before {
      border-bottom-right-radius: 100%;
      left: -7px;
    }

    &:after {
      border-bottom-left-radius: 100%;
      right: -7px;
    }
  }
}

3. Javascript Code

const uls = document.querySelectorAll("ul");

uls.forEach((ul) => {
  const resetClass = ul.parentNode.getAttribute("class");
  const lis = ul.querySelectorAll("li");

  lis.forEach((li) => {
    li.addEventListener("click", (e) => {
      e.preventDefault();
      e.stopPropagation();
      const target = e.currentTarget;

      if (
        target.classList.contains("active") ||
        target.classList.contains("follow")
      ) {
        return;
      }

      ul.parentNode.setAttribute(
        "class",
        `${resetClass} ${target.getAttribute("data-where")}-style`
      );

      lis.forEach((item) => clearClass(item, "active"));

      setClass(target, "active");
    });
  });
});

function clearClass(node, className) {
  node.classList.remove(className);
}

function setClass(node, className) {
  node.classList.add(className);
}

I hope you did find this tutorial useful!

For more web development or UI/UX design tutorials, follow us on:

Other useful resources: