为什么hover播放/暂停按钮时水平居中的li元素会发生位移?
问题描述
实现li元素水平居中排列,后方跟随Play或Pause按钮,使用Flexbox实现基础布局后出现hover位移问题。
故障表现
- hover按钮时,
li元素会发生位移,位置出现变化。
约束条件
- 不能给
TEXT、hover显示文本、Play或Pause设置固定宽度,文本长度可任意扩展。
现有代码
CSS
li { list-style:none; } .abc{ display: flex; align-items: center; margin: 0 auto; width: 100%; justify-content: center; } .list{ overflow: hidden; left: 0; list-style: none; display: -ms-flexbox; display: flex; flex-flow: row nowrap; justify-content: center; align-items: center; text-align: center; padding: 0; margin: 0; } .list li{ width: 52px; margin: 0 9px; } .list li button{ border: 1px solid #3A3631; width: 52px; } .p{ position: relative; height: 100%; display: flex; align-self: center; align-items: center; width: initial; left: 18px; margin-bottom: 0; } .container { padding: 8px; border: 1px solid; display: inline-flex; align-items: center; justify-content: center; transition: all 0.2s linear; } .text { display: none; } .button { border: 0; background: transparent; box-sizing: border-box; width: 0; height: 20px; border-color: transparent transparent transparent #202020; transition: 100ms all ease; cursor: pointer; border-style: solid; border-width: 10px 0 10px 20px; padding: 0 } .button.paused { border-style: double; border-width: 0px 0 0px 20px; } .button:hover { border-color: transparent transparent transparent #404040; } .container:hover span { display: inline; }
HTML
<div class="abc"> <ul class='list'> <li><button><span></span></button></li> <li><button><span></span></button></li> <li><button><span></span></button></li> <li><button><span></span></button></li> </ul> <div class="p"> <div class="container"> <button class='button'> </button> <span class="text">Play</span> </div> </div> </div>
预期效果

修复方案
问题原因
外层.abc使用普通flex布局,所有子元素共同参与宽度计算,hover时播放按钮区域因为显示文本宽度变大,触发整体flex重新居中,导致左侧li列表位移。
修复代码
仅需要修改以下CSS片段即可:
/* 调整外层容器,作为绝对定位的参照物 */ .abc{ position: relative; display: flex; align-items: center; margin: 0 auto; width: 100%; justify-content: center; } /* 把右侧播放按钮区改为绝对定位,不参与flex宽度计算 */ .p{ position: absolute; right: calc(50% - 190px); /* 可根据实际需求调整偏移量,适配不同长度的li列表 */ top: 50%; transform: translateY(-50%); display: flex; align-items: center; margin-bottom: 0; } /* 优化文本显隐逻辑,避免布局抖动,不需要固定宽度 */ .text { opacity: 0; visibility: hidden; margin-left: 0; transition: all 0.2s linear; white-space: nowrap; } .container:hover .text { opacity: 1; visibility: visible; margin-left: 8px; }
效果说明
修改后左侧li列表始终保持水平居中,hover播放按钮显示文本时,仅按钮区域本身向右扩展,不会影响左侧li的位置,同时满足文本长度可任意扩展的约束。
内容的提问来源于stack exchange,提问作者user5711656
相关产品推荐
相关产品推荐

