如何用纯CSS3实现聚焦父元素时显示子元素的平滑resize过渡?
纯CSS3实现父元素随子元素显隐平滑过渡尺寸
当然可以!我之前也踩过类似的坑——直接用width/height过渡到auto根本不生效,试了visibility又没法触发尺寸变化,后来发现用**max-height/max-width配合CSS过渡**是最靠谱的纯CSS方案,完全不需要JS或jQuery。
核心原理
CSS过渡不支持height: auto或width: auto的动画,但我们可以用max-height/max-width来模拟:给父元素设置一个收起时的固定max-*值,展开时设置一个远大于子元素最大可能尺寸的max-*值,配合overflow: hidden就能实现平滑的尺寸过渡效果。
垂直方向展开/收起示例(最常用场景)
先看基础的HTML结构:
<div class="parent" tabindex="0"> 点击或聚焦我展开 <div class="child"> 这是动态高度的子元素内容<br> 可以有多行文本<br> 高度完全自适应 </div> </div>
对应的CSS代码:
.parent { border: 1px solid #ddd; padding: 12px; /* 核心过渡属性 */ transition: max-height 0.3s ease-in-out; /* 收起时的max-height:等于父元素不含子元素时的高度 */ max-height: 44px; overflow: hidden; cursor: pointer; } /* 聚焦时触发展开 */ .parent:focus { /* 设置一个足够大的值,确保能容纳子元素的最大高度 */ max-height: 500px; outline: none; } .child { margin-top: 10px; padding-top: 10px; border-top: 1px dashed #eee; }
水平方向展开/收起示例
如果需要横向的尺寸过渡,只需要把max-height换成max-width,再调整相关布局属性:
<div class="parent-horizontal" tabindex="0"> 点击展开 <span class="child-horizontal">这是横向的子元素内容</span> </div>
.parent-horizontal { border: 1px solid #ddd; padding: 8px 12px; transition: max-width 0.3s ease; /* 收起时的宽度 */ max-width: 80px; overflow: hidden; white-space: nowrap; /* 防止文本换行 */ cursor: pointer; } .parent-horizontal:focus { max-width: 300px; } .child-horizontal { margin-left: 8px; color: #666; }
为什么你之前的方法没生效?
width/height过渡:CSS不支持auto值的过渡动画,固定值过渡没法适配动态变化的子元素尺寸visibility:这个属性只控制元素是否可见,不会改变元素的布局空间,所以父元素不会产生尺寸变化calc():只能计算固定数值组合,无法动态获取子元素的实际尺寸,没法实现自适应过渡
小优化建议
如果担心max-*设置太大导致动画首尾有延迟,可以根据子元素的大致尺寸范围设置一个更接近的最大值;另外可以给子元素加上visibility: hidden,在父元素收起时隐藏,展开时设为visible,避免子元素在收起状态下仍可交互:
.child { visibility: hidden; transition: visibility 0s 0.3s; /* 延迟隐藏,配合max-height过渡 */ } .parent:focus .child { visibility: visible; transition: visibility 0s; /* 立即显示 */ }
内容的提问来源于stack exchange,提问作者Kapcash
相关产品推荐
相关产品推荐

