滚动容器main内子元素高度受限,如何实现自适应内容高度?
问题描述
滚动元素内的子元素高度为何会受父元素限制?
运行下方代码后,会看到<div class="form">的白色背景矩形高度被main元素限制,超出内容发生溢出。希望让该div能根据自身内容自由设置高度,同时main元素保持可滚动状态,该如何实现?
代码示例
CSS
:root { --colorPrimary: #12b7ff; --colorPrimaryLight: #95ccff; --colorPrimaryDark: #095880; --colorSecondary: #00BBC1; --colorSecondaryLight: #80DDDA; --colorSecondaryDark: #00676A; --colorMainBackground: white; --colorButton: var(--colorSecondary); --colorButtonBorder: var(--colorSecondary); --colorButtonHover: var(--colorSecondaryDark); --colorInputBackground: var(--colorMainBackground); --colorInputBorder: var(--colorPrimary); --colorInputBorderFocus: var(--colorPrimaryDark); --stringFontName: 'Ubuntu'; --dimenMainMargin: 10px; --dimenMainPadding: 30px; --dimenMainRadius: 10px; --dimenHeaderHeight: 50px; --dimenMainCentralDivMargin: 50px; --dimenButtonBorder: 0px; --dimenButtonBorderRadius: 5px; --dimenButtonPadding: 20px; --dimenButtonTextSize: 15px; --dimenInputBorder: 1px; --dimenInputPadding: 5px; --dimenInputBorderRadius: 5px; --dimenInputMargin: 10px; --dimenInputLabelMarginTop: 10px; --dimenParagraphSize: 16px; --timeLoadingAnimation: 2s; --timeImageHoverInTransition: 0.1s; --timeImageHoverOutTransition: 0.2s; --timeButtonHoverInTransition: 0.1s; --timeButtonHoverOutTransition: 0.2s; } main { position: fixed; display: flex; top: var(--dimenHeaderHeight); left: 0px; right: 0px; bottom: 0px; height: auto; justify-content: center; overflow: auto; } main>* { position: relative; display: block; margin-left: auto; margin-right: auto; margin-top: var(--dimenMainMargin); padding: var(--dimenMainPadding); border-radius: var(--dimenMainRadius); background: var(--colorMainBackground); } p { font-size: var(--dimenParagraphSize); } button { display: inline-block; background: var(--colorButton); border: var(--dimenButtonBorder) solid var(--colorButtonBorder); border-radius: var(--dimenButtonBorderRadius); padding: var(--dimenButtonPadding); transition: all var(--timeButtonHoverOutTransition); font-family: var(--stringFontName), sans-serif; font-size: var(--dimenButtonTextSize); font-weight: bold; cursor: pointer; } button.text { background: none; border: none; border-bottom: 1px solid var(--colorButtonBorder); border-radius: 0px; padding: 0px; margin: 0px; font-weight: normal; text-decoration: none; font-size: var(--dimenParagraphSize); } button.submit-button { width: 100%; } button:hover { background: var(--colorButtonHover); transition: all var(--timeButtonHoverInTransition); } button.text:hover { background: none; color: var(--colorButtonHover); } main div.central-div { display: flex; width: 100%; border-radius: 0px; background: var(--colorPrimary); margin-top: var(--dimenMainCentralDivMargin); } main div.central-div>div { display: inline-block; margin-left: auto; margin-right: auto; padding: var(--dimenMainPadding); border-radius: var(--dimenMainRadius); background: var(--colorMainBackground); } h1 { color: var(--colorPrimaryDark); } form h1, form p { box-align: center; } input, input[type="text"], input[type="password"], input[type="mail"] { display: block; width: 100%; background: var(--colorInputBackground); padding: var(--dimenInputPadding); border: var(--dimenInputBorder) solid var(--colorInputBorder); border-radius: var(--dimenInputBorderRadius); margin-top: var(--dimenInputMargin); margin-bottom: var(--dimenInputMargin); transition: var(--timeButtonHoverOutTransition) all ease-out; } input:focus, input[type="text"]:focus, input[type="password"]:focus, input[type="mail"]:focus { border: var(--dimenInputBorder) solid var(--colorInputBorderFocus); transition: var(--timeButtonHoverInTransition) all ease-out; } label.input-label { display: inline-block; margin-top: var(--dimenInputLabelMarginTop); }
HTML
<main> <div class="central-div"> <div class="form"> <h1> Créer un nouveau compte </h1> <p>Je souhaite plutôt <button class="text">me connecter</button></p> <label class="input-label">Nom d'utilisateur</label> <input type="text"> <label class="input-label">Adresse mail</label> <input type="text"> <label class="input-label">Mot de passe</label> <input type="password"> <label class="input-label">Confirmez votre mot de passe</label> <input type="password"> <button class="submit-button"> Créer un compte </button> </div> </div> </main>
关键CSS片段
main { position: fixed; display: flex; top: var(--dimenHeaderHeight); left: 0px; right: 0px; bottom: 0px; height: auto; justify-content: center; overflow: auto; } main>* { position: relative; display: block; margin-left: auto; margin-right: auto; margin-top: var(--dimenMainMargin); padding: var(--dimenMainPadding); border-radius: var(--dimenMainRadius); background: var(--colorMainBackground); } main div.central-div { display: flex; width: 100%; border-radius: 0px; background: var(--colorPrimary); margin-top: var(--dimenMainCentralDivMargin); } main div.central-div>div { display: inline-block; margin-left: auto; margin-right: auto; padding: var(--dimenMainPadding); border-radius: var(--dimenMainRadius); background: var(--colorMainBackground); }
解决方案
问题根源在于Flex容器的默认对齐规则:
main是Flex容器,默认align-items: stretch,这会让它的直接子元素(.central-div)自动拉伸至与main等高,导致.central-div的高度被限制在main的可视范围内。- 同时
.central-div也是Flex容器,同样继承了align-items: stretch,让它的子元素(.form)也被拉伸至与自身等高,最终.form的高度被限制,内容溢出。
只需修改两处CSS即可解决:
- 给
main添加align-items: flex-start,让它的子元素不再被强制拉伸,而是根据自身内容高度自适应:
main { position: fixed; display: flex; top: var(--dimenHeaderHeight); left: 0px; right: 0px; bottom: 0px; height: auto; justify-content: center; overflow: auto; align-items: flex-start; /* 添加这一行 */ }
- 给
.central-div也添加align-items: flex-start,确保它的子元素.form能自由适应内容高度:
main div.central-div { display: flex; width: 100%; border-radius: 0px; background: var(--colorPrimary); margin-top: var(--dimenMainCentralDivMargin); align-items: flex-start; /* 添加这一行 */ }
修改后,.form会根据内部表单元素的总高度自动调整自身高度,当内容超出main的可视范围时,main会自动出现滚动条,同时保持整体布局的合理性。
内容的提问来源于Stack Exchange,提问作者Kaki In
相关产品推荐
相关产品推荐

