在前端开发中,Tab 页是常见的页面布局方式之一。而 Material Design 是 Google 推出的一种设计风格,以平面化、简洁、直观的设计特点受到了广泛的欢迎。本文将介绍如何利用 JS/CSS 实现 Material Design 风格的 Tab 页,帮助开发者更好地实现这种页面布局。
实现思路
Material Design 风格的 Tab 页主要有以下特点:
- Tab 项之间的切换是无缝的,没有页面刷新的感觉。
- 当前选中的 Tab 项会有明显的高亮状态。
- Tab 项可以滚动,当超出容器宽度时,可以通过左右箭头进行滚动。
- Tab 项的宽度可以根据内容自适应。
基于以上特点,我们可以采用以下实现思路:
- 使用 HTML 结构实现 Tab 页的基本骨架。
- 使用 CSS 实现 Tab 项之间的样式,包括高亮状态、箭头、滚动等效果。
- 使用 JS 实现 Tab 项之间的切换效果。
HTML 结构
我们可以使用以下 HTML 结构实现 Tab 页的基本骨架:
// javascriptcn.com 代码示例 <div class="tab-container"> <div class="tab-scroll-arrow tab-scroll-arrow-left"></div> <div class="tab-scroll-arrow tab-scroll-arrow-right"></div> <div class="tab-items"> <div class="tab-item tab-item-active">Tab 1</div> <div class="tab-item">Tab 2</div> <div class="tab-item">Tab 3</div> <!-- ... --> </div> <div class="tab-content"> <!-- Tab 1 的内容 --> </div> <div class="tab-content"> <!-- Tab 2 的内容 --> </div> <div class="tab-content"> <!-- Tab 3 的内容 --> </div> <!-- ... --> </div>
其中,.tab-container
是整个 Tab 页的容器,.tab-scroll-arrow
是左右箭头的容器,.tab-items
是 Tab 项的容器,.tab-item
是每个 Tab 项的容器,.tab-item-active
是当前选中的 Tab 项,.tab-content
是每个 Tab 项对应的内容。
CSS 样式
Tab 项样式
为了实现 Material Design 风格的 Tab 项,我们需要对 Tab 项进行以下样式设置:
// javascriptcn.com 代码示例 .tab-item { display: inline-block; padding: 12px 24px; cursor: pointer; transition: color .2s ease-in-out; } .tab-item:hover { color: #00bcd4; } .tab-item-active { color: #00bcd4; font-weight: bold; }
其中,.tab-item
是每个 Tab 项的容器,display: inline-block
表示 Tab 项在同一行显示,padding
控制 Tab 项的内边距,cursor: pointer
表示 Tab 项可以被点击,transition
控制 Tab 项的颜色变化动画,.tab-item:hover
表示鼠标悬停在 Tab 项上时的样式,.tab-item-active
表示当前选中的 Tab 项的样式。
左右箭头样式
为了实现 Tab 项的滚动效果,我们需要添加左右箭头,并对其进行以下样式设置:
// javascriptcn.com 代码示例 .tab-scroll-arrow { display: none; position: absolute; top: 50%; transform: translateY(-50%); width: 24px; height: 24px; background: url(arrow.png) no-repeat center center; background-size: contain; cursor: pointer; } .tab-scroll-arrow-left { left: 0; background-position: left center; } .tab-scroll-arrow-right { right: 0; background-position: right center; }
其中,.tab-scroll-arrow
是左右箭头的容器,display: none
表示默认隐藏,position: absolute
表示绝对定位,top: 50%
和 transform: translateY(-50%)
表示垂直居中,width
和 height
控制箭头的大小,background
控制箭头的背景图片和位置,cursor: pointer
表示箭头可以被点击,.tab-scroll-arrow-left
和 .tab-scroll-arrow-right
分别表示左箭头和右箭头的样式。
Tab 项滚动样式
为了实现 Tab 项的滚动效果,我们需要对 Tab 项容器进行以下样式设置:
// javascriptcn.com 代码示例 .tab-items { white-space: nowrap; overflow-x: auto; -webkit-overflow-scrolling: touch; -ms-overflow-style: none; scrollbar-width: none; } .tab-items::-webkit-scrollbar { display: none; }
其中,white-space: nowrap
表示 Tab 项在同一行显示,overflow-x: auto
表示当 Tab 项超出容器宽度时,自动显示水平滚动条,-webkit-overflow-scrolling: touch
表示在移动设备上使用滚动效果,-ms-overflow-style: none
和 scrollbar-width: none
表示隐藏滚动条,.tab-items::-webkit-scrollbar
表示对 Webkit 浏览器的滚动条进行样式设置。
Tab 项自适应样式
为了实现 Tab 项的自适应效果,我们需要对 Tab 项容器进行以下样式设置:
.tab-item { flex-shrink: 0; white-space: nowrap; }
其中,flex-shrink: 0
表示 Tab 项不缩小,white-space: nowrap
表示 Tab 项不换行。
JS 代码
为了实现 Tab 项之间的切换效果,我们需要使用 JS 代码实现以下功能:
- 点击 Tab 项时,切换到对应的内容。
- 点击左右箭头时,滚动到相应位置。
// javascriptcn.com 代码示例 // 获取相关元素 const tabItems = document.querySelectorAll('.tab-item'); const tabContents = document.querySelectorAll('.tab-content'); const tabItemsContainer = document.querySelector('.tab-items'); const tabScrollArrowLeft = document.querySelector('.tab-scroll-arrow-left'); const tabScrollArrowRight = document.querySelector('.tab-scroll-arrow-right'); // 切换 Tab 项和内容 function switchTab(index) { // 切换 Tab 项的样式 tabItems.forEach(item => item.classList.remove('tab-item-active')); tabItems[index].classList.add('tab-item-active'); // 切换内容的显示 tabContents.forEach(content => content.style.display = 'none'); tabContents[index].style.display = 'block'; } // 点击 Tab 项时切换 tabItems.forEach((item, index) => { item.addEventListener('click', () => { switchTab(index); }); }); // 点击左箭头时滚动 tabScrollArrowLeft.addEventListener('click', () => { tabItemsContainer.scrollBy({ left: -200, behavior: 'smooth' }); }); // 点击右箭头时滚动 tabScrollArrowRight.addEventListener('click', () => { tabItemsContainer.scrollBy({ left: 200, behavior: 'smooth' }); });
其中,switchTab
函数用于切换 Tab 项和内容,tabItems.forEach
用于添加点击事件,tabScrollArrowLeft.addEventListener
和 tabScrollArrowRight.addEventListener
用于添加左右箭头的点击事件。
示例代码
最终的示例代码如下所示:
// javascriptcn.com 代码示例 <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>Material Design 风格的 Tab 页</title> <style> .tab-container { position: relative; width: 100%; height: 400px; background-color: #f2f2f2; overflow: hidden; } .tab-items { white-space: nowrap; overflow-x: auto; -webkit-overflow-scrolling: touch; -ms-overflow-style: none; scrollbar-width: none; } .tab-items::-webkit-scrollbar { display: none; } .tab-item { display: inline-block; padding: 12px 24px; cursor: pointer; transition: color .2s ease-in-out; flex-shrink: 0; white-space: nowrap; } .tab-item:hover { color: #00bcd4; } .tab-item-active { color: #00bcd4; font-weight: bold; } .tab-content { display: none; padding: 24px; } .tab-scroll-arrow { display: none; position: absolute; top: 50%; transform: translateY(-50%); width: 24px; height: 24px; background: url(arrow.png) no-repeat center center; background-size: contain; cursor: pointer; } .tab-scroll-arrow-left { left: 0; background-position: left center; } .tab-scroll-arrow-right { right: 0; background-position: right center; } </style> </head> <body> <div class="tab-container"> <div class="tab-scroll-arrow tab-scroll-arrow-left"></div> <div class="tab-scroll-arrow tab-scroll-arrow-right"></div> <div class="tab-items"> <div class="tab-item tab-item-active">Tab 1</div> <div class="tab-item">Tab 2</div> <div class="tab-item">Tab 3</div> <div class="tab-item">Tab 4</div> <div class="tab-item">Tab 5</div> <div class="tab-item">Tab 6</div> <div class="tab-item">Tab 7</div> <div class="tab-item">Tab 8</div> <div class="tab-item">Tab 9</div> <div class="tab-item">Tab 10</div> <div class="tab-item">Tab 11</div> <div class="tab-item">Tab 12</div> <div class="tab-item">Tab 13</div> <div class="tab-item">Tab 14</div> <div class="tab-item">Tab 15</div> <div class="tab-item">Tab 16</div> <div class="tab-item">Tab 17</div> <div class="tab-item">Tab 18</div> <div class="tab-item">Tab 19</div> <div class="tab-item">Tab 20</div> </div> <div class="tab-content" style="display: block;"> <h2>Tab 1 的内容</h2> <p>这是 Tab 1 的内容。</p> </div> <div class="tab-content"> <h2>Tab 2 的内容</h2> <p>这是 Tab 2 的内容。</p> </div> <div class="tab-content"> <h2>Tab 3 的内容</h2> <p>这是 Tab 3 的内容。</p> </div> <div class="tab-content"> <h2>Tab 4 的内容</h2> <p>这是 Tab 4 的内容。</p> </div> <div class="tab-content"> <h2>Tab 5 的内容</h2> <p>这是 Tab 5 的内容。</p> </div> <div class="tab-content"> <h2>Tab 6 的内容</h2> <p>这是 Tab 6 的内容。</p> </div> <div class="tab-content"> <h2>Tab 7 的内容</h2> <p>这是 Tab 7 的内容。</p> </div> <div class="tab-content"> <h2>Tab 8 的内容</h2> <p>这是 Tab 8 的内容。</p> </div> <div class="tab-content"> <h2>Tab 9 的内容</h2> <p>这是 Tab 9 的内容。</p> </div> <div class="tab-content"> <h2>Tab 10 的内容</h2> <p>这是 Tab 10 的内容。</p> </div> <div class="tab-content"> <h2>Tab 11 的内容</h2> <p>这是 Tab 11 的内容。</p> </div> <div class="tab-content"> <h2>Tab 12 的内容</h2> <p>这是 Tab 12 的内容。</p> </div> <div class="tab-content"> <h2>Tab 13 的内容</h2> <p>这是 Tab 13 的内容。</p> </div> <div class="tab-content"> <h2>Tab 14 的内容</h2> <p>这是 Tab 14 的内容。</p> </div> <div class="tab-content"> <h2>Tab 15 的内容</h2> <p>这是 Tab 15 的内容。</p> </div> <div class="tab-content"> <h2>Tab 16 的内容</h2> <p>这是 Tab 16 的内容。</p> </div> <div class="tab-content"> <h2>Tab 17 的内容</h2> <p>这是 Tab 17 的内容。</p> </div> <div class="tab-content"> <h2>Tab 18 的内容</h2> <p>这是 Tab 18 的内容。</p> </div> <div class="tab-content"> <h2>Tab 19 的内容</h2> <p>这是 Tab 19 的内容。</p> </div> <div class="tab-content"> <h2>Tab 20 的内容</h2> <p>这是 Tab 20 的内容。</p> </div> </div> <script> const tabItems = document.querySelectorAll('.tab-item'); const tabContents = document.querySelectorAll('.tab-content'); const tabItemsContainer = document.querySelector('.tab-items'); const tabScrollArrowLeft = document.querySelector('.tab-scroll-arrow-left'); const tabScrollArrowRight = document.querySelector('.tab-scroll-arrow-right'); function switchTab(index) { tabItems.forEach(item => item.classList.remove('tab-item-active')); tabItems[index].classList.add('tab-item-active'); tabContents.forEach(content => content.style.display = 'none'); tabContents[index].style.display = 'block'; } tabItems.forEach((item, index) => { item.addEventListener('click', () => { switchTab(index); }); }); tabScrollArrowLeft.addEventListener('click', () => { tabItemsContainer.scrollBy({ left: -200, behavior: 'smooth' }); }); tabScrollArrowRight.addEventListener('click', () => { tabItemsContainer.scrollBy({ left: 200, behavior: 'smooth' }); }); </script> </body> </html>
总结
本文介绍了如何利用 JS/CSS 实现 Material Design 风格的 Tab 页。通过 HTML 结构、CSS 样式和 JS 代码的配合,我们可以实现无缝切换、高亮状态、滚动效果和自适应宽度等特点。希望本文对于前端开发者实现 Tab 页的布局方式有所帮助。
来源:JavaScript中文网 ,转载请注明来源 本文地址:https://www.javascriptcn.com/post/65702293d2f5e1655d8cfc04