返回博客

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: columnflex: 1 是 flex 子项属性,父容器不是 flex 容器时它完全不生效——.result-body 高度由内容决定,而内容只有一个 position: absolutescroll-view,脱离了文档流,不贡献高度。最终:

.result-body 高度 = 0
scroll-view height: 100% → 100% × 0 = 0
内容不可见
坑:min-height 不等于 height,flex 链路会在这里断掉

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% 基准。

正解:条件类 + height:0 + position:relative 三件套

search-mode 激活时:父容器 height: 100vh + display:flex+columnresult-body 拿到确定高度 → scroll-view.abheight:100% 有效。result-bodyheight: 0 是关键补丁,防止 flex 子项用内容高度(内容为 absolute,高度 0)覆盖 flex 分配结果。

一句话外卖

height: 100% 向上找的是 computed height,不是 min-heightflex: 1 向上找的是 flex 容器——链路上任意一节断裂,高度就会悄无声息地塌成 0。