About this snippet

Upgrade your mobile navigation with this fluid animation. The active background moves elastically to the selected icon using simple CSS transitions, providing a delightful visual cue that tells users exactly where they are.

Size
2.5 KB
Uses
HTML, CSS, JavaScript
Loads
Nothing external
Views
511
<div class="tab-bar">
  <a href="#" class="tab-item">
    <svg viewBox="0 0 24 24" width="24" height="24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M3 9l9-7 9 7v11a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z"></path></svg>
  </a>
  <a href="#" class="tab-item active">
    <svg viewBox="0 0 24 24" width="24" height="24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="11" cy="11" r="8"></circle><line x1="21" y1="21" x2="16.65" y2="16.65"></line></svg>
  </a>
  <a href="#" class="tab-item">
    <svg viewBox="0 0 24 24" width="24" height="24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M20 21v-2a4 4 0 0 0-4-4H8a4 4 0 0 0-4 4v2"></path><circle cx="12" cy="7" r="4"></circle></svg>
  </a>
  <a href="#" class="tab-item">
    <svg viewBox="0 0 24 24" width="24" height="24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M12 20h9"></path><path d="M16.5 3.5a2.121 2.121 0 0 1 3 3L7 19l-4 1 1-4L16.5 3.5z"></path></svg>
  </a>
  <div class="indicator"></div>
</div>
.tab-bar {
  font-family: system-ui, "Segoe UI", Roboto, Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";
  position: relative;
  display: flex;
  background: #fff;
  padding: 10px;
  border-radius: 20px;
  box-shadow: 0 10px 30px rgba(0,0,0,0.05);
  width: 300px;
  margin: 0 auto;
  justify-content: space-around;
  border: 1px solid #f3f4f6;
}
.tab-item {
  width: 50px;
  height: 50px;
  display: flex;
  align-items: center;
  justify-content: center;
  color: #9ca3af;
  z-index: 2;
  transition: color 0.3s;
}
.tab-item.active {
  color: #2563eb;
}
.indicator {
  position: absolute;
  top: 10px;
  left: 22px;
  width: 50px;
  height: 50px;
  background: #eff6ff;
  border-radius: 12px;
  z-index: 1;
  transition: transform 0.3s cubic-bezier(0.4, 0, 0.2, 1);
}
/* Logic to move indicator based on sibling count */
.tab-item:nth-child(1).active ~ .indicator { transform: translateX(0); }
.tab-item:nth-child(2).active ~ .indicator { transform: translateX(75px); }
.tab-item:nth-child(3).active ~ .indicator { transform: translateX(150px); }
.tab-item:nth-child(4).active ~ .indicator { transform: translateX(225px); }
const tabs = document.querySelectorAll(".tab-item");

tabs.forEach(tab => {
  tab.addEventListener("click", (e) => {
    e.preventDefault();
    tabs.forEach(t => t.classList.remove("active"));
    tab.classList.add("active");
  });
});
Esc
↑↓ moveEnter select

Start from a template

Open an .html file, or HTML, CSS, JS, Markdown, Less or TypeScript files. You can also drop them here. Styles and scripts go into their panes.

Share

Source

Keyboard shortcuts

Save