Firefox下@property的替代方案:圆形动画兼容问题求助
兼容全浏览器的圆形填充动画替代方案
问题背景
之前用@property实现了圆形填充动画,但@property仅部分浏览器支持,需要替换成全兼容方案。原实现通过动态修改锥形渐变的角度变量实现填充效果,尝试直接用transform: rotate没达到预期。
核心思路
放弃自定义属性,改用双层元素+旋转遮罩的方式:
- 外层容器固定圆形尺寸,作为边界
- 底层是带渐变效果的完整圆形
- 上层用白色遮罩层(和页面背景色一致),通过分阶段旋转遮罩层,逐步露出底层渐变圆形,模拟从0到360度的填充动画
完整代码实现
HTML结构
保留原有布局,调整内部元素适配新逻辑:
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> <div class="circle-graph"> <div class="graph-wrap"> <div id="graph-2"> <div class="circle-wrap"> <!-- 底层渐变圆形 --> <div class="circle-bg"></div> <!-- 旋转遮罩层 --> <div class="circle-mask"></div> <div class="outer-border"></div> <div class="inner-border"></div> <div class="fade-in-img">填充完成后的内容</div> </div> </div> </div> </div>
CSS样式
.circle-graph-info { align-items: center; display: flex; justify-content: center; margin: 0 0 0 240px; position: relative; } .circle-graph-info p { color: #479F56; font-size: 120px; font-weight: 800; margin: 0 -50px 0 0; max-width: 275px; position: relative; } .circle-graph-info span { color: #000; display: block; font-size: 28px; font-weight: 400; } .circle-graph-info p:first-of-type::before { content: ''; display: block; background: #479F56; height: 5px; left: -200px; position: absolute; top: 50%; width: 161px; border-radius: 5px; } .circle-wrap { padding: 5px; position: relative; height: 484px; width: 484px; border-radius: 50%; overflow: hidden; /* 隐藏遮罩层溢出部分 */ } /* 底层渐变圆形 */ .circle-bg { width: 100%; height: 100%; border-radius: 50%; background: rgb(138,173,81); background: linear-gradient(90deg, rgba(138,173,81,1) 0%, rgba(71,159,86,1) 0%, rgba(138,173,81,1) 100%); } /* 遮罩层:初始覆盖整个圆形,通过旋转露出底层渐变 */ .circle-mask { position: absolute; top: 0; left: 0; width: 50%; height: 100%; background: #fff; /* 必须和页面背景色一致 */ transform-origin: right center; /* 以右侧中心为旋转轴 */ animation: mask-rotate 2s .3s ease forwards; -webkit-animation: mask-rotate 2s .3s ease forwards; } /* 分阶段旋转动画,模拟完整填充效果 */ @keyframes mask-rotate { 0% { transform: rotate(0deg); width: 50%; left: 0; transform-origin: right center; } 50% { transform: rotate(180deg); width: 50%; left: 0; transform-origin: right center; } 51% { transform: rotate(0deg); width: 100%; left: 0; transform-origin: center center; } 100% { transform: rotate(360deg); width: 100%; left: 0; transform-origin: center center; } } /* 兼容webkit内核浏览器 */ @-webkit-keyframes mask-rotate { 0% { -webkit-transform: rotate(0deg); width: 50%; left: 0; -webkit-transform-origin: right center; } 50% { -webkit-transform: rotate(180deg); width: 50%; left: 0; -webkit-transform-origin: right center; } 51% { -webkit-transform: rotate(0deg); width: 100%; left: 0; -webkit-transform-origin: center center; } 100% { -webkit-transform: rotate(360deg); width: 100%; left: 0; -webkit-transform-origin: center center; } } .fade-in-img { display: none; position: absolute; z-index: 9; top: 32%; left: 0; right: 0; margin: 0 auto; width: 140px; text-align: center; } .outer-border { position: absolute; top: 0; left: 0; border-radius: 50%; box-shadow: inset 0px 0px 10px rgba(0, 0, 0, 0.25); height: 102%; width: 102%; pointer-events: none; /* 不干扰下层元素交互 */ } .inner-border { background: #fff; position: absolute; top: 32px; left: 32px; border-radius: 50%; box-shadow: 0px 0px 10px rgba(0,0,0,0.25); height: 89%; width: 89%; pointer-events: none; }
JavaScript逻辑
保留原有交互逻辑,仅调整选择器:
var circleMask = $(".circle-mask"); var circleImg = $('.fade-in-img'); // 监听动画结束事件,兼容webkit内核 circleMask.on('animationend webkitAnimationEnd', function() { $(circleImg).fadeIn(); });
方案说明
- 兼容所有支持CSS动画的浏览器(包括IE10+),无需依赖
@property - 动画分两段执行:前半段旋转半宽遮罩覆盖左半圆,后半段切换旋转轴用全宽遮罩旋转一圈,完美还原原实现的填充效果
- 遮罩层颜色必须和页面背景色一致,确保视觉上是“填充”而非单纯旋转
- 保留了原动画的时长、延迟和缓动曲线,体验和原实现完全一致
内容的提问来源于stack exchange,提问作者justDan
相关产品推荐
相关产品推荐

