CSS制作时间轴如何让连接线显示在导航按钮后方
时间轴连接线覆盖导航按钮问题解决方案
问题描述
开发时间轴组件过程中,已通过CSS实现导航节点按钮、节点间连接线样式,预期效果为连接线显示在按钮后方,实际渲染时连接线覆盖在按钮前方,不符合美观要求。
- 问题效果截图:

- 在线调试地址:CodePen 调试入口
附原始代码:
index.html
<!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> <div class="container"> <div class="head"> <ul class="nav"> <li class="st st1 active"> <img src="https://images.unsplash.com/photo-1593085512500-5d55148d6f0d?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxzZWFyY2h8Mnx8Y2FydG9vbnxlbnwwfHwwfHw%3D&auto=format&fit=crop&w=600&q=60" alt="" /> <p>Minions</p> </li> <li class="st st2"> <img src="https://images.unsplash.com/photo-1637858868799-7f26a0640eb6?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxzZWFyY2h8MTN8fGNhcnRvb258ZW58MHx8MHx8&auto=format&fit=crop&w=600&q=60" alt="" /> <p>Happy</p> </li> <li class="st st3"> <img src="https://images.unsplash.com/photo-1638803040283-7a5ffd48dad5?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxzZWFyY2h8NDF8fGNhcnRvb258ZW58MHx8MHx8&auto=format&fit=crop&w=600&q=60" alt="" /> <p>Cartoon</p> </li> <li class="st st4"> <img src="https://images.unsplash.com/photo-1637855463319-9acb4e5aa44f?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxzZWFyY2h8NDl8fGNhcnRvb258ZW58MHx8MHx8&auto=format&fit=crop&w=600&q=60" alt="" /> <p>Cat</p> </li> <li class="st st5"> <img src="https://images.unsplash.com/photo-1578632767115-351597cf2477?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxzZWFyY2h8Mnx8YW5pbWV8ZW58MHx8MHx8&auto=format&fit=crop&w=600&q=60" alt="" /> <p>anime</p> </li> </ul> <div class="line"> <span></span> </div> </div> <div class="content"> <section class="minion-section"> <img src="" alt="" /> <h1>Minion</h1> <p> Lorem ipsum dolor sit amet consectetur adipisicing elit. Cupiditate quaerat quos eligendi distinctio velit. Id, a, amet, similique saepe quaerat quam veniam suscipit exercitationem ut quidem odio? Necessitatibus, velit recusandae. </p> </section> <section class="happy-section"> <img src="" alt="" /> <h1>Happy</h1> <p> Lorem ipsum dolor sit amet consectetur adipisicing elit. Cupiditate quaerat quos eligendi distinctio velit. Id, a, amet, similique saepe quaerat quam veniam suscipit exercitationem ut quidem odio? Necessitatibus, velit recusandae. </p> </section> <section class="cartoon-section"> <img src="" alt="" /> <h1>Cartoon</h1> <p> Lorem ipsum dolor sit amet consectetur adipisicing elit. Cupiditate quaerat quos eligendi distinctio velit. Id, a, amet, similique saepe quaerat quam veniam suscipit exercitationem ut quidem odio? Necessitatibus, velit recusandae. </p> </section> <section class="cat-section"> <img src="" alt="" /> <h1>Cat</h1> <p> Lorem ipsum dolor sit amet consectetur adipisicing elit. Cupiditate quaerat quos eligendi distinctio velit. Id, a, amet, similique saepe quaerat quam veniam suscipit exercitationem ut quidem odio? Necessitatibus, velit recusandae. </p> </section> <section class="anime-section"> <img src="" alt="" /> <h1>Anime</h1> <p> Lorem ipsum dolor sit amet consectetur adipisicing elit. Cupiditate quaerat quos eligendi distinctio velit. Id, a, amet, similique saepe quaerat quam veniam suscipit exercitationem ut quidem odio? Necessitatibus, velit recusandae. </p> </section> </div> </div> </body> </html>
style.css
@import url('https://fonts.googleapis.com/css2?family=Epilogue:wght@200&display=swap'); *{ padding: 0 ; margin: 0; } body{ background-position: center; font-family: 'Epilogue', sans-serif; } img{ width: 80px; } ul { text-align: center; } ul li { display: inline-block; width: 200px; text-transform: uppercase; font-weight: 700; transition: all .3s ease; position: relative; } .container{ margin: 50px auto; width: 80vw; } ul.nav li .inner{ position: absolute; width: 100%; font-size: 14px; font-weight: bold; } ul.nav li.active, ul.nav li:hover{ color: #444; } ul.nav li::after{ content: ''; display: block; width: 7px; height: 7px; background: #777; border-radius: 50%; margin: auto; border: 7px solid #fff; margin-top: 40px; box-shadow: 0px 0px 5px 0px rgba(0, 0, 0, .2); } ul.nav li:hover::after, ul.nav li.active::after{ background: blue; } .line{ width: 76%; margin: auto; background: #eee; height: 7px; position: absolute; left: 11.5%; top: 41%; z-index: 1; border-radius: 50px; }
问题原因
两个CSS配置问题导致层级异常:
- 层叠上下文优先级错误:给连接线
.line设置了z-index:1,但导航列表ul.nav、列表项li、li生成的圆形节点(::after伪元素)都没有配置定位属性和更高的z-index值,按照CSS层叠规则,设置了z-index的定位元素会覆盖普通流元素,所以连接线盖在了按钮上方。 - 定位参考错误:包裹导航和连接线的
.head容器没有开启相对定位,当前.line的绝对定位是相对于整个页面根元素计算的,窗口尺寸变化时连接线很容易出现错位。
修复方案
不需要修改HTML结构,只需要调整CSS规则,一共改4处:
- 给
.head添加position: relative,作为内部绝对定位元素的参考容器,避免连接线位置偏移 - 给
ul.nav添加position: relative和z-index: 2,让整个导航列表层级高于连接线 - 给
ul.nav li::after(圆形节点按钮)添加position: relative和z-index: 2,保证节点按钮不会被连接线覆盖 - 保持
.line的z-index:1不变,作为最底层元素
修复后的完整CSS代码:
@import url('https://fonts.googleapis.com/css2?family=Epilogue:wght@200&display=swap'); *{ padding: 0 ; margin: 0; } body{ background-position: center; font-family: 'Epilogue', sans-serif; } img{ width: 80px; } ul { text-align: center; } ul li { display: inline-block; width: 200px; text-transform: uppercase; font-weight: 700; transition: all .3s ease; position: relative; } .container{ margin: 50px auto; width: 80vw; } /* 给head加相对定位,作为内部绝对元素的定位参考 */ .head { position: relative; } ul.nav li .inner{ position: absolute; width: 100%; font-size: 14px; font-weight: bold; } ul.nav li.active, ul.nav li:hover{ color: #444; } ul.nav li::after{ content: ''; display: block; width: 7px; height: 7px; background: #777; border-radius: 50%; margin: auto; border: 7px solid #fff; margin-top: 40px; box-shadow: 0px 0px 5px 0px rgba(0, 0, 0, .2); /* 给节点圆点加定位和高层级,保证在连线上方 */ position: relative; z-index: 2; } ul.nav li:hover::after, ul.nav li.active::after{ background: blue; } /* 给导航列表加定位和高层级 */ ul.nav { position: relative; z-index: 2; } .line{ width: 76%; margin: auto; background: #eee; height: 7px; position: absolute; left: 11.5%; top: 41%; z-index: 1; border-radius: 50px; }
修改后连接线会稳定显示在所有导航节点的下方,同时窗口缩放时连接线位置不会错位,完全符合预期效果。
内容的提问来源于stack exchange,提问作者Android Army
相关产品推荐
相关产品推荐

