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

如何实现不触发浏览器窗口调整抖动的slide-in滑入动画

问题根因

页面抖动是因为元素动画初始状态横向位移到视窗外时,触发了页面横向滚动条出现,挤占视口宽度导致布局重排。以下是两种可直接落地的解决方案:


方案1:纯CSS快速修复

适合不需要复杂交互的场景,两行代码即可解决:

  1. 给页面根节点加横向溢出隐藏,直接禁止横向滚动条触发:
html, body {
  overflow-x: hidden;
}
  1. 补全优化现有动画代码,增加透明度控制和动画填充模式,避免初始状态闪显:
@keyframes slideFromRight {
  0% {
    transform: translateX(800px) translateY(-80px);
    opacity: 0;
  }
  100% {
    transform: translateX(0) translateY(0);
    opacity: 1;
  }
}

.img--berk {
  float: right;
  width: 335px;
  height: 213px;
  margin-top: 1%;
  margin-right: 1%;
  margin-left: 1%;
  border-radius: 9%;
  border: 4px solid var(--blue);
  /* both属性等于同时设置backwards和forwards,初始状态自动应用0%帧样式,动画结束保持100%帧样式 */
  animation: slideFromRight 1.2s cubic-bezier(0.35,-0.15, 0.63, 1.58) both;
}

方案2:React + IntersectionObserver 按需触发动画(更稳妥)

从根源避免元素溢出视窗,适合多元素动画、需要兼容小屏设备的场景:

  1. 封装自定义Hook监听元素是否进入视窗:
import { useEffect, useRef, useState } from 'react';

const useSlideInAnimation = (threshold = 0.1) => {
  const ref = useRef(null);
  const [isVisible, setIsVisible] = useState(false);

  useEffect(() => {
    const observer = new IntersectionObserver((entries) => {
      entries.forEach(entry => {
        if (entry.isIntersecting) {
          setIsVisible(true);
          observer.unobserve(entry.target);
        }
      })
    }, { threshold });

    if (ref.current) observer.observe(ref.current);
    return () => ref.current && observer.unobserve(ref.current);
  }, [threshold]);

  return [ref, isVisible];
};
  1. 组件内调用Hook绑定元素:
const YourPageComponent = () => {
  const [imgRef, isImgVisible] = useSlideInAnimation();
  return (
    <img 
      ref={imgRef}
      className={`img--berk ${isImgVisible ? 'slide-active' : ''}`}
      src="你的图片资源地址"
      alt="图片描述"
    />
  );
};
  1. 调整CSS逻辑,仅在元素进入视窗后触发动画:
@keyframes slideFromRight {
  0% {
    transform: translateX(100vw) translateY(-80px);
    opacity: 0;
  }
  100% {
    transform: translateX(0) translateY(0);
    opacity: 1;
  }
}

.img--berk {
  float: right;
  width: 335px;
  height: 213px;
  margin-top: 1%;
  margin-right: 1%;
  margin-left: 1%;
  border-radius: 9%;
  border: 4px solid var(--blue);
  /* 初始状态保持在最终位置,仅透明隐藏,不会溢出视窗 */
  opacity: 0;
}

.img--berk.slide-active {
  animation: slideFromRight 1.2s cubic-bezier(0.35,-0.15, 0.63, 1.58) forwards;
}

额外优化建议

把固定位移值translateX(800px)改成translateX(100vw),可以适配所有屏幕尺寸,避免小屏设备位移距离不够、大屏设备位移距离不足的问题。

内容的提问来源于stack exchange,提问作者PKPed

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.06 06:39:00