需求
實現頂部菜單欄,切換時下劃線跟隨滑動
效果
思路
看效果,思路有2:
- 方案A:下劃線
- 設置下劃線 border-bottom
- 點擊標題後控制下劃線的展示隱藏
- 注:下劃線長度及圓角無法設置
- 方案B:模擬下劃線
- 新啓元素模,使用背景色擬下劃線效果
- 點擊標題後,計算要滑動的距離
- css3動畫移動到目標位置
以上方案對比,發現方案1缺點較大,例如無法控制下劃線長度,圓角,以及下劃線漸變色等。因此採用方案2處理。
實現步驟
本案例基於vue實現
1. 基礎佈局
<div id="app">
<div class="nav">
<!-- 標題列表 -->
<div class="nav-list">
<div v-for="(item, index) in navList" :key="item">
{{ item }}
</div>
</div>
<!-- 下劃線 -->
<div class="nav-line">
<div :style="{transform: 'translateX(' + translateX + 'px) translateX(-50%)',}"></div>
</div>
</div>
</div>
.nav {
width: 100%;
position: fixed;
top: 0;
left: 0;
z-index: 999;
background: #fff;
}
.nav .nav-list {
margin: 0 auto;
max-width: 600Px;
display: flex;
justify-content: space-around;
align-items: center;
height: 44px;
}
.nav .nav-list>div {
font-size: 16px;
font-family: PingFangSC-Regular, PingFang SC, sans-serif;
font-weight: 400;
color: #666;
line-height: 16px;
cursor: pointer;
text-align: center;
}
.nav-line {
margin: 0 auto;
}
.nav-line>div {
width: 18px;
height: 4px;
border-radius: 2px;
transition-duration: 0.3s;
position: relative;
top: -7px;
}
data: {
navList: ['首頁', '推薦', '關注', '會員', '消息'],
translateX: 0
},
運行如下:
2. 添加點擊切換事件及激活的菜單加粗
<!-- 標題列表 -->
<div class="nav-list">
<div v-for="(item, index) in navList" :key="item"
+ @click="changeTitle(index)"
+ :class="{ 'nav-list--active': index === active }"
>
{{ item }}
</div>
</div>
/* 新增激活狀態樣式 */
.nav .nav-list .nav-list--active {
font-family: PingFangSC-Semibold, PingFang SC, sans-serif;
font-weight: bold;
color: #333333;
transition: all 0.3s;
}
data: {
navList: ['首頁', '推薦', '關注', '會員', '消息'],
active: 0,
translateX: 0
},
methods: {
/**
* 點擊切換標題
* @param {number} index 菜單序列(點擊的第index個)
*/
changeTitle(index) {
this.active = index;
this.setUnderLine();
},
/**
* 設置下劃線
*/
setUnderLine() {
// 按照步驟2設置下劃線
}
},
3. 設置下劃線
/**
* 設置下劃線
*/
setUnderLine() {
+ // 屏幕寬
+ let width = document.documentElement.clientWidth;
+ // 每個菜單所佔寬度 = 屏寬 / 菜單個數
+ let slidingWidth = (width / this.navList.length).toFixed(2);
+ // 半個菜單寬度 (爲了將下劃線與菜單對齊)
+ let halfSlidingWidth = (slidingWidth / 2).toFixed(2);
+ // 水平位移目的座標 = 半個菜單寬度 + (菜單寬 x 當前所在的index)
+ this.translateX = Number(halfSlidingWidth) + Number(slidingWidth * this.active);
}
實現如下效果:
4. bug處理
如上所示,點擊後的效果完成了,但是在初始化的時候,會發現依然有問題。解決方案是在頁面加載後先執行一次setUnderLine
方法。
+ mounted() {
+ this.setUnderLine();
+ }
5. 優化
上述方案已基本滿足需求,現提出優化方案:將標題文字及下劃線採用漸變色處理
優化內容:
- 下劃線漸變色
- 標題文字漸變色
- 根據標題個數自適應【已完成】
由於我們在處理的平移距離的時候已經是根據標題個數長度去處理,因此優化3已完成。
5.1 下劃線漸變
由於下劃線是背景色填充的,因此可直接修改背景色爲漸變色:
.nav-line>div {
width: 18px;
height: 4px;
background-color: #4158D0;
+ background-image: linear-gradient(43deg, #4158D0 0%, #C850C0 46%, #FFCC70 100%);
border-radius: 2px;
transition-duration: 0.3s;
position: relative;
top: -7px;
}
5.2 文字顏色漸變
.nav .nav-list>div {
font-size: 16px;
font-family: PingFangSC-Regular, PingFang SC, sans-serif;
font-weight: 400;
color: #666;
line-height: 16px;
cursor: pointer;
text-align: center;
+ background-image: linear-gradient(43deg, #4158D0 0%, #C850C0 46%, #FFCC70 100%);
+ -webkit-background-clip: text;
+ -webkit-text-fill-color: transparent;
}
5.3 激活文字改顏色
.nav .nav-list .nav-list--active {
font-family: PingFangSC-Semibold, PingFang SC, sans-serif;
font-weight: bold;
color: #333333;
transition: all 0.3s;
+ background-color: #FFE53B;
+ background-image: linear-gradient(147deg, #FFE53B 0%, #FF2525 74%);
}
最終完成圖例效果
完整代碼關注W信G衆號【流眸】回覆【21601】獲取
小結
案例通過新增元素div來模擬下劃線,點擊時計算水平方向的目的座標,通過CSS動畫實現效果。實現方式難度適中,效果良好,並且可以在一定程度上進行優化擴展。