如何实现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
相关产品推荐
相关产品推荐

