天天看點

Sliding bottom tab 仿 bilibili 安卓用戶端滑動 tabSliding bottom tab 仿 bilibili 安卓用戶端滑動 tab

Sliding bottom tab 仿 bilibili 安卓用戶端滑動 tab

先看效果

Sliding bottom tab 仿 bilibili 安卓用戶端滑動 tabSliding bottom tab 仿 bilibili 安卓用戶端滑動 tab

😄第一次做效果,咱就是沒寫過,是以寫來看看,順便把基礎知識練習一下

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

  1. 整體, 取消所有的

    padding

    , 和

    margin

    , 并設定背景顔色和字型
    * {
      padding: 0;
      margin: 0;
      font-family: Helvetica, sans-serif;
      background-color: rgba(#e6eef9, 0.5);
    }
               
  2. 設定導航, 頁面居中

    vh

    : 這個機關的意思是整個視窗高度的

    1%

    , 是以

    100vh

    就是占滿整個高度. 對應的當然有

    vw

    整個視窗寬度的

    1%

    ,
    nav {
      display: flex;
      justify-content: center;
      align-items: center;
      height: 100vh;
      background-color: #F3F4F6;
    }
               
  3. 設定具體的

    tab

    标簽

    要求很簡單, 隻占整個

    nav

    80%

    , 占多少都行, 這主要是為了截圖友善🤭

    positive

    定位為了友善滑動條的定位
    nav .container {
      display: flex;
      justify-content: space-evenly;
      align-items: center;
      background-color: #fff;
      padding: 4px;
      position: relative;
      width: 80%;
    }
               
  4. 隐藏

    radio

    , 同時設定當這個

    radio

    狀态為

    checked

    時, 對應的

    label

    顔色的改變 ( 使用了相鄰兄弟選擇器

    +

    )
    input[type="radio"] {
      display: none;
    }
    input[type="radio"]:checked + label {
      color: #185ee0;
    }
               
  5. 設定

    label

    , 居中顯示
    label {
      display: flex;
      justify-content: center;
      align-items: center;
    }
               
  6. 設定滑動條

    注意

    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;
}