如何为<li>元素间竖线添加从上到选中项的颜色填充动画?
实现时间线竖线从顶部到当前选中项的填充动画思路
核心思路
你当前用每个<li>的::after伪元素拼接竖线,这种分散结构很难实现整体填充动画。最优方案是把竖线改成<ul>的单个伪元素,叠加一个可动画的彩色线条,结合已有的active-section类控制填充范围,无需修改现有HTML标记。
具体实现步骤
1. 重构竖线为整体结构
移除原来每个<li>的::after样式,改用<ul>的伪元素创建完整的基础白线:
/* 删除原有的 nav li::after 样式 */ nav ul { display: flex; flex-direction: column; align-items: center; position: relative; /* 新增:为伪元素提供定位基准 */ } nav ul::after { content: ''; position: absolute; left: 50%; top: 0; bottom: 0; width: 2px; background-color: #fff; /* 原白线颜色 */ transform: translateX(-50%); z-index: -1; }
2. 添加可动画的填充线条
用<ul>的::before伪元素作为彩色填充线,初始高度为0并设置过渡动画:
nav ul::before { content: ''; position: absolute; left: 50%; top: 0; width: 2px; background-color: #29aae2; /* 和hover效果统一的填充色 */ transform: translateX(-50%); z-index: -1; height: var(--fill-height, 0); transition: height 0.6s ease; /* 平滑过渡动画 */ }
3. 结合active类动态控制填充高度
利用你已有的滚动监听逻辑(给对应<a>添加active-section类),通过JS计算当前选中项到<ul>顶部的距离,动态设置填充线条高度:
function updateTimelineFill() { const activeLink = document.querySelector('nav .active-section'); if (!activeLink) return; const activeLi = activeLink.closest('li'); const ul = activeLink.closest('ul'); // 计算填充高度:active项的顶部偏移 + 自身高度的一半(让填充到圆点位置) const fillHeight = activeLi.offsetTop + activeLi.offsetHeight / 2; ul.style.setProperty('--fill-height', `${fillHeight}px`); } // 绑定到滚动和初始加载事件 window.addEventListener('scroll', updateTimelineFill); window.addEventListener('load', updateTimelineFill);
备选:纯CSS固定布局实现
如果时间线布局高度固定,也可以不用JS,直接通过CSS选择器针对不同位置的active项设置固定高度:
/* 第一个li激活时的填充高度 */ nav ul li:first-child a.active-section ~ ul::before { height: 40px; /* 根据实际布局调整数值 */ } /* 第二个li激活时的填充高度 */ nav ul li:nth-child(2) a.active-section ~ ul::before { height: 110px; } /* 依次为每个li设置对应高度 */
注意事项
- 微调
<li>的padding和圆点的top偏移值,确保圆点与竖线对齐 - 保持
z-index层级正确,避免填充线条覆盖圆点或链接内容 - 可根据需求调整
transition的动画时长和缓动函数
内容的提问来源于stack exchange,提问作者Jonny Quinn
相关产品推荐
相关产品推荐

