如何在CSS Transform过渡后为字母添加浮动动画并保持位置
问题描述
我希望在.letter元素完成transform过渡后,为每个字母添加浮动动画,且动画过程中字母保持过渡后的指定位置。但我尝试添加动画后,所有字母都会回到初始位置。
原代码
CSS
@import url("https://fonts.googleapis.com/css2?family=Rubik:wght@400;500;600;700&display=swap"); body { background-color: black; margin: 0; padding: 0; box-sizing: border-box; display: flex; justify-content: center; align-items: center; height: 100vh; } .word { transition: 0.3s; opacity: 1; } p, a { color: #fff; font-size: 5vw; font-family: "Rubik", sans-serif; text-transform: uppercase; margin: 0; text-decoration: none; letter-spacing: 2px; } .line { display: flex; justify-content: space-between; } .fancy { cursor: pointer; } #txt:has(.fancy:hover) .word:not(.fancy:hover) { opacity: 0.2; } .letter { display: inline-block; transition: all 0.6s ease; } .fancy:hover .letter:nth-child(1) { transform: translate(-40%, 60%) rotate(8deg); } .fancy:hover .letter:nth-child(2) { transform: translate(20%, -60%) rotate(0deg); } .fancy:hover .letter:nth-child(3) { transform: translate(-70%, 80%) rotate(-3deg); } .fancy:hover .letter:nth-child(4) { transform: translate(-30%, -45%) rotate(3deg); } .fancy:hover .letter:nth-child(5) { transform: translate(0%, 20%) rotate(7deg); } .fancy:hover .letter:nth-child(6) { transform: translate(10%, 30%) rotate(2deg); } .fancy:hover .letter:nth-child(7) { transform: translate(20%, 60%) rotate(3deg); } .fancy:hover .letter:nth-child(8) { transform: translate(-20%, 30%) rotate(4deg); } .fancy:hover .letter:nth-child(9) { transform: translate(69%, 0%) rotate(-3deg); } .fancy:hover .letter:nth-child(10) { transform: translate(12%, 18%) rotate(5deg); } .fancy:hover .letter:nth-child(11) { transform: translate(15%, -10%) rotate(-5deg); } .fancy:hover .letter:nth-child(12) { transform: translate(0%, 60%) rotate(9deg); }
HTML
<div id="txt"> <div class="line"> <p class="word">A</p> <p class="word">Person</p> </div> <div class="line"> <p class="word">Youtube</p> <p class="word">&</p> </div> <div class="line"> <a id="yt-link" href="www.youtube.com" class="word fancy" target="_blank"><span class="letter">C</span><span class="letter">o</span><span class="letter">d</span><span class="letter">e</span><span class="letter">p</span><span class="letter">e</span><span class="letter">n</span><span class="letter">d</span><span class="letter">e</span><span class="letter">n</span><span class="letter">c</span><span class="letter">e</span></a> </div> <div class="line"> <a id="yt-link" href="www.youtube.com" class="word fancy" target="_blank"><span class="letter">@</span><span class="letter">h</span><span class="letter">y</span><span class="letter">p</span><span class="letter">e</span><span class="letter">r</span><span class="letter">p</span><span class="letter">l</span><span class="letter">e</span><span class="letter">x</span><span class="letter">e</span><span class="letter">d</span></a> </div> </div>
解决方案
问题根源是CSS动画会直接覆盖transform属性,导致hover时设置的位置被重置。下面是具体的解决方法:
修改后的CSS代码
@import url("https://fonts.googleapis.com/css2?family=Rubik:wght@400;500;600;700&display=swap"); body { background-color: black; margin: 0; padding: 0; box-sizing: border-box; display: flex; justify-content: center; align-items: center; height: 100vh; } .word { transition: 0.3s; opacity: 1; } p, a { color: #fff; font-size: 5vw; font-family: "Rubik", sans-serif; text-transform: uppercase; margin: 0; text-decoration: none; letter-spacing: 2px; } .line { display: flex; justify-content: space-between; } .fancy { cursor: pointer; } #txt:has(.fancy:hover) .word:not(.fancy:hover) { opacity: 0.2; } .letter { display: inline-block; transition: all 0.6s ease; } /* 定义浮动动画:基于hover后的位置做小幅度偏移 */ @keyframes float { 0%, 100% { transform: inherit; /* 继承hover时的transform值 */ } 25% { transform: inherit translate(5%, -5%); /* 在原有位置基础上叠加偏移 */ } 50% { transform: inherit translate(-3%, 3%); } 75% { transform: inherit translate(2%, -2%); } } /* hover时先完成过渡,再启动浮动动画 */ .fancy:hover .letter { animation: float 2s ease-in-out infinite; animation-delay: 0.6s; /* 等待过渡完成(0.6s)后再触发动画 */ } .fancy:hover .letter:nth-child(1) { transform: translate(-40%, 60%) rotate(8deg); } .fancy:hover .letter:nth-child(2) { transform: translate(20%, -60%) rotate(0deg); } .fancy:hover .letter:nth-child(3) { transform: translate(-70%, 80%) rotate(-3deg); } .fancy:hover .letter:nth-child(4) { transform: translate(-30%, -45%) rotate(3deg); } .fancy:hover .letter:nth-child(5) { transform: translate(0%, 20%) rotate(7deg); } .fancy:hover .letter:nth-child(6) { transform: translate(10%, 30%) rotate(2deg); } .fancy:hover .letter:nth-child(7) { transform: translate(20%, 60%) rotate(3deg); } .fancy:hover .letter:nth-child(8) { transform: translate(-20%, 30%) rotate(4deg); } .fancy:hover .letter:nth-child(9) { transform: translate(69%, 0%) rotate(-3deg); } .fancy:hover .letter:nth-child(10) { transform: translate(12%, 18%) rotate(5deg); } .fancy:hover .letter:nth-child(11) { transform: translate(15%, -10%) rotate(-5deg); } .fancy:hover .letter:nth-child(12) { transform: translate(0%, 60%) rotate(9deg); }
关键修改说明
- 继承transform值:动画中用
transform: inherit保留hover时设置的位置,避免覆盖。 - 叠加偏移效果:在关键帧里基于继承的transform添加小幅度偏移,实现浮动。
- 延迟启动动画:通过
animation-delay: 0.6s让动画等过渡完成后再开始,确保字母先到位再浮动。 - 统一添加动画规则:给所有
.fancy:hover .letter统一绑定动画,减少重复代码。
内容的提问来源于stack exchange,提问作者Ahmed
相关产品推荐
相关产品推荐

