如何原生无第三方包实现TabBar未选中标签的线性指示器置于线条中间
实现方案
实现思路
- 以底部全宽灰色线条作为定位父容器,指示器通过绝对定位的垂直居中规则固定在线条中间位置
- 点击标签时动态计算选中标签的位置参数,同步更新指示器的水平位置
完整代码实现
HTML 结构
<div class="tab-container"> <div class="tab-item active">首页</div> <div class="tab-item">资讯</div> <div class="tab-item">动态</div> <div class="tab-item">我的</div> <!-- 底部背景线条(轨道) --> <div class="tab-track"> <!-- 选中指示器 --> <div class="tab-indicator"></div> </div> </div>
CSS 样式
.tab-container { display: flex; position: relative; width: 100%; max-width: 500px; } .tab-item { flex: 1; padding: 14px 0; text-align: center; cursor: pointer; font-size: 14px; color: #333; } .tab-item.active { color: #1890ff; font-weight: 500; } /* 底部背景线条 */ .tab-track { position: absolute; bottom: 0; left: 0; width: 100%; height: 3px; background-color: #e8e8e8; } /* 选中指示器 */ .tab-indicator { position: absolute; /* 核心规则:垂直居中在背景线条中间 */ top: 50%; transform: translateY(-50%); height: 2px; width: 24px; background-color: #1890ff; border-radius: 1px; transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1); }
JS 逻辑(原生无依赖)
const tabList = document.querySelectorAll('.tab-item'); const indicator = document.querySelector('.tab-indicator'); // 更新指示器位置 function syncIndicator(activeTab) { const tabOffsetLeft = activeTab.offsetLeft; const tabWidth = activeTab.offsetWidth; const indicatorWidth = indicator.offsetWidth; // 计算指示器水平居中对应当前标签的左偏移值 const targetLeft = tabOffsetLeft + (tabWidth - indicatorWidth) / 2; indicator.style.left = `${targetLeft}px`; } // 初始化默认选中态 syncIndicator(document.querySelector('.tab-item.active')); // 绑定标签点击事件 tabList.forEach(tab => { tab.addEventListener('click', () => { // 切换激活态样式 document.querySelector('.tab-item.active').classList.remove('active'); tab.classList.add('active'); // 同步指示器位置 syncIndicator(tab); }); });
核心说明
- 实现指示器在底部线条中间的核心是给指示器设置
top: 50%+transform: translateY(-50%),无需计算固定偏移值,适配任意高度的底部线条 - 指示器的宽度可根据需求调整,若需要和标签文字等宽,可在
syncIndicator方法中动态获取文字宽度赋值给指示器即可
内容的提问来源于stack exchange,提问作者Acorcdev
相关产品推荐
相关产品推荐

