You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.02 19:15:03