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
--PEN HEADER--> > --PEN CONTENT--> |
Click to any navigation link
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.
This awesome script developed by nat-davydova. Visit their official repository for more information and follow for future updates.