grid 布局,解决内容溢出,minmax(0, 1fr) 和 1fr的区别

1,404 阅读4分钟

前言

开发的时候遇到一个问题,这是页面

申请内容这部分,高度溢出了。预期效果是在卡片内出现滚动条,然而页面表现却不如预期。于是对我的css样式debug了半小时,最终发现了问题,并成功解决

我的css

页面代码我就不贴了,只贴下原本的css吧

.modalBody {
  height: 880px;
  background: linear-gradient(
    0deg,
    rgba(229, 239, 252, 1) 0%,
    rgba(229, 239, 252, 1) 100%
  );
  box-sizing: border-box;
  padding: 32px 50px;
  display: grid;
  gap: 40px;
  grid-template-columns: 1fr 1fr 490px;
  grid-template-rows: 245px 1fr;
  grid-template-areas: "a a b" "c d b";


  > :nth-child(1) {
    grid-area: a;
    position: relative;

    &::after {
      content: "";
      background-image: url("@/assets/images/applyRecord/zhuangshibg.png");
      background-size: 100% 100%;
      position: absolute;
      width: 212px;
      height: 212px;
      inset: auto 40px 15px auto;
    }
  }

  > :nth-child(2) {
    grid-area: b;
  }

  > :nth-child(3) {
    grid-area: c;
  }

  > :nth-child(4) {
    grid-area: d;
  }
}

/** 内容区域css **/
.header {
  width: 126px;
  height: 42px;
  border-radius: 10px 10px 0px 0px;

  background: linear-gradient(
    0deg,
    rgba(139, 183, 254, 1) 0%,
    rgba(114, 157, 252, 1) 100%
  );
  color: rgba(255, 255, 255, 1);
  font-size: 20px;
  font-weight: bold;
  text-align: center;
  line-height: 42px;
}

.content {
  height: calc(100% - 42px);
  overflow: auto;
  padding: 35px 30px;
  box-sizing: border-box;
  border-radius: 0px 10px 10px 10px;
}



css使用的grid布局,申请内容位于grid-area:c中,如代码所示content区域已经设置高度height: calc(100% - 42px);overflow:auto,在内容未溢出时,css正常工作,但是content内容溢出时,就发生了如上图所示的问题,且overflow未生效,内容区域被撑开,然后就开始debug

debug过程

我的第一反应是高度未正常设置,但好像并非如此

.modalBody {height:880px, grid-template-rows: 245px 1fr;}


.header { height: 42px;} .content { height: calc(100% - 42px); }


我应该明确指定了高度,我是这样想的,如果出现问题就应该是我对 1fr 存在理解偏差

这是阮一峰老师的经典文章,相信很多同学都看过,非常的模糊,然后我之前的理解就是它会尽可能占据父容器剩余的空间

那么当内容超过剩余空间,也就是内容溢出后将如何表现呢?

当我查询1fr的系统性说明


它会缩小到内容的最小高度!!!!


真相大白了

解决问题

为了解决这个问题就要使用minmax()函数了

minmax(0, 1fr) 提供了一种更灵活的方式来应对高度不确定的内容。它允许内容在空间不足时缩小到 0,而 1fr 则始终试图占用尽可能多的空间。

然后css 就改为这个样子


.modalBody {
//before
grid-template-rows: 245px 1fr;

//after
grid-template-rows: 245px minmax(0, 1fr);

}

grid-template-rows: 245px 1fr;

  • 解释: 这表示网格的第一行高度为 245px,第二行高度为 1fr。
  • 行为: 第二行将尽可能占用剩余的空间。如果剩余空间是负的(例如,内容溢出),第二行将会缩小到 0 高度或其内容的最小高度。

grid-template-rows: 245px minmax(0, 1fr);

  • 解释: 这表示网格的第一行高度为 245px,第二行高度在 0 到 1fr 之间。
  • 行为: 第二行的高度可以在 0 和 1fr 之间伸缩,最小高度是 0,最大高度是 1fr。即使内容溢出,这个设置会确保第二行至少有 0 的高度,不会因为内容过多而使网格失效。

区别总结

  • 弹性: minmax(0, 1fr) 提供了更多的弹性,明确规定了行的最小高度和最大高度。这样即使没有足够的空间,第二行也会保持在 0 和 1fr 之间。
  • 溢出行为: 使用 minmax(0, 1fr) 可以更好地处理内容溢出的情况,因为它允许第二行高度缩小到 0,而 1fr 则会尽量占用剩余空间,但在空间不足时行为可能不如 minmax 明确。

示例

假设 .modalBody 的高度不足以完全展示所有内容:

<div class="modalBody">
  <div>Item 1 (245px height)</div>
  <div>Item 2 (Flexible height)</div>
  <div>Item 3</div>
  <div>Item 4</div>
</div>
  • grid-template-rows: 245px 1fr;

    .modalBody {
      display: grid;
      grid-template-rows: 245px 1fr;
    }
    
    • 第二行会尝试占用所有剩余空间,如果空间不足,会导致内容溢出到网格外。
  • grid-template-rows: 245px minmax(0, 1fr);

    .modalBody {
      display: grid;
      grid-template-rows: 245px minmax(0, 1fr);
    }
    
    • 第二行高度在 0 和 1fr 之间伸缩,不会因为空间不足而导致网格失效。

使用 minmax(0, 1fr) 可以更灵活地应对高度不够的情况。

最后效果

完美解决