【问题标题】:Grid layout with auto columns resize with a full-width flex child具有自动列的网格布局使用全宽 flex 子项调整大小
【发布时间】:2021-06-21 20:44:55
【问题描述】:

我已经使用 CSS 网格布局创建了一个带有可扩展行的表格,并且一切正常,直到我在可扩展部分添加一个具有 flex 布局的元素。

可展开部分使用网格列:1/-1;并且内容不应该影响网格的其余部分,或者这就是我的想法。

我创建了一个简化版本来显示问题:

function toggle() {
  const elem = document.querySelector('.all-columns');
  if (elem.style.display === "none") {
    elem.style.display = "flex";
  } else {
    elem.style.display = "none";
  }
}
.grid-container {
  display: grid;
  grid-template-columns: auto auto auto;
  width: 400px;
}

.row {
  display: contents;
}

.all-columns {
  grid-column: 1/-1;
  display: flex;
  flex-wrap: wrap;
  background: red;
  border: 1px solid black;
}

.column {
  border: 1px solid black;
}

.flex-child {
  width: 180px;
  text-align: center;
  background: blue;
  border: 1px solid black;
}
<div class="grid-container">
  <div class="row">
    <div class="column">Row1 Column1</div>
    <div class="column">Row1 Column2 with large name</div>
    <div class="column">Row1 Column3</div>
  </div>
  <div class="row">
    <div class="all-columns">
      <div class="flex-child">1 flex</div>
      <div class="flex-child">2 flex</div>
      <div class="flex-child">3 flex</div>
      <div class="flex-child">4 flex</div>
      <div class="flex-child">5 flex</div>
    </div>
  </div>
  <div class="row">
    <div class="column">Row3 Column1</div>
    <div class="column">Row4 Column2</div>
    <div class="column">Row1 Column3</div>
  </div>
</div>
<br>
<button onclick="toggle()">Toggle expandable section</button>

如您所见,当可展开部分显示/隐藏时,中间列的大小会发生变化。

可扩展部分的内容是外部的,所以我根本无法修改它。 我已经在 Firefox 和 Chrome 中测试过,结果相同。

如果有人对此行为有解释,我将不胜感激。

谢谢。

【问题讨论】:

  • 由于列是auto.all-columns 的内容最终比网格更宽400px 所以一切都被推动以适应它然后flex-wrap 踢最后包装,如果你'确定400px 只需将其作为固定宽度添加到.all-columns

标签: css grid-layout


【解决方案1】:

width: 0;min-width: 100%; 添加到所有列中,这样它不会有助于定义宽度并且不会影响其他元素:

function toggle() {
  const elem = document.querySelector('.all-columns');
  if (elem.style.display === "none") {
    elem.style.display = "flex";
  } else {
    elem.style.display = "none";
  }
}
.grid-container {
  display: grid;
  grid-template-columns: auto auto auto;
  width: 400px;
}

.row {
  display: contents;
}

.all-columns {
  grid-column: 1/-1;
  width: 0;
  min-width: 100%;
  display: flex;
  flex-wrap: wrap;
  background: red;
  border: 1px solid black;
}

.column {
  border: 1px solid black;
}

.flex-child {
  width: 180px;
  text-align: center;
  background: blue;
  border: 1px solid black;
}
<div class="grid-container">
  <div class="row">
    <div class="column">Row1 Column1</div>
    <div class="column">Row1 Column2 with large name</div>
    <div class="column">Row1 Column3</div>
  </div>
  <div class="row">
    <div class="all-columns">
      <div class="flex-child">1 flex</div>
      <div class="flex-child">2 flex</div>
      <div class="flex-child">3 flex</div>
      <div class="flex-child">4 flex</div>
      <div class="flex-child">5 flex</div>
    </div>
  </div>
  <div class="row">
    <div class="column">Row3 Column1</div>
    <div class="column">Row4 Column2</div>
    <div class="column">Row1 Column3</div>
  </div>
</div>
<br>
<button onclick="toggle()">Toggle expandable section</button>

【讨论】:

  • 你知道为什么我们需要添加这些规则吗?我猜 width: 0 使网格忽略子元素以进行一些内部大小计算,并且 min-width 覆盖宽度,因此元素适合整行,但由于 .all-columns 适合所有列(从 1 到 -1),调整大小是网格布局中的预期行为还是浏览器没有正确计算列的大小?
  • @JesusBarcenilla 你有 2 个组件,孩子和网格轨道。通过设置宽度; 0 孩子在计算中被忽略,就像你说的那样,浏览器将定义轨道的宽度(列,行)然后你将孩子设置为所有列(grid-column:1/-1 )。到目前为止,我们在所有列(具有确定大小)内都有一个 width:0 元素位置。最后,我们使用 min-width:100% 强制孩子拥有所有列的宽度(100% 将指的是孩子所在的轨道)。
  • @JesusBarcenilla 我写了一篇关于这个技巧的小文章:dev.to/afif/responsive-text-based-on-image-size-36n9 .. 它适用于很多情况
猜你喜欢
  • 2019-02-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多