页面加载时transition导致圆形菜单元素移位问题求助
解决Chrome中圆形菜单移位及层级异常问题
问题根源
- 定位属性冲突:初始时
.opener通过top:50%/left:50%+transform: translate(-50%,-50%)实现居中,复选框选中后又修改top/left属性,导致translate的偏移与新的top/left叠加,计算出的位置偏离预期。 - 过渡属性范围过大:使用
transition: all会让包括top/left在内的所有可过渡属性同时动画,Chrome渲染引擎处理这类混合过渡时易出现错位。
修复方案
- 统一用
margin实现初始居中,移除transform中的translate(-50%,-50%),避免定位冲突。 - 菜单展开时,通过
transform: translate(x,y) scale(1)控制位置和缩放,不再修改top/left。 - 明确指定过渡属性,只对
transform和font-size做动画,减少不必要的渲染开销。
修改后的完整代码
CSS代码
/*reset*/ *, *::before, *::after{ -webkit-box-sizing: border-box; -moz-box-sizing: border-box; box-sizing: border-box; margin: 0; padding: 0; } ul,li{ list-style: none; } a{ text-decoration: none; } img{ display: block; } /*default*/ body{ background-color: #d9d9d9; } /*start*/ #btn{ display: none; } .main{ width: 70px; height: 70px; border-radius: 50%; background-color: #3f3faf; text-align: center; line-height: 70px; font-size: 30px; color: #fff; position: absolute; top: 50%; left: 50%; transform: translate(-50%,-50%); cursor: pointer; z-index: 2; } .opener { width: 70px; height: 70px; overflow: hidden; border-radius: 50%; background-color: #3f3faf; position: absolute; top: 50%; left: 50%; /* 用margin替代translate实现居中 */ margin-top: -35px; margin-left: -35px; transform: scale(0); z-index: 1; cursor: pointer; text-align: center; line-height: 70px; font-size: 0; color: #fff; /* 明确过渡属性,避免all带来的冲突 */ transition: transform .4s, font-size .4s; } .op-1{ transition-delay: .1s; } .op-2{ transition-delay: .2s; } .op-3{ transition-delay: .3s; } .op-4{ transition-delay: .6s; } .op-5{ transition-delay: .7s; } .op-6{ transition-delay: .8s; } #btn:checked~.opener { transform: scale(1); font-size: 30px; } /* 改用transform: translate控制展开位置 */ #btn:checked~.op-1{ transform: translate(60px, -120px) scale(1); } #btn:checked~.op-2{ transform: translate(120px, 0) scale(1); } #btn:checked~.op-3{ transform: translate(60px, 120px) scale(1); } #btn:checked~.op-4{ transform: translate(-60px, -120px) scale(1); } #btn:checked~.op-5{ transform: translate(-120px, 0) scale(1); } #btn:checked~.op-6{ transform: translate(-60px, 120px) scale(1); }
HTML代码(无需修改)
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Circle Menu</title> <link rel="stylesheet" href="css/font-icon.css"> <link rel="stylesheet" href="css/style.css"> </head> <body> <input type="checkbox" id="btn"> <label for="btn" class="main icon-menu"></label> <div class="opener op-1 icon-google2"></div> <div class="opener op-2 icon-facebook2"></div> <div class="opener op-3 icon-telegram"></div> <div class="opener op-4 icon-twitter"></div> <div class="opener op-5 icon-linkedin"></div> <div class="opener op-6 icon-pinterest"></div> </body> </html>
补充说明
- 你可以调整
translate中的数值来改变菜单展开的半径和位置,比如增大数值让菜单展开范围更大。 - 统一使用
transform做动画能保证Chrome中渲染的一致性,避免不同定位属性过渡时的冲突。
内容的提问来源于stack exchange,提问作者Omid gh
相关产品推荐
相关产品推荐

