如何实现元素的两列等量布局(元素高度不拉伸)?
需求与问题
我需要实现一种布局:元素数量不固定,要分成两列等量元素,且每个元素保持自身高度,不会被拉伸到所在行的最大高度。目前用了Flex布局的容器和元素样式,搭配AngularJS的HTML代码,但效果不符合预期,求最优实现方案。
当前使用的代码
容器样式
.script-objections-container { display: flex; flex-flow: row wrap; align-content: space-between; width: 100%; counter-reset: items; overflow-y: auto; }
元素样式
.script-objection-container { background-color: #fff; border: 2px solid #ead5ff; box-shadow: 0 3px 6px rgb(230 233 244 / 60%); border-radius: 8px; padding: 15px; width: 48%; margin-top: 0; margin-bottom: 2%; margin-left: 0; margin-right: 2%; } .script-objection-container .script-objection-header { font-family: 'Poppins'; font-style: normal; font-weight: 500; font-size: 14px; line-height: 21px; color: #375591; }
AngularJS HTML代码
<div class="script-objections-container"> <!-- ngRepeat: Objection in GetObjections() --> <div ng-repeat="Objection in GetObjections()" class="script-objection-container ng-scope"> <div> <label class="script-objection-header ng-binding">Test</label> <!-- ngRepeat: Item in Objection.Items --> <div ng-repeat="Item in Items" class="script-objection-subject-text ng-scope"> <div style="display: inline-block; vertical-align: top; width: 10px;"> <a ng-click="ExpandOrCollapse(item)" ng-show="!!item.IsExpanded"> <img src="/images/triangle-expanse.svg"> </a> <a ng-click="ExpandOrCollapse(item)" ng-show="!item.IsExpanded" class="ng-hide"> <img src="/images/triangle-collapse.svg"> </a> </div> <div class="script-objection-subject"> <label ng-click="ExpandOrCollapse(item)" class="ng-binding">This is a test</label> </div> <!-- ngIf: !item.IsExpanded --> </div><!-- end ngRepeat: Item in Items --> </div> </div> </div>
当前效果

最优实现方案
方案1:改用CSS Grid布局(推荐)
Grid天生适配这种分栏且保持元素自身高度的需求,比Flex更直观省心:
- 修改容器样式:
.script-objections-container { display: grid; /* 自动分成2列,每列宽度均等 */ grid-template-columns: repeat(2, 1fr); /* 统一控制列、行之间的间距,替代元素margin更简洁 */ gap: 2%; width: 100%; overflow-y: auto; counter-reset: items; }
- 调整元素样式,移除多余margin:
.script-objection-container { background-color: #fff; border: 2px solid #ead5ff; box-shadow: 0 3px 6px rgb(230 233 244 / 60%); border-radius: 8px; padding: 15px; /* 宽度由Grid自动分配,去掉原有width和margin */ width: auto; margin: 0; }
该方案下,元素会自动均分至两列,且每个元素保持自身高度,不会被拉伸。
方案2:修复Flex布局问题
如果坚持使用Flex,需调整对齐逻辑并修正宽度计算:
- 修改容器样式:
.script-objections-container { display: flex; flex-flow: row wrap; /* 让元素顶部对齐,避免拉伸 */ align-items: flex-start; /* 控制列之间的间距 */ justify-content: space-between; width: 100%; counter-reset: items; overflow-y: auto; }
- 调整元素的宽度与margin:
.script-objection-container { /* 原有样式保留,调整宽度计算避免溢出 */ width: calc(50% - 1%); margin-bottom: 2%; margin-left: 0; margin-right: 0; }
注意:Flex是按行排列,当元素高度差异大时,可能出现最后一行元素占满宽度的情况,若要严格保证两列数量均等,需在AngularJS中额外拆分数组为左右两组,不如Grid方案省心。
AngularJS额外优化(可选)
将GetObjections()的结果提前赋值到作用域变量,避免ngRepeat每次 digest 循环都调用函数:
// 控制器内添加 $scope.objections = $scope.GetObjections();
HTML中修改为:
<div ng-repeat="Objection in objections" class="script-objection-container ng-scope">
内容的提问来源于stack exchange,提问作者dragnash
相关产品推荐
相关产品推荐

