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

如何实现CSS过渡仅在元素宽度减小时生效,宽度增大时无过渡?

如何实现CSS过渡仅在元素宽度减小时生效,宽度增大时无过渡?

这个需求挺实用的,纯CSS确实没法直接判断元素宽度的变化方向,不过咱们结合一点JavaScript就能轻松实现!下面给你一步步拆解方案:

第一步:准备基础CSS样式

我们给元素默认设置无过渡,然后专门定义一个类来控制“缩小过渡”的效果:

.element-class {
    /* 默认状态:宽度变化无过渡 */
    transition: width 0ms;
}
.element-class.shrinking {
    /* 仅当元素缩小时,应用过渡动画 */
    transition: width 500ms ease 0ms;
}

第二步:用JavaScript监听宽度变化并动态切换类

这里推荐用现代浏览器支持的ResizeObserver API来监听元素尺寸变化,它比定时检测性能更好,响应也更及时:

// 获取目标元素
const targetElement = document.querySelector('.element-class');
// 记录元素初始宽度
let lastWidth = targetElement.offsetWidth;

// 创建尺寸观察器
const resizeObserver = new ResizeObserver(entries => {
  entries.forEach(entry => {
    const currentWidth = entry.contentRect.width;
    
    if (currentWidth < lastWidth) {
      // 宽度在缩小,添加过渡类
      targetElement.classList.add('shrinking');
    } else if (currentWidth > lastWidth) {
      // 宽度在增大,移除过渡类
      targetElement.classList.remove('shrinking');
      // 强制触发浏览器重绘,避免过渡状态残留
      void targetElement.offsetWidth;
    }
    
    // 更新记录的宽度值
    lastWidth = currentWidth;
  });
});

// 开始监听元素尺寸变化
resizeObserver.observe(targetElement);

兼容性降级方案(针对旧浏览器)

如果需要兼容不支持ResizeObserver的旧浏览器(比如IE),可以用定时检测的方式替代:

const targetElement = document.querySelector('.element-class');
let lastWidth = targetElement.offsetWidth;

// 定时检测宽度变化,间隔可根据需求调整
setInterval(() => {
  const currentWidth = targetElement.offsetWidth;
  
  if (currentWidth < lastWidth) {
    targetElement.classList.add('shrinking');
  } else if (currentWidth > lastWidth) {
    targetElement.classList.remove('shrinking');
    void targetElement.offsetWidth;
  }
  
  lastWidth = currentWidth;
}, 50);

原理说明

  • CSS本身没有能力检测属性的变化方向,只能基于当前元素状态应用样式,所以必须借助JS来判断宽度是在增大还是缩小。
  • 当宽度增大时,我们移除过渡类,此时元素用默认的transition: width 0ms,宽度会瞬间变化;当宽度缩小时,添加过渡类,就会触发你想要的500ms平滑过渡。

备注:内容来源于stack exchange,提问作者luckycoder

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.17 09:28:07