如何在动画中调整两个Flexbox的尺寸?
如何在动画中调整两个Flexbox的尺寸?
嗨,我来帮你拆解这个问题,先搞懂为什么你用calc(100% - 200px)会不对齐,再给你两个简单靠谱的解决方案。
先说说你遇到的核心问题
你用position: relative + left来移动div1的时候,div1其实还占据着原来的200px空间(relative定位不会脱离文档流,只是视觉上移走了)。这就导致:
- 当你给div2设
calc(100% - 200px)时,这个100%是父容器的总宽度(比如50vw),所以div2的宽度是50vw - 200px,加上div1的200px,刚好填满父容器,这时候是对的。 - 但你把div1移到左边-200px后,div1依然占着那200px的位置,这时候你给div2设
width: 100%,div2的宽度会变成50vw,但div1还占着200px,flex布局会默认压缩div2(因为flex-shrink: 1),所以实际显示的宽度根本不是你想要的100%,自然就不对齐了。
解决方案1:利用Flex自动填充特性(最推荐)
既然用了flex布局,就该用好它的自动适配能力,完全不用手动算宽度。核心思路是:让div2自动填充剩余空间,通过控制div1的宽度实现滑入滑出动画。
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <style> *{ padding: 0; margin: 0; box-sizing: border-box; } .chat-container { display: flex; height: 50vh; width: 50vw; background-color: #f0f0f0; } #div1 { background-color: #0004ff; height: 100%; width: 0; /* 默认隐藏,宽度为0 */ text-align: center; transition: width 0.3s ease; /* 宽度过渡动画 */ overflow: hidden; /* 防止内容在宽度为0时溢出 */ } #div1.active { width: 200px; /* 激活时展开到200px */ } #div2 { background-color: #ff0000; height: 100%; text-align: center; flex: 1; /* 关键:让div2自动填充父容器剩余空间 */ } </style> </head> <body> <div class="chat-container"> <div id="div1"> <p>div1</p> </div> <div id="div2"> <p>div2</p> </div> </div> <button id="button">animation</button> <script> let isActive = false; const div1 = document.getElementById("div1"); document.getElementById("button").addEventListener("click", function() { isActive = !isActive; div1.classList.toggle("active", isActive); }); </script> </body> </html>
这个方案的好处:
- 完全不用手动计算宽度,
flex:1会让div2自动适配剩余空间,div1展开/收起时,div2会同步自动调整尺寸,绝对不会有对齐问题。 - 用class控制状态,比直接修改style属性更清晰,后续加样式也更方便维护。
- 动画平滑同步,因为div1的宽度变化和div2的空间适配都是flex布局自动处理的。
解决方案2:用transform滑入滑出(保留div1原宽度)
如果你想保留div1的200px宽度,只是视觉上滑入滑出,可以用transform: translateX(不影响文档流,但需要配合控制div2的flex属性),不过这个方案稍微复杂一点,不如方案1省心。
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <style> *{ padding: 0; margin: 0; box-sizing: border-box; } .chat-container { display: flex; height: 50vh; width: 50vw; background-color: #f0f0f0; overflow: hidden; /* 隐藏超出父容器的部分 */ } #div1 { background-color: #0004ff; height: 100%; width: 200px; text-align: center; transition: transform 0.3s ease; transform: translateX(-100%); /* 默认隐藏在左边 */ flex-shrink: 0; /* 防止div1被压缩 */ } #div1.active { transform: translateX(0); /* 滑入显示 */ } #div2 { background-color: #ff0000; height: 100%; text-align: center; flex: 1; /* 自动填充剩余空间 */ transition: flex 0.3s ease; } #div1.active + #div2 { flex: 0 0 calc(100% - 200px); /* div1显示时,div2固定宽度 */ } </style> </head> <body> <div class="chat-container"> <div id="div1"> <p>div1</p> </div> <div id="div2"> <p>div2</p> </div> </div> <button id="button">animation</button> <script> let isActive = false; const div1 = document.getElementById("div1"); document.getElementById("button").addEventListener("click", function() { isActive = !isActive; div1.classList.toggle("active", isActive); }); </script> </body> </html>
这个方案的核心是用相邻兄弟选择器#div1.active + #div2来控制div2的尺寸,当div1显示时,div2的宽度固定为父容器减200px;当div1隐藏时,div2用flex:1填满整个父容器。
总结
最推荐用方案1,因为它完全利用了flex布局的优势,代码简洁,逻辑清晰,绝对不会出现尺寸不对齐的问题。你之前的calc问题本质上是没搞懂relative定位不脱离文档流,导致div1始终占据空间,而flex布局的自动适配特性可以帮你省去所有手动计算的麻烦。
备注:内容来源于stack exchange,提问作者XCZ_Mike
相关产品推荐
相关产品推荐

