scroll-view 高度为零:min-height 打断 flex 链路的沉默 Bug
某个搜索结果页,接口数据妥妥地返回了,console.log 确认数据已经挂到 data 上,但页面就是一片空白。换了好几轮数据、加了各种调试输出,结果始终如此。最后定位到根因:scroll-view 的高度在布局层被算成了 0。
现象
- 页面有两种模式:默认"发现流"用自然页面滚动;切换到搜索结果后用
<scroll-view>接管滚动区域。 - 搜索结果接口返回正常,数据绑定正常,但搜索结果列表完全不可见。
- 开发者工具 Elements 面板查看
scroll-view节点,计算高度为0px。
根因
页面典型结构长这样:
<view class="page-wrap">
<view class="header"><!-- 固定头部 --></view>
<view class="flex-1 result-body">
<scroll-view class="ab" scroll-y>
<!-- 搜索结果列表 -->
</scroll-view>
</view>
</view>.ab 是全局工具类:
.ab {
position: absolute;
top: 0; left: 0;
width: 100%;
height: 100%;
}.flex-1 也是全局工具类:flex: 1。
问题在于 .page-wrap 只写了 min-height: 100vh,没有 display: flex; flex-direction: column。flex: 1 是 flex 子项属性,父容器不是 flex 容器时它完全不生效——.result-body 高度由内容决定,而内容只有一个 position: absolute 的 scroll-view,脱离了文档流,不贡献高度。最终:
.result-body 高度 = 0
scroll-view height: 100% → 100% × 0 = 0
内容不可见
min-height: 100vh 只保证容器至少这么高,但它不是 flex 容器,flex-1 子项算不出确定高度。height: 100% 继承的是父容器的 computed height,而不是 min-height 的值。只要链路上任意一节缺少确定高度或缺少 display: flex,下游的 height: 100% 都会塌陷到 0。
正解
对于有双模式(自然滚动 + scroll-view 滚动)的页面,用条件类切换布局,避免对两种模式都生效:
WXML:
<view class="page-wrap {{isSearch ? 'search-mode' : ''}}">
<view class="header">...</view>
<view class="flex-1 result-body">
<scroll-view class="ab" scroll-y>...</scroll-view>
</view>
</view>WXSS:
/* 默认:自然页面滚动 */
.page-wrap {
min-height: 100vh;
}
/* 搜索模式:锁定视口高度,激活 flex 列布局 */
.page-wrap.search-mode {
height: 100vh;
display: flex;
flex-direction: column;
overflow: hidden;
}
/* 结果容器填满剩余空间 */
.result-body {
flex: 1;
height: 0; /* 关键:强制 flex 分配剩余空间,而非由内容撑开 */
position: relative; /* 为 .ab 的绝对定位提供坐标系 */
width: 100%;
}height: 0 看起来反直觉,但这是 flex 布局中让子项"填满剩余空间而非内容高度"的标准写法:flex: 1 告诉 flex 算法"分配剩余空间给我",height: 0 则明确表示"我自身不依赖内容高度",两者配合才能让 .ab 拿到确定的 100% 基准。
search-mode 激活时:父容器 height: 100vh + display:flex+column → result-body 拿到确定高度 → scroll-view.ab 的 height:100% 有效。result-body 的 height: 0 是关键补丁,防止 flex 子项用内容高度(内容为 absolute,高度 0)覆盖 flex 分配结果。
一句话外卖
height: 100%向上找的是 computed height,不是min-height;flex: 1向上找的是 flex 容器——链路上任意一节断裂,高度就会悄无声息地塌成 0。