如何实现GIF所示图片过渡效果?解决hover时图片缩放问题
解决图片hover过渡时的缩放问题
问题说明
尝试复刻GIF的图片过渡效果:通过opacity属性在hover时切换两张图片,但使用object-fit: cover后,hover时扩大容器宽度会导致图片出现缩放跳动的问题。
解决方案
核心思路是让hover时显示的第二张图片提前设置目标宽度(即容器hover后的宽度),避免容器宽度变化时图片被强制缩放,同时固定图片的裁剪位置,保证过渡平滑。
修改后的完整代码
CSS代码
@import url('https://fonts.googleapis.com/css2?family=Montserrat&family=Roboto&family=Shantell+Sans:ital,wght@1,300&display=swap'); * { padding: 0; margin: 0; box-sizing: border-box; } :root{ --small : url("https://i.ibb.co/1MYMcPX/MV5-BY2-Q1-Zj-Bj-MTMt-Nj-Qx-OS00-OTRk-LThm-Zj-Ut-ZWUy-Mz-Vh-MTA4-MGE1-Xk-Ey-Xk-Fqc-Gde-QXVy-NTgx-ODY.jpg"); --image : url("https://i.ibb.co/TMn41Gs/ezgif-com-gif-maker.jpg"); } body { min-height: 100vh; display: flex; justify-content: center; align-items: center; } body::after{ position:absolute; width:0; height:0; overflow:hidden; z-index:-1; content: var(--image) } .container{ white-space: nowrap; overflow-x: scroll; scrollbar-width: none; justify-content: flex-start; width: 600px; } .container::-webkit-scrollbar { width: 0; height: 0; } .item{ display: inline-block; height: 160px; width: 130px; position: relative; transition: all 0.5s linear; overflow: hidden; /* 裁剪超出容器的图片部分 */ } img{ position: absolute; object-fit: cover; height: 100%; border-radius: 0.5rem; object-position: center center; /* 固定裁剪中心,避免位置偏移 */ } img:nth-child(1){ opacity: 1; width: 100%; /* 第一张图始终适配容器宽度 */ } img:nth-child(2){ opacity: 0; width: 300px; /* 提前设置为容器hover后的宽度,避免缩放 */ left: 0; /* 固定左侧对齐 */ } .item:hover{ width: 300px; } .item:hover img:nth-child(1){ opacity: 0; } .item:hover img:nth-child(2){ opacity: 1; }
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"> <link rel="stylesheet" href="style.css"> <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.4/jquery.min.js" integrity="sha512-pumBsjNRGGqkPzKHndZMaAG+bir374sORyzM3uulLV14lN5LyykqNk8eEeUlUkB3U0M4FApyaHraT65ihJhDpQ==" crossorigin="anonymous" referrerpolicy="no-referrer"></script> <title>Goggle movies</title> <script src="index.js" defer></script> </head> <body> <div class="container"> <div class="item"> <img src="https://i.ibb.co/1MYMcPX/MV5-BY2-Q1-Zj-Bj-MTMt-Nj-Qx-OS00-OTRk-LThm-Zj-Ut-ZWUy-Mz-Vh-MTA4-MGE1-Xk-Ey-Xk-Fqc-Gde-QXVy-NTgx-ODY.jpg" alt=""> <img src="https://i.ibb.co/TMn41Gs/ezgif-com-gif-maker.jpg" alt=""> </div> <div class="item"> <img src="https://i.ibb.co/1MYMcPX/MV5-BY2-Q1-Zj-Bj-MTMt-Nj-Qx-OS00-OTRk-LThm-Zj-Ut-ZWUy-Mz-Vh-MTA4-MGE1-Xk-Ey-Xk-Fqc-Gde-QXVy-NTgx-ODY.jpg" alt=""> <img src="https://i.ibb.co/TMn41Gs/ezgif-com-gif-maker.jpg" alt=""> </div> <div class="item"> <img src="https://i.ibb.co/1MYMcPX/MV5-BY2-Q1-Zj-Bj-MTMt-Nj-Qx-OS00-OTRk-LThm-Zj-Ut-ZWUy-Mz-Vh-MTA4-MGE1-Xk-Ey-Xk-Fqc-Gde-QXVy-NTgx-ODY.jpg" alt=""> <img src="https://i.ibb.co/TMn41Gs/ezgif-com-gif-maker.jpg" alt=""> </div> <div class="item"> <img src="https://i.ibb.co/1MYMcPX/MV5-BY2-Q1-Zj-Bj-MTMt-Nj-Qx-OS00-OTRk-LThm-Zj-Ut-ZWUy-Mz-Vh-MTA4-MGE1-Xk-Ey-Xk-Fqc-Gde-QXVy-NTgx-ODY.jpg" alt=""> <img src="https://i.ibb.co/TMn41Gs/ezgif-com-gif-maker.jpg" alt=""> </div> </div> </body> </html>
修改要点说明
- 给
.item添加overflow: hidden,确保超出容器的图片部分被裁剪,避免布局混乱。 - 给两张图片设置
object-position: center center,固定图片的裁剪中心,保证过渡过程中图片主体位置一致。 - 将第二张图片的宽度固定为容器hover后的目标宽度(300px),初始状态下仅显示容器宽度内的部分,hover时容器宽度扩大,图片完整显示,避免了缩放跳动。
- 保持
opacity的过渡动画,实现两张图片的平滑切换。
内容的提问来源于stack exchange,提问作者gaito Uzumaki
相关产品推荐
相关产品推荐

