无固定高度时实现Modal尺寸变化的平滑动画
问题描述
开发了一个点击按钮后从页面底部弹出的Modal窗口,内部原本为表单,目前用带有较大上下内边距的div作为占位符。点击提交按钮后,该div会被替换为高度更小的提示类div,两者均嵌套在Modal容器内。此时Modal会因内容尺寸差异改变自身大小,但变化过程十分突兀,希望实现平滑的缩容动画。不过这两个内容div都未设置固定height属性,高度由内部内容自动撑开。尝试在相关CSS类中添加transition属性,但未实现Modal高度变化的动画效果,目前Modal的滑入和滑出动画正常,仅尺寸调整无过渡效果。
HTML代码
<div class="quote"> <div class="exit"></div> <div class="quoteForm">Form</div> <div class="quoteAlert"> Thank you for your inquiry. </div> <div class="submit"></div> </div>
CSS代码
.quote { position: fixed; bottom: 0px; right: 0px; left: 0px; /*height: 300px;*/ width: 100%; background: #9900ff; transform: translateY(800px); transition: transform .2s ease; opacity: .95; } .quote.active { transform: translateY(0px); transition: transform .2s ease; } .exit { position: absolute; top: 30px; right: 30px; width: 20px; height: 20px; cursor: pointer; } .exit span { height: 2px; width: 20px; display: block; background-color: #fafafa; margin-top: 8px; transform: rotate(45deg); } .exit span:before { width: 20px; content: ""; background-color: #fafafa; height: 2px; transform: rotate(90deg); margin-top: -4px; display: block; } .exit.active { display: none; } .submit { position: absolute; bottom: 27px; right: 33px; width: 20px; height: 20px; cursor: pointer; } .submit span { height: 2px; width: 20px; display: block; background-color: #fafafa; margin-top: 8px; } .submit span:before { width: 10px; content: ""; background-color: #fafafa; height: 2px; transform: rotate(45deg); margin-top: -4px; display: block; float: right; } .submit span:after { width: 10px; content: ""; background-color: #fafafa; height: 2px; transform: rotate(-45deg); margin-top: 4px; display: block; float: right; } .submit.active span { display: none; } .quoteForm { color: #fafafa; /*display: block;*/ padding: 90px 0 90px 0; width: 100%; text-align: center; transition: transform .9s ease; } .quoteAlert { color: #fafafa; /*display: block;*/ padding: 20px 0 20px 0; width: 100%; text-align: center; transition: transform .9s ease; }
JavaScript代码
function send(){ $('.exit').toggleClass('active'); $('.submit').toggleClass('active'); $('.quoteForm').fadeOut(0); $('.quoteAlert').fadeIn(0); $('.quote').delay(5000).fadeOut(500); }
解决方案
核心原因
CSS transition无法对height: auto的变化生效——浏览器无法计算auto到具体高度值的过渡差值,因此直接添加transition不会产生动画效果。
方案1:用max-height模拟过渡(纯CSS实现)
适合能预估内容最大高度的场景,无需额外JS逻辑:
- 修改
.quote容器的CSS,添加max-height和overflow: hidden,并扩展过渡属性:
.quote { position: fixed; bottom: 0px; right: 0px; left: 0px; width: 100%; background: #9900ff; transform: translateY(800px); transition: max-height 0.3s ease, transform .2s ease; /* 新增max-height过渡 */ opacity: .95; max-height: 0; /* 初始隐藏时高度为0 */ overflow: hidden; /* 隐藏超出容器的内容 */ } .quote.active { transform: translateY(0px); max-height: 300px; /* 设置为大于表单的最大高度(表单上下padding各90px,300px足够覆盖) */ } /* 新增提交后的状态类,控制容器高度收缩 */ .quote.submitted { max-height: 100px; /* 设置为大于提示框的最大高度(提示框上下padding各20px,100px足够覆盖) */ }
- 修改JS,在提交时给
.quote添加submitted类:
function send(){ $('.exit').toggleClass('active'); $('.submit').toggleClass('active'); $('.quoteForm').fadeOut(0); $('.quoteAlert').fadeIn(0); $('.quote').addClass('submitted'); // 触发高度收缩动画 $('.quote').delay(5000).fadeOut(500); }
方案2:用JS获取实际高度(精确适配动态内容)
如果内容高度无法预估,用JS获取两个内容块的实际高度,实现精准过渡:
- 修改
.quote的CSS,移除固定高度相关设置,添加overflow: hidden:
.quote { position: fixed; bottom: 0px; right: 0px; left: 0px; width: 100%; background: #9900ff; transform: translateY(800px); opacity: .95; overflow: hidden; /* 防止内容溢出 */ }
- 修改JS,在页面加载时设置Modal初始高度,提交时切换为提示框高度并添加过渡:
// 页面加载完成后,设置Modal初始高度(包含padding的完整高度) $(document).ready(function(){ const formHeight = $('.quoteForm').outerHeight(true); $('.quote').css('height', formHeight); }); function send(){ $('.exit').toggleClass('active'); $('.submit').toggleClass('active'); $('.quoteForm').fadeOut(0); $('.quoteAlert').fadeIn(0); // 获取提示框的完整高度 const alertHeight = $('.quoteAlert').outerHeight(true); // 给Modal添加高度过渡动画 $('.quote').css({ 'transition': 'height 0.3s ease, transform .2s ease', 'height': alertHeight }); $('.quote').delay(5000).fadeOut(500); }
内容的提问来源于stack exchange,提问作者Joey Harrison
相关产品推荐
相关产品推荐

