CSS如何实现导航栏li元素悬停时控制对应div执行transform变换
问题核心原因
你之前尝试的所有选择器不生效的原因有两个:
- CSS 没有向上遍历父元素的选择器,你的
.red_circle和<li>不在同一父级容器下,也不是<li>的子元素,因此>、、+、~这几个选择器都无法从<li>出发匹配到.red_circle - 你写的选择器末尾多了一个多余的逗号,会导致整段样式规则失效
方案1:使用CSS :has() 选择器(无需修改HTML结构)
当前主流浏览器(Chrome 105+、Firefox 121+、Safari 15.4+)均支持:has()选择器,直接修改CSS选择器即可实现需求:
/* 给滑动块加过渡效果,让滑动更流畅 */ .red_circle { display: block; position: absolute; /* 固定定位避免影响其他元素布局 */ top: 100px; height: 50px; width: 50px; background-color: red; transition: transform 0.3s ease; } /* 选中包含被hover的第n个li的ul,再匹配ul之后相邻的.red_circle */ ul:has(li:nth-child(1):hover) + .red_circle { transform: translateX(100px); } ul:has(li:nth-child(2):hover) + .red_circle { transform: translateX(200px); } ul:has(li:nth-child(3):hover) + .red_circle { transform: translateX(300px); } ul:has(li:nth-child(4):hover) + .red_circle { transform: translateX(400px); }
方案2:兼容旧浏览器方案(调整HTML结构)
如果需要适配不支持:has()的旧浏览器,可以调整HTML结构,把.red_circle放到<ul>内部作为最后一个子元素:
调整后HTML代码:
<container> <ul> <li><a href="#">Test 1</a></li> <li><a href="#">Test 2</a></li> <li><a href="#">Test 3</a></li> <li><a href="#">Test 4</a></li> <div class="red_circle"></div> </ul> </container>
对应CSS代码:
* { list-style-type: none; } ul { display: flex; position: relative; /* 给子元素的absolute定位做参照 */ } a { display: block; padding: 1em; color: white; background-color: orange; } .red_circle { position: absolute; top: 100px; height: 50px; width: 50px; background-color: red; transition: transform 0.3s ease; } /* 用后续兄弟选择器匹配同属ul下的.red_circle */ li:nth-child(1):hover ~ .red_circle { transform: translateX(100px); } li:nth-child(2):hover ~ .red_circle { transform: translateX(200px); } li:nth-child(3):hover ~ .red_circle { transform: translateX(300px); } li:nth-child(4):hover ~ .red_circle { transform: translateX(400px); }
内容的提问来源于stack exchange,提问作者Dave
相关产品推荐
相关产品推荐

