flex-wrap 导致儿童身高增加一倍

KJ *_*lke 5 css flexbox css-grid

正如标题所示,当在父 div 上启用 flex-wrap:wrap 时,子网格容器的高度会加倍。我希望它不要这样做,但更重要的是,为什么会发生这种情况?

我假设如果/当添加更多网格项以使其包裹时,网格的高度将简单地调整......但我显然错过了一些东西。

我希望它看起来像flex-wrap:nowrap启用时一样,但我也希望它能够换行......

在 Codepen 上查看

.container {
  width: 88%;
  margin: 2rem auto;
  max-width: 1400px;
}

.cno-event-search-filters__container {
  display: flex;
  flex-direction: column;
  align-items: stretch;
}

.cno-event-search-filters__filter-container {
  border: 2px solid black;
  display: grid;
  grid-template-columns: repeat(auto-fit, max(240px));
  gap: 1rem;
}
Run Code Online (Sandbox Code Playgroud)
<div class="container">
  <div class="cno-event-search-filters">
    <div class="cno-event-search-filters__container">
      <h4 class="cno-event-search-filters__title">Event Types</h4>
      <div class="cno-event-search-filters__filter-container">
        <div class="cno-event-search-filters__filter">
          <input type="checkbox" id="Culture">
          <label for="Culture">Culture</label>
        </div>
        <div class="cno-event-search-filters__filter">
          <input type="checkbox" id="Entertainment">
          <label for="Entertainment">Entertainment</label>
        </div>
        <div class="cno-event-search-filters__filter">
          <input type="checkbox" id="Sports">
          <label for="Sports">Sports</label>
        </div>
      </div>
    </div>
    <div class="cno-event-search-filters__container">
      <h4 class="cno-event-search-filters__title">Locations</h4>
      <div class="cno-event-search-filters__filter-container">
        <div class="cno-event-search-filters__filter">
          <input type="checkbox" id="Ampitheatre">
          <label for="Ampitheatre">Ampitheatre</label>
        </div>
        <div class="cno-event-search-filters__filter">
          <input type="checkbox" id="Capitol Lawn">
          <label for="Capitol Lawn">Capitol Lawn</label>
        </div>
        <div class="cno-event-search-filters__filter">
          <input type="checkbox" id="Capitol Museum">
          <label for="Capitol Museum">Capitol Museum</label>
        </div>
        <div class="cno-event-search-filters__filter">
          <input type="checkbox" id="Chapel">
          <label for="Chapel">Chapel</label>
        </div>
        <div class="cno-event-search-filters__filter">
          <input type="checkbox" id="Choctaw Village">
          <label for="Choctaw Village">Choctaw Village</label>
        </div>
        <div class="cno-event-search-filters__filter">
          <input type="checkbox" id="Playground">
          <label for="Playground">Playground</label>
        </div>
        <div class="cno-event-search-filters__filter">
          <input type="checkbox" id="Red Warrior Park">
          <label for="Red Warrior Park">Red Warrior Park</label>
        </div>
        <div class="cno-event-search-filters__filter">
          <input type="checkbox" id="Stickball Field">
          <label for="Stickball Field">Stickball Field</label>
        </div>
      </div>
    </div>
  </div>
</div>
Run Code Online (Sandbox Code Playgroud)

Tem*_*fif 4

这个怪癖有点棘手,所以我将尝试使用简单的词语来解释发生了什么。

\n

首先,在定义时,flex-wrap您可以控制布局的性质,如规范中详述:

\n
\n

flex-wrap 属性控制flex容器是单行还是多行,

\n

nowrap

\n

Flex 容器是单行的

\n

wrap

\n

Flex 容器是多行的

\n
\n

即使在您的情况下,添加时您也只有一行flex-wrap: wrap仍被视为“多行”,并且算法与“单行”有点不同。

\n

差异与每行尺寸的计算方式有关,这也会影响项目的尺寸。这里是关于宽度,因为我们有列方向。

\n

当您有“单行”布局 ( flex-wrap: nowrap) 时,计算行的宽度很容易。从规格来看

\n
\n

如果 Flex 容器是单线且具有确定的交叉尺寸,则 Flex 线的交叉尺寸为 Flex 容器\xe2\x80\x99s 内交叉尺寸。

\n
\n

您的容器是一个块元素,因此它的全宽(确定的交叉尺寸)。该宽度用作线条的大小,并且内部元素将拉伸以适合该大小。这是合乎逻辑的行为,但我们可以改变它,我们删除那个拉伸部分。

\n

\r\n
\r\n
.container {\n  width: 88%;\n  margin: 2rem auto;\n  max-width: 1400px;\n}\n\n.cno-event-search-filters__container {\n  display: flex;\n  flex-direction: column;\n  align-items: start;\n}\n\n.cno-event-search-filters__filter-container {\n  border: 2px solid black;\n  display: grid;\n  grid-template-columns: repeat(auto-fit, max(240px));\n  gap: 1rem;\n}
Run Code Online (Sandbox Code Playgroud)\r\n
<div class="container">\n  <div class="cno-event-search-filters">\n    <div class="cno-event-search-filters__container">\n      <h4 class="cno-event-search-filters__title">Event Types</h4>\n      <div class="cno-event-search-filters__filter-container">\n        <div class="cno-event-search-filters__filter">\n          <input type="checkbox" id="Culture">\n          <label for="Culture">Culture</label>\n        </div>\n        <div class="cno-event-search-filters__filter">\n          <input type="checkbox" id="Entertainment">\n          <label for="Entertainment">Entertainment</label>\n        </div>\n        <div class="cno-event-search-filters__filter">\n          <input type="checkbox" id="Sports">\n          <label for="Sports">Sports</label>\n        </div>\n      </div>\n    </div>\n    <div class="cno-event-search-filters__container">\n      <h4 class="cno-event-search-filters__title">Locations</h4>\n      <div class="cno-event-search-filters__filter-container">\n        <div class="cno-event-search-filters__filter">\n          <input type="checkbox" id="Ampitheatre">\n          <label for="Ampitheatre">Ampitheatre</label>\n        </div>\n        <div class="cno-event-search-filters__filter">\n          <input type="checkbox" id="Capitol Lawn">\n          <label for="Capitol Lawn">Capitol Lawn</label>\n        </div>\n        <div class="cno-event-search-filters__filter">\n          <input type="checkbox" id="Capitol Museum">\n          <label for="Capitol Museum">Capitol Museum</label>\n        </div>\n        <div class="cno-event-search-filters__filter">\n          <input type="checkbox" id="Chapel">\n          <label for="Chapel">Chapel</label>\n        </div>\n        <div class="cno-event-search-filters__filter">\n          <input type="checkbox" id="Choctaw Village">\n          <label for="Choctaw Village">Choctaw Village</label>\n        </div>\n        <div class="cno-event-search-filters__filter">\n          <input type="checkbox" id="Playground">\n          <label for="Playground">Playground</label>\n        </div>\n        <div class="cno-event-search-filters__filter">\n          <input type="checkbox" id="Red Warrior Park">\n          <label for="Red Warrior Park">Red Warrior Park</label>\n        </div>\n        <div class="cno-event-search-filters__filter">\n          <input type="checkbox" id="Stickball Field">\n          <label for="Stickball Field">Stickball Field</label>\n        </div>\n      </div>\n    </div>\n  </div>\n</div>
Run Code Online (Sandbox Code Playgroud)\r\n
\r\n
\r\n

\n

请注意,网格内只有一列,240px因为您的元素不再在整行内拉伸,并且 CSS 网格算法将按照其算法仅创建一列

\n
\n

当自动填充作为重复次数给出时,如果网格容器在相关轴上具有确定的尺寸或最大尺寸,...否则,如果网格容器在相关轴上具有确定的最小尺寸...否则,指定的曲目列表仅重复一次。

\n
\n

你的网格容器没有明确的尺寸,没有最大尺寸,也没有最小尺寸,所以我们陷入最后一个“否则”,我们以一次重复结束。(注意,这里auto-fitauto-fill相同的算法)

\n

现在,当您有“多行”布局时,定义行数和行大小的算法会更加复杂,并且与“单行”布局不同,即使最后只有一行。这是最棘手的部分,您需要知道的是,项目的大小用于确定线条的大小。

\n

换句话说,我们需要首先确定元素大小以找到行的大小,而网格容器没有确定的大小,没有最大大小,也没有最小大小,因此我们陷入了与之前相同的情况,即以一列结束。然后flexbox算法就会识别出一行。然后拉伸对齐将触发以使网格容器全宽,并且auto-fit算法将再次触发以创建更多列,但网格容器的高度不会改变,这就是怪癖。

\n

在查找行数并定义其大小之前,我们首先计算网格容器的宽度/高度。找到行数及其大小后,宽度将更新(由于拉伸对齐),但高度不会改变。列数将会改变,因为我们有空间容纳它们。

\n

如果你做一下比较,你会发现高度等于没有的容器的大小grid-template-columns。添加flex-wrap: wrap并使用开发工具禁用grid-template-columns,高度不会改变。stretch当我们禁用对齐时,该高度也是相同的

\n

在此输入图像描述

\n

这是您的案例的简化版本。调整主容器的大小,并注意内部容器的高度不会改变。

\n

\r\n
\r\n
.box {\n  display: flex;\n  flex-direction: column;\n  flex-wrap: wrap;\n  /* align-items: start; try to disable this to see the difference */\n  border:2px solid #000;\n  overflow: hidden;\n  resize: horizontal;\n}\n.box > div {\n  display: grid;\n  gap: 1rem;\n  grid-template-columns: repeat(auto-fill, 100px);\n  border:2px solid red;\n}
Run Code Online (Sandbox Code Playgroud)\r\n
<div class="box">\n  <div>\n    <div>One</div>\n    <div>Two</div>\n    <div>Three</div>\n  </div>\n</div>
Run Code Online (Sandbox Code Playgroud)\r\n
\r\n
\r\n

\n

要解决此问题并允许更改高度,您需要像算法中那样具有“定义的尺寸、最大尺寸或最小尺寸”。

\n

amin-width: 100%width: 100%可以完成这项工作

\n

\r\n
\r\n
.box {\n  display: flex;\n  flex-direction: column;\n  flex-wrap: wrap;\n  /* align-items: start; try to disable this to see the difference */\n  border:2px solid #000;\n  overflow: hidden;\n  resize: horizontal;\n}\n.box > div {\n  display: grid;\n  width: 100%;\n  gap: 1rem;\n  grid-template-columns: repeat(auto-fill, 100px);\n  border:2px solid red;\n  box-sizing: border-box;\n}
Run Code Online (Sandbox Code Playgroud)\r\n
<div class="box">\n  <div>\n    <div>One</div>\n    <div>Two</div>\n    <div>Three</div>\n  </div>\n</div>
Run Code Online (Sandbox Code Playgroud)\r\n
\r\n
\r\n

\n