Sliding bottom tab 仿 bilibili 安卓用戶端滑動 tab
先看效果
![](https://img.laitimes.com/img/9ZDMuAjOiMmIsIjOiQnIsIiZpdmLzUzYiJWOkBjZxY2N1ADO4EWO1QjM0UmZ4IGM5ETM4Q2Lc52YucWbp5GZzNmLn9Gbi1yZtl2Lc9CX6MHc0RHaiojIsJye.gif)
😄第一次做效果,咱就是沒寫過,是以寫來看看,順便把基礎知識練習一下
HTML
<nav>
<div class="container">
<input type="radio" name="nav" id="nav-song" checked>
<label for="nav-song">簡介</label>
<input type="radio" name="nav" id="nav-video">
<label id="nav-video-lable" for="nav-video">評論 1104</label>
<input type="radio" name="nav" id="nav-live">
<label id="nav-live-lable" for="nav-live">點我發彈幕</label>
<span class="glider"></span>
</div>
</nav>
個人覺得代碼部分不是很難, 但也有幾個地方需要像我一樣的小白注意
- 第一就是使用
做頁籤之間互斥的情況, 并且使用<input type="radio">
預設選中某一項checked
- 隐藏
而使用<input>
作為頁籤顯示的漢字;<label>
CSS
- 整體, 取消所有的
, 和padding
, 并設定背景顔色和字型margin
* { padding: 0; margin: 0; font-family: Helvetica, sans-serif; background-color: rgba(#e6eef9, 0.5); }
- 設定導航, 頁面居中
: 這個機關的意思是整個視窗高度的vh
, 是以1%
就是占滿整個高度. 對應的當然有100vh
整個視窗寬度的vw
,1%
nav { display: flex; justify-content: center; align-items: center; height: 100vh; background-color: #F3F4F6; }
- 設定具體的
tab
标簽
要求很簡單, 隻占整個
的nav
, 占多少都行, 這主要是為了截圖友善🤭80%
定位為了友善滑動條的定位positive
nav .container { display: flex; justify-content: space-evenly; align-items: center; background-color: #fff; padding: 4px; position: relative; width: 80%; }
- 隐藏
, 同時設定當這個radio
狀态為radio
時, 對應的checked
顔色的改變 ( 使用了相鄰兄弟選擇器label
)+
input[type="radio"] { display: none; } input[type="radio"]:checked + label { color: #185ee0; }
- 設定
, 居中顯示label
label { display: flex; justify-content: center; align-items: center; }
-
設定滑動條
注意
定位使得absolute
變為塊元素, 是以高度可以生效<span>
.glider { position: absolute; bottom: 0; height: 2px; background-color: #185ee0; transition: all .2s ease-in-out; }
JavaScript
就是, 剛加載的時候讓滾動條處于第一個
tab
下面, 然後每次點選時, 調整滾動條的寬度和位置即可, 記得
offsetWidth
和
offsetLeft
傳回的是
number
, 是以最後要加上
px
let glider = document.querySelector('.glider');
let firstFlag = true;
document.querySelectorAll('label').forEach((label) => {
if (firstFlag) {
glider.style.width = label.offsetWidth + 'px';
glider.style.left = label.offsetLeft + 'px';
firstFlag = false;
}
label.addEventListener('click', (e) => {
glider.style.width = e.target.offsetWidth + 'px';
glider.style.left = e.target.offsetLeft + 'px';
});
});
最後放上所有代碼
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<nav>
<div class="container">
<input type="radio" name="nav" id="nav-song" checked>
<label for="nav-song">簡介</label>
<input type="radio" name="nav" id="nav-video">
<label for="nav-video">評論 1104</label>
<input type="radio" name="nav" id="nav-live">
<label for="nav-live">點我發彈幕</label>
<span class="glider"></span>
</div>
</nav>
<script>
let glider = document.querySelector('.glider');
let firstFlag = true;
document.querySelectorAll('label').forEach((label) => {
if (firstFlag) {
glider.style.width = label.offsetWidth + 'px';
glider.style.left = label.offsetLeft + 'px';
firstFlag = false;
}
label.addEventListener('click', (e) => {
glider.style.width = e.target.offsetWidth + 'px';
glider.style.left = e.target.offsetLeft + 'px';
});
});
</script>
</body>
</html>
* {
padding: 0;
margin: 0;
font-family: Helvetica, sans-serif;
background-color: rgba(#e6eef9, 0.5);
}
nav {
display: flex;
justify-content: center;
align-items: center;
height: 100vh;
background-color: #F3F4F6;
}
nav .container {
display: flex;
justify-content: space-evenly;
align-items: center;
background-color: #fff;
/* border-radius: 9999px; */
padding: 4px;
position: relative;
width: 80%;
}
input[type="radio"] {
display: none;
}
input[type="radio"]:checked + label {
color: #185ee0;
}
.glider {
position: absolute;
bottom: 0;
height: 2px;
background-color: #185ee0;
transition: all .2s ease-in-out;
}
label {
display: flex;
justify-content: center;
align-items: center;
}