如何为包含可显示/隐藏文本元素的li容器添加transition-duration实现平滑变形效果
解决CSS Transition不生效的问题
嘿,我来帮你搞定这个平滑过渡的问题!你现在的过渡效果没生效,主要有两个核心原因:
问题根源
height: auto/width: auto无法被过渡:CSS过渡只能作用于有具体数值的属性,auto是一个不确定的值,浏览器没法计算过渡的中间状态,所以直接跳变了。- 过渡属性没加对元素:你要过渡的是
<p>元素的透明度、高度和宽度,所以transition得加到<p>上,而不是父元素<li>(当然如果li本身有样式变化需要过渡也可以加,但这里核心是p的动画)。
解决方案:用max-height模拟height: auto的过渡
最灵活的方式是用max-height代替height: auto,我们可以给它设置一个足够大的数值(确保能容纳所有文本内容),从0过渡到这个数值,就能实现类似高度展开的平滑效果。
修改后的完整代码
CSS部分
li{ overflow: hidden; background: #141516; box-shadow: inset 0px 10px 1px rgba(0, 0, 0, 0.25); border-radius: 46px; font-size: 36px; margin-bottom : auto; color: #eee; } li img{ width: 200px; height: 100px; padding: 25px 30px 30px; margin: 10px auto 0; } li p{ opacity: 0; width: 0; max-height: 0; /* 用max-height替代height,初始为0 */ overflow: hidden; /* 隐藏超出max-height的内容 */ /* 给p添加过渡,指定要过渡的属性、时长和缓动效果 */ transition: opacity 0.3s ease, max-height 0.5s ease, width 0.3s ease; } /* 用CSS hover实现更简洁,也可以保留你的JS逻辑 */ li:hover p{ opacity: 1; width: auto; /* width:auto可以正常显示,或者设具体值过渡更稳定 */ max-height: 200px; /* 设一个足够大的数值,确保能容纳所有文本内容 */ }
(可选)如果保留JS逻辑
如果你不想用CSS hover,继续用JS的话,只需要修改JS里的样式设置,同时确保<p>已经加了上面的transition属性:
const li = document.querySelectorAll("li") li.forEach((element)=>{ element.addEventListener("mouseover",()=>{ const p = element.querySelector("p"); p.style.opacity = "1"; p.style.maxHeight = "200px"; // 换成max-height,不要用height:auto p.style.width = "auto"; }) element.addEventListener("mouseout",()=>{ const p = element.querySelector("p"); p.style.opacity = "0" p.style.maxHeight = "0"; p.style.width = "0"; }) })
额外小提示
- 如果你知道
<p>内容的固定高度,直接用固定的height值过渡会更精准;如果内容高度不确定,max-height是最优解。 - 可以调整transition里的时长(比如
0.5s改成0.8s)和缓动函数(ease换成ease-in-out)来优化动画效果。
内容的提问来源于stack exchange,提问作者Mathis
相关产品推荐
相关产品推荐

