tab切换,所需的 UI 只有两组元素 - Header 和 Tab,下面介绍几种不同的实现方法和他们的优缺点
本文主要说一些 CSS 的实现方法。最好的方法是 第四种 => label + input 的实现方式。
1.首先来个JS的实现办法。JS的实现往往是比较简单的。本文主讲css实现,js的css就不细写了。
其实没有什么逻辑,就是 a 触发 b,修改 class。简简单单,平平淡淡。
-
实现思路 => 通过点击 Header 来触发 Tab 的
display
属性。- style
#tabGroup li { display: none; } #tabGroup .current { display: block; }
- body
<nav id="navGroup"> <h2>tab1</h2> <h2>tab2</h2> <h2>tab3</h2> </nav> <ul id="tabGroup"> <li class="current">content1</li> <li>content2</li> <li>content3</li> </ul>
- js
const navGroup = document.getElementById("navGroup").getElementsByTagName("h2"); const tabGroup = document.getElementById("tabGroup").getElementsByTagName("li"); for (let i = 0; i < navGroup.length; i++) { navGroup[i].onclick = function () { for (let k = 0; k < tabGroup.length; k++) { tabGroup[k].style.display = "none"; } tabGroup[i].style.display = "block"; } }
-
缺点:用到了 JS。(其实也不能说是什么缺点,大概只是人类的偏好,和为了衬托 CSS 的实现吧。
概述:其实 CSS 的方法,主要是标记。是谁来决定 Tab 的高亮?是谁来决定 Header 的高亮? => 有时候点击不一定代表着记录。 所以,我们要努力让点击产生效果,撬动 CSS。
2.CSS方法 - 锚点实现 => 跳转到名为孤独的锚点,并且将孤独的情绪放在页面之上。
锚点的实现本身是有局限性的。因为它将 元素id放于页面顶部的特性,当页面高度很高的时候,就挡住了Header栏。
有时候,不将 body 的 height 设为最大,你是看不出来的。所以我这里故意将 body 设为 1000px。
-
实现思路 => 通过伪元素
:target
来高亮被命运选中的元素 => 那么 header 呢?header 如何来决定谁来高亮它 - 答案是没有,它被无情的抛弃了。- html
<nav class="tab-header" id="test"> <a href="#tab1" class="header-item">Tab1</a> <a href="#tab2" class="header-item">Tab2</a> <a href="#tab3" class="header-item">Tab3</a> </nav> <ul class="tab-content"> <li class="content-item" id="tab1">content1</li> <li class="content-item" id="tab2">content2</li> <li class="content-item" id="tab3">content3</li> </ul>
- css
body,p,div{margin: 0;} h2{margin: 0;font-size:100%;} ul{margin: 0;padding: 0;list-style: none;} a{text-decoration: none;color:inherit;} .tab-header, .tab-content { margin: 0 auto; } .tab-header { 600px; height: 30px; background-color: #089e8a; font-size: 0; text-shadow: 0 0 10px #000; cursor: pointer; } .tab-content { 600px; height: 400px; overflow: hidden; } .header-item { display: inline-block; 33%; font-size: 16px; line-height: 30px; text-align: center; } .header-item:hover { color: #fff; } .header-item:target { background: #6c9; } .content-item { 100%; height: 100%; text-indent: 2em; background-color: #6c9; } body { /* position: fixed; */ height: 1000px; }
-
缺点:1.对Header的高亮束手无测 2.锚点的限制 => 高度一高的时候,锚点跳转遮住了导航栏。
3.CSS方法实现 => 锚点实现 => 关于前者的改善 => 通过 :target
我们能选择到 tab,谁来选中 header 的问题。
女孩的心灵,是我触不可及的地方。就如同这里的 Header 一样,我们都需要一座桥。
- 实现原理:为了让 Header 被点击后,能够锚点一起改变样式 => 我们将锚点的 tab 放在 Header 的上方就行了。
因为他们是兄弟,而且 tab 是哥哥。 => 开弓没有回头箭,css找不到之前的兄弟元素,却可以找到之后的兄弟元素。
- css => 利用兄弟元素选择器
~
=>.brother:target ~ .弟弟元素 {...}
body,p,div{margin: 0;} h2{margin: 0;font-size:100%;} ul{margin: 0;padding: 0;list-style: none;} a{text-decoration: none;color:inherit;} ul { position: relative; margin: 0 auto; 600px; height: 400px; overflow: hidden; font-size: 0; } li { 33.3%; display: inline-block; font-size: 12px; } .header-item { display: inline-block; 100%; line-height: 30px; height: 30px; background: #089e8a; border-right: 1px solid #fff; text-align: center; text-shadow: 0 0 10px #000; } .header-item:hover { background: #6c8; } .content-item { position: absolute; top: 30px; left: 0; 600px; height: 370px; background: #6c9; } .current { z-index: 1; } .content-item:target { z-index: 1; } .content-item:target ~ .header-item { background: #6c9; } body { height: 1200px; }
- html => 真正修改的其实 html 结构。
<ul> <li> <p id="tab1" class="content-item current">content1</p> <a class="header-item" href="#tab1">Tab1</a> </li> <li> <p id="tab2" class="content-item">content2</p> <a class="header-item" href="#tab2">Tab2</a> </li> <li> <p id="tab3" class="content-item">content3</p> <a class="header-item" href="#tab3">Tab3</a> </li> </ul>
- css => 利用兄弟元素选择器
- 缺点:锚点的技术限制始终存在,科技是一点点进步的,下一步,我们来解决锚点。
intel 芯片的厚度,每年都在缩小,每次到达 厚度的极限的时候 => 就是它们换材料的时候了。 => 其实根本没有什么极限,只是没有找到方法罢了。
4.CSS实现 => 使用 label + input 实现
-
实现原理:label 触发 input-ratio 的点击(label的特性) => 元素顺序:ratio-label-p => 通过 ratio 特性
:checked
选中 label 和 p 分别改变样式。标记 和 桥梁。都有了。
- html
<ul> <li> <input class="header-anchor" name="nav" type="radio" id="tab1" checked> <label class="header-item" for="tab1">Tab One</label> <p class="content-item current">content1</p> </li> <li> <input class="header-anchor" name="nav" type="radio" id="tab2" checked> <label class="header-item" for="tab2">Tab Two</label> <p class="content-item item2">content2</p> </li> <li> <input class="header-anchor" name="nav" type="radio" id="tab3" checked> <label class="header-item" for="tab3">Tab Three</label> <p class="content-item item3">content3</p> </li> </ul>
- css
body,p,div{margin: 0;} h2{margin: 0;font-size:100%;} ul{margin: 0;padding: 0;list-style: none;} a{text-decoration: none;color:inherit;} ul { margin: 0 auto; 600px; height: 400px; overflow: hidden; font-size: 0; } li { 33.3%; display: inline-block; font-size: 12px; } .header-anchor { display: none; } .header-item { display: inline-block; 100%; height: 30px; line-height: 30px; background: #089e8a; text-align: center; border-right: 1px solid #6c9; cursor: pointer; } .header-item:hover { color: #fff; } .content-item { position: relative; 600px; height: 370px; background: #6c9; text-indent: 2em; } .item2 { margin-left: -100%; } .item3 { margin-left: -200%; } body { height: 1200px; } .header-anchor:checked ~ .header-item { background: #6c9; } .header-anchor:checked ~ .content-item { z-index: 1; }
-
缺点:多了一个元素?如果这都算缺点。