<section class="header"> <h1 class="header-title">ナビゲーションサンプルその2</h1> <p class="header-sub-title">スクロールするとタブがスライドするナビゲーション&途中から固定</p> <div class="header-nav"> <ul class="nav-tabs"> <li><a class="nav-tab" href="#content1">CONTENT1</a></li> <li><a class="nav-tab" href="#content2">CONTENT2</a></li> <li><a class="nav-tab" href="#content3">CONTENT3</a></li> <li><a class="nav-tab" href="#content4">CONTENT4</a></li> <li><a class="nav-tab" href="#content5">CONTENT5</a></li> </ul> <span class="tab-slider"></span> </div> </section> <section class="contents"> <div class="content" id="content1"> <h2 class="content-title">CONTENT1</h2> <p>something about content1</p> </div> <div class="content" id="content2"> <h2 class="content-title">CONTENT2</h2> <p>something about content2</p> </div> <div class="content" id="content3"> <h2 class="content-title">CONTENT3</h2> <p>something about content3</p> </div> <div class="content" id="content4"> <h2 class="content-title">CONTENT4</h2> <p>something about content4</p> </div> <div class="content" id="content5"> <h2 class="content-title">CONTENT5</h2> <p>something about content5</p> </div> </section>
.header, .content { display: flex; flex-direction: column; justify-content: center; align-items: center; text-align: center; position: relative; height: 100vh; background: #eee; .header-title, .content-title{ font-size: 1.5rem; margin: 0; letter-spacing: 0.5rem; } .header-sub-title { font-size: 1.0rem; opacity: 0.6; } } .header-nav { display: flex; position: absolute; bottom: 0; left: 0; width: 100%; height: 70px; box-shadow: 0 0 20px rgba(0, 0, 0, 0.1); background: #fff; z-index: 10; &.fixed { position: fixed; top: 0; } } .nav-tabs { display: flex; width: 100%; height: 100%; li { flex: 1; } a { text-decoration: none; } } .nav-tab { display: flex; justify-content: center; align-items: center; flex: 1; height: 100%; color: #000; font-size: 0.8rem; letter-spacing: 0.1rem; transition: all ease-in-out 0.5s; &:hover { color: #fff; background: #79c3bf; transition: all ease-in-out 0.5s; } } .tab-slider { position: absolute; bottom: 0; width: 0; height: 6px; background: #00a5a0; transition: left ease-in-out 0.3s; }
class StickyNavigation { constructor() { this.currentId = null; this.currentTab = null; this.tabContainerHeight = 70; let self = this; $('.nav-tab').click(function() { self.onTabClick(event, $(this)); }); $(window).scroll(() => { this.onScroll(); }); $(window).resize(() => { this.onResize(); }); } onTabClick(event, element) { event.preventDefault(); let scrollTop = $(element.attr('href')).offset().top - this.tabContainerHeight + 1; $('html, body').animate({ scrollTop: scrollTop }, 600); } onScroll() { this.checkTabContainerPosition(); this.findCurrentTabSelector(); } onResize() { if (this.currentId) { this.setSliderCss(); } } checkTabContainerPosition() { let offset = $('.header').offset().top + $('.header').height() - this.tabContainerHeight; if ($(window).scrollTop() > offset) { $('.header-nav').addClass('fixed'); } else { $('.header-nav').removeClass('fixed'); } } findCurrentTabSelector(element) { let newCurrentId; let newCurrentTab; let self = this; $('.nav-tab').each(function() { let id = $(this).attr('href'); let offsetTop = $(id).offset().top - self.tabContainerHeight; let offsetBottom = $(id).offset().top + $(id).height() - self.tabContainerHeight; if ($(window).scrollTop() > offsetTop && $(window).scrollTop() < offsetBottom) { newCurrentId = id; newCurrentTab = $(this); } }); if (this.currentId != newCurrentId || this.currentId === null) { this.currentId = newCurrentId; this.currentTab = newCurrentTab; this.setSliderCss(); } } setSliderCss() { let width = 0; let left = 0; if (this.currentTab) { width = this.currentTab.css('width'); left = this.currentTab.offset().left; } $('.tab-slider').css('width', width); $('.tab-slider').css('left', left); } } new StickyNavigation();