I have created two distinct versions.
The initial one is Vue-specific and includes a hover effect that causes the bar to move when changing tabs, returning to its original position if the tab was not clicked.
The second example is a basic JavaScript version that only moves the bar when a new tab is clicked.
/* Vue Section */
new Vue({
el: '#app',
computed: {
lineStyles() {
return this.lineTemp == null ? this.line : this.lineTemp;
}
},
mounted() {
const tab = document.getElementById('nav-tab-1');
if (tab) {
let styles = {
left: tab.offsetLeft,
width: tab.clientWidth
}
this.line = styles;
}
},
data() {
return {
currentTab: 2,
line: {
left: 0,
width: 69
},
lineTemp: null
}
},
methods: {
onTabClick(evt) {
const tab = evt.target
let styles = {
left: tab.offsetLeft,
width: tab.clientWidth
}
this.line = styles;
},
onTabMouseEnter(evt) {
const tab = evt.target
let styles = {
left: tab.offsetLeft,
width: tab.clientWidth
}
this.lineTemp = styles;
},
onTabMouseLeave() {
this.lineTemp = null;
}
}
})
/* Plain JS section */
function onTabClick(evt) {
setLineStyle(evt.target)
}
function setLineStyle(tab) {
let line = document.querySelector('.tabs2 > .line')
line.style.left = tab.offsetLeft + "px";
line.style.width = tab.clientWidth + "px";
}
/* bind events on load */
window.onload = function() {
const tabs = document.querySelectorAll('.tabs2 > .nav > .nav-item')
tabs.forEach((tab, index) => {
tab.onclick = onTabClick;
if(index == 0) setLineStyle(tab);
})
}
.line {
position: absolute;
bottom: 0;
transition: left 0.5s ease-in-out, width 0.5s 0.10s;
height: 10px;
background-color: blue;
left: 0;
width: 69px;
pointer-events: none;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.6.11/vue.js"></script>
<link href="https://unpkg.com/<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="d8bab7b7acbbaeb8abadace88278332">[email protected]</a>/dist/css/bootstrap.min.css" rel="stylesheet" />
<!-- Vue Section -->
<div id="app">
<h4>Vue Option with hover effect</h4>
<div class="position-relative">
<ul class="nav">
<li v-for="i in 3" :id="`nav-tab-${i}`" class="nav-item" @click="onTabClick" @mouseenter="onTabMouseEnter" @mouseleave="onTabMouseLeave">
<a class="nav-link" href="#">
Tab {{ i }}
</a>
</li>
</ul>
<div class="line" :style="{ left: `${lineStyles.left}px`, width: `${lineStyles.width}px` }"></div>
</div>
</div>
<hr />
<!-- Plain Javascript Section -->
<div>
<h4>Plain javascript option with only click</h4>
<div class="tabs2 position-relative">
<ul class="nav">
<li class="nav-item">
<a class="nav-link" href="#">
Tab 1
</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#">
Long tab 2
</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#">
Tab 3
</a>
</li>
</ul>
<div class="line"></div>
</div>
</div>