Pure JavaScript Simple Tabs Navigation UI Design
This is simple yest useful Pure JavaScript Tabs Navigation UI Design This JS tabs is good for your portable application navigation menu, this concept may intrigue you. With smooth and fluid transition impacts, the content is present intelligently to the clients. Since it is a concept model, the creator has utilized a wireframe-like component in the demo. The whole source code content to make this plan is present to you legitimately so that you can without much of a stretch use this code in your structure. This tabs concept for the navigation menu will be a decent decision for one-page website layouts too.
HTML
Tabs Navigation UI
Click to any navigation link
- Profile
- Settings
- About Us
- FAQ
CSS
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: 'Lato', sans-serif;
font-size: 16px;
color: #2c2c2c;
}
body a {
color: inherit;
text-decoration: none;
}
.btn {
-webkit-transition-property: all;
transition-property: all;
-webkit-transition-duration: 0.2s;
transition-duration: 0.2s;
-webkit-transition-timing-function: linear;
transition-timing-function: linear;
-webkit-transition-delay: 0s;
transition-delay: 0s;
padding: 10px 20px;
margin-right: 10px;
background-color: #fff;
border: 1px solid #2c2c2c;
border-radius: 3px;
cursor: pointer;
outline: none;
}
.btn:last-child {
margin-right: 0;
}
.btn:hover, .btn.js-active {
color: #fff;
background-color: #2c2c2c;
}
.header {
max-width: 500px;
margin: 50px auto;
text-align: center;
}
.header__title {
margin-bottom: 30px;
font-weight: 500;
}
.content {
max-width: 700px;
margin: auto;
}
.content__title {
margin-bottom: 20px;
font-size: 18px;
font-weight: 500;
text-align: center;
}
.content__inner {
width: 375px;
height: 550px;
margin: auto;
box-shadow: 0 8px 17px 2px rgba(0, 0, 0, 0.14), 0 3px 14px 2px rgba(0, 0, 0, 0.12), 0 5px 5px -3px rgba(0, 0, 0, 0.2);
}
.tabs {
position: relative;
padding: 15px;
height: 100%;
overflow: hidden;
}
.tabs__nav {
position: relative;
}
.tabs__nav-decoration {
position: absolute;
top: 0;
left: 0;
height: 100%;
-webkit-transition: width .2s linear 0s, -webkit-transform .2s ease-out 0s;
transition: width .2s linear 0s, -webkit-transform .2s ease-out 0s;
transition: width .2s linear 0s, transform .2s ease-out 0s;
transition: width .2s linear 0s, transform .2s ease-out 0s, -webkit-transform .2s ease-out 0s;
background-color: #119DA4;
border-radius: 3px;
z-index: 1;
}
.tabs__nav-list {
position: relative;
display: -webkit-box;
display: flex;
-webkit-box-pack: justify;
justify-content: space-between;
list-style-type: none;
z-index: 5;
}
.tabs__nav-item {
-webkit-transition-property: all;
transition-property: all;
-webkit-transition-duration: 0.2s;
transition-duration: 0.2s;
-webkit-transition-timing-function: linear;
transition-timing-function: linear;
-webkit-transition-delay: 0s;
transition-delay: 0s;
padding: 15px;
cursor: pointer;
}
.tabs__nav-item.js-active {
-webkit-transition-property: all;
transition-property: all;
-webkit-transition-duration: 0.2s;
transition-duration: 0.2s;
-webkit-transition-timing-function: linear;
transition-timing-function: linear;
-webkit-transition-delay: 0.05s;
transition-delay: 0.05s;
color: #fff;
}
.tabs__panels {
position: relative;
margin-top: 30px;
}
.tabs__panel {
position: absolute;
top: 0;
left: 0;
-webkit-transition: none;
transition: none;
-webkit-transform: scale(0.8);
transform: scale(0.8);
width: 100%;
opacity: 0;
}
.tabs__panel.js-active {
-webkit-transition: all .25s linear 0s;
transition: all .25s linear 0s;
-webkit-transform: scale(1);
transform: scale(1);
opacity: 1;
}
.tabs__panel-card {
display: -webkit-box;
display: flex;
margin-bottom: 30px;
padding: 15px;
box-shadow: 0 2px 2px 0 rgba(0, 0, 0, 0.14), 0 3px 1px -2px rgba(0, 0, 0, 0.12), 0 1px 5px 0 rgba(0, 0, 0, 0.2);
}
.tabs__panel-card:last-child {
margin-bottom: 0;
}
.tabs__panel-card--spaced-between {
-webkit-box-pack: justify;
justify-content: space-between;
}
.tabs__panel-avatar {
flex-shrink: 0;
width: 100px;
height: 100px;
border-radius: 50%;
background-color: rgba(0, 0, 0, 0.15);
}
.tabs__panel-img {
flex-shrink: 0;
width: 80px;
height: 80px;
border-radius: 4px;
background-color: rgba(0, 0, 0, 0.15);
}
.tabs__panel-content {
width: 100%;
margin-left: 30px;
}
.tabs__panel-content:first-child {
margin-left: 0;
}
.tabs__panel-content:not(:last-child) {
margin-right: 30px;
}
.tabs__panel-content:before, .tabs__panel-content:after {
display: block;
width: 100%;
height: 20px;
content: '';
background-color: rgba(0, 0, 0, 0.15);
}
.tabs__panel-content:before {
margin-bottom: 15px;
}
JS
const DOM = {
tabsNav: document.querySelector('.tabs__nav'),
tabsNavItems: document.querySelectorAll('.tabs__nav-item'),
panels: document.querySelectorAll('.tabs__panel') };
//set active nav element
const setActiveItem = elem => {
DOM.tabsNavItems.forEach(el => {
el.classList.remove('js-active');
});
elem.classList.add('js-active');
};
//find active nav element
const findActiveItem = () => {
let activeIndex = 0;
for (let i = 0; i < DOM.tabsNavItems.length; i++) {if (window.CP.shouldStopExecution(0)) break;
if (DOM.tabsNavItems[i].classList.contains('js-active')) {
activeIndex = i;
break;
};
}window.CP.exitedLoop(0);;
return activeIndex;
};
//find active nav elements parameters: left coord, width
const findActiveItemParams = activeItemIndex => {
const activeTab = DOM.tabsNavItems[activeItemIndex];
//width of elem
const activeItemWidth = activeTab.offsetWidth - 1;
//left coord in the tab navigation
const activeItemOffset_left = activeTab.offsetLeft;
return [activeItemWidth, activeItemOffset_left];
};
//appending decoration block to an active nav element
const appendDecorationNav = () => {
//creating decoration element
let decorationElem = document.createElement('div');
decorationElem.classList.add('tabs__nav-decoration');
decorationElem.classList.add('js-decoration');
//appending decoration element to navigation
DOM.tabsNav.append(decorationElem);
//appending styles to decoration element
return decorationElem;
};
//appending styles to decoration nav element
const styleDecorElem = (elem, decorWidth, decorOffset) => {
elem.style.width = `${decorWidth}px`;
elem.style.transform = `translateX(${decorOffset}px)`;
};
//find active panel
const findActivePanel = index => {
return DOM.panels[index];
};
//set active panel class
const setActivePanel = index => {
DOM.panels.forEach(el => {
el.classList.remove('js-active');
});
DOM.panels[index].classList.add('js-active');
};
//onload function
window.addEventListener('load', () => {
//find active nav item
const activeItemIndex = findActiveItem();
//find active nav item params
const [decorWidth, decorOffset] = findActiveItemParams(activeItemIndex);
//appending decoration element to an active elem
const decorElem = appendDecorationNav();
//setting styles to the decoration elem
styleDecorElem(decorElem, decorWidth, decorOffset);
//find active panel
findActivePanel(activeItemIndex);
//set active panel
setActivePanel(activeItemIndex);
});
//click nav item function
DOM.tabsNav.addEventListener('click', e => {
const navElemClass = 'tabs__nav-item';
//check if we click on a nav item
if (e.target.classList.contains(navElemClass)) {
const clickedTab = e.target;
const activeItemIndex = Array.from(DOM.tabsNavItems).indexOf(clickedTab);
//set active nav item
setActiveItem(clickedTab);
//find active nav item
const activeItem = findActiveItem();
//find active nav item params
const [decorWidth, decorOffset] = findActiveItemParams(activeItem);
//setting styles to the decoration elem
const decorElem = document.querySelector('.js-decoration');
styleDecorElem(decorElem, decorWidth, decorOffset);
//find active panel
findActivePanel(activeItemIndex);
//set active panel
setActivePanel(activeItemIndex);
}
});
See live demo and download source code.
DEMO | DOWNLOAD
This awesome script developed by nat-davydova. Visit their official repository for more information and follow for future updates.
