如何仅用CSS实现动画播放结束后自动从头循环播放
纯CSS实现交通灯无限循环方案
你之前直接给单个动画加infinite不生效的核心原因有两个:
- 三个灯的动画是独立计时的,单个动画加无限循环后,只会在自己1秒播放完成后立刻重启,不会等其余灯的动画跑完,原本设置的延迟只在首次加载时生效,后续循环不会按红→黄→绿的顺序依次点亮
- 原有动画关键帧只写了从灰色点亮的过渡逻辑,没有写灯亮后恢复灰色的熄灭逻辑,第一次播放完三个灯就会保持常亮状态卡住
正确实现不需要JavaScript,只要把三个灯的动画时间轴对齐到同一个总周期,再统一加无限循环参数即可,修改步骤如下:
- 给三个灯的动画设置相同的总时长,这里按红、黄、绿各亮1秒算,总时长设为3秒,统一加
infinite参数,去掉单独设置的延迟 - 重写三个动画的关键帧,让每个灯只在自己对应的周期段点亮,其余时间保持灰色熄灭状态
修改后完整CSS代码
* { box-sizing: border-box; } :root { --cadetblue: #5F9EA0; --darkblue: #282845; --green: #14A014; --yellow: #FFD801; --red: #FF0A0A; } body { margin: 0; padding: 0; background-color: var(--cadetblue); } .complete-section { width: 100vw; height: 100vh; display: flex; justify-content: center; align-items: center; } .traffic-body { width: 140px; height: 400px; border-radius: 120px; background-color: var(--darkblue); } .light { width: 100px; height: 100px; border-radius: 100%; margin: auto; margin-top: 20px; } .circle-red { /* 总周期3秒,无限循环 */ animation: circlered 3s infinite; background-color: grey; } .circle-yellow { animation: circleyellow 3s infinite; background-color: grey; } .circle-green { animation: circlegreen 3s infinite; background-color: grey; } @keyframes circlered { /* 前1/3周期红灯亮 */ 0%, 32% { background-color: var(--red); } /* 剩余周期红灯熄灭 */ 33%, 100% { background-color: grey; } } @keyframes circleyellow { /* 前1/3周期黄灯熄灭 */ 0%, 32% { background-color: grey; } /* 中间1/3周期黄灯亮 */ 33%, 65% { background-color: var(--yellow); } /* 最后1/3周期黄灯熄灭 */ 66%, 100% { background-color: grey; } } @keyframes circlegreen { /* 前2/3周期绿灯熄灭 */ 0%, 65% { background-color: grey; } /* 最后1/3周期绿灯亮 */ 66%, 100% { background-color: var(--green); } }
HTML部分不需要做任何修改,直接用原有代码即可。
如果需要调整每个灯的点亮时长,只要修改动画总时长,再对应调整关键帧里的百分比分界点就可以,比如要红灯亮1.5秒、黄灯亮0.5秒、绿灯亮2秒,就把总动画时长改成4秒,再按时间占比调整各关键帧的百分比数值。
内容的提问来源于stack exchange,提问作者Elizabeth
相关产品推荐
相关产品推荐

