</> ConvertAtlas Developer Tools
Bootstrap 5 · Intermediate

Animated Underline Tabs

Tabs with a sliding underline indicator that swaps content.

Requires Bootstrap 5. Add the CDN tags below to your page (styles in <head>, scripts before </body>). The downloaded file already includes them.
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css">
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.bundle.min.js"></script>
<div class="card border-0 shadow-sm" style="max-width:360px"><div class="card-body">
  <div class="position-relative d-flex gap-4 border-bottom" id="tuWrap">
    <button class="btn btn-link text-decoration-none px-0 active" data-tu>Home</button>
    <button class="btn btn-link text-decoration-none px-0 text-secondary" data-tu>Profile</button>
    <button class="btn btn-link text-decoration-none px-0 text-secondary" data-tu>Messages</button>
    <span class="position-absolute bg-primary" id="tuBar" style="height:2px;bottom:-1px;transition:.3s"></span>
  </div>
  <div class="small text-secondary mt-3" id="tuContent">Home content here.</div>
</div></div>
var data=['Home content here.','Your profile details.','You have 3 messages.'];
var tabs=document.querySelectorAll('#tuWrap [data-tu]'),bar=document.getElementById('tuBar'),content=document.getElementById('tuContent');
function move(b,i){bar.style.left=b.offsetLeft+'px';bar.style.width=b.offsetWidth+'px';content.textContent=data[i]}
tabs.forEach(function(b,i){b.onclick=function(){tabs.forEach(function(x){x.classList.add('text-secondary');x.classList.remove('active')});b.classList.remove('text-secondary');b.classList.add('active');move(b,i)}});
setTimeout(function(){move(tabs[0],0)},50);
Free to use.This component uses Bootstrap 5 (linked above). Copy any file, or download a ready-to-open .html page with the CDN links already included.