React使用styled-components实现骨架屏从左到右宽度动画问题
问题原因
- CSS 中
width属性不支持负值,你在100%关键帧写的width: -100%是无效属性,会被浏览器直接忽略,导致动画执行到50%后逻辑异常 - 单纯修改
width属性时,元素默认从左侧开始裁切,收缩阶段会从左向右缩小,无法实现「固定右侧边缘向左收缩至0」的需求
修正方案
推荐使用transform: scaleX()配合transform-origin实现,性能优于直接修改width(不会触发DOM重排),也更容易控制动画方向:
import { keyframes } from 'styled-components'; const reveal = keyframes` 0% { transform: scaleX(0); transform-origin: left center; } 50% { transform: scaleX(1); transform-origin: left center; } 50.1% { transform-origin: right center; } 100% { transform: scaleX(0); transform-origin: right center; } `; const StyledSkeleton = styled.div` height: 40px; overflow: hidden; background-color: ${colors.LOADER_BACKGROUND}; /* 无用的font-size、line-height属性可以直接删除 */ animation: ${reveal} 2s ease-in infinite; `;
实现逻辑
- 前50%动画将变换原点设为左侧,元素从X轴缩放0过渡到1,实现从左向右展开铺满的效果
- 50%的瞬间切换变换原点为右侧,后50%动画从X轴缩放1过渡到0,自然实现从右向左收缩至0的效果
如果需要兼容极端场景必须用width实现,可以用绝对定位配合left/right属性:
const reveal = keyframes` 0% { left: 0; right: 100%; } 50% { left: 0; right: 0; } 100% { left: 100%; right: 0; } `; const StyledSkeleton = styled.div` position: relative; height: 40px; overflow: hidden; &::before { content: ''; position: absolute; top: 0; bottom: 0; background-color: ${colors.LOADER_BACKGROUND}; animation: ${reveal} 2s ease-in infinite; } `;
内容的提问来源于stack exchange,提问作者cbutler
相关产品推荐
相关产品推荐

