【问题标题】:How to evenly distribute width between flexbox children with nested flexboxes?如何在具有嵌套弹性盒的弹性盒子项之间均匀分布宽度?
【发布时间】:2019-06-12 18:49:50
【问题描述】:

我正在为我正在构建的网站开发一些 css3。我正在尝试创建一个“容器”类,该类使用 flexbox 使其所有子项具有相等的宽度。这可以正常工作,但是当我将一个“容器”和一个普通元素放入另一个“容器”时,这两个孩子的宽度不相等。

我不确定为什么这不起作用,因为它适用于任何不是容器的元素。

HTML:

<div class="container">
  <div class="container">
    <div class="content-box">
      One Sixth
    </div>
    <div class="content-box">
      One Sixth
    </div>
    <div class="content-box">
      One Sixth
    </div>
  </div>
  <div class="content-box">
    One half
  </div>
</div>

CSS:

.container {
    display: flex;
    align-items: flex-start;
}

.container > * {
    flex-basis: 100%;
    min-width: 0;
}

.container > :not(:first-child) {
    margin-left: 2%;
}

Codepen 示例:https://codepen.io/NetworkOverflow/pen/XLbdqa

【问题讨论】:

    标签: html css flexbox


    【解决方案1】:

    问题是当您将容器放入容器中时,它会添加边距,因此您会看到右侧空间加倍。

    我会将您的容器设置为justify-content: space-between;,它将内容元素推到外部边缘。我使用flex:1 而不是flex-basis 来告诉浏览器每个元素应该占用相同数量的空间。

    你的 CSS 变成:

    .container {
        display: flex;
        align-items: flex-start;
        justify-content: space-between;
    }
    
    .container > * {
        flex: 1;
        margin-left: 2%;
        min-width: 0;
    }
    
    .container > *:first-child {
        margin-left:0;
    }
    
    /* not needed
    .container > :not(:first-child) {
        margin-left: 2%;
    }
    */
    

    更新:

    根据使用情况,有时添加“调整大小”类以根据项目数量强制flex-basis 会很有帮助。这是一个codepen 示例。

    .third {
      flex-basis: calc(33.3333% - 2%);
    }
    .half {
      flex-basis: calc(33.3333% - 2%);
    }
    

    【讨论】:

    • 不过,这似乎并没有真正解决问题。一个包含两个内容框的容器与一个包含一个容器和一个内容框的容器之间仍然存在差异。看到这个:codepen.io/NetworkOverflow/pen/NZqRgL
    • 你可以给其中一些添加一个类吗?有时它有助于告诉浏览器你想要多大的东西。这是更新的pen
    【解决方案2】:

    您为将所有元素设置为 flex-basis: 100% 付出了代价。

    因为您要告诉所有元素(无论它们可能有多少兄弟姐妹)占据容器的整个宽度,所以您迫使 flex-shrink 计算容纳所有元素所需的空间。

    这涉及到一个相对复杂的 flexbox 算法,当您考虑填充和 box-sizing: border-box 时,它会变得更加复杂,这两者都存在于您的代码中。

    算法解释在这里:How does flex-shrink factor in padding and border-box?

    最快和最简单的解决方案是指定容器的实际宽度。

    对于说明问题的行(使用容器,以及容器中的容器),不要将它们设置为flex-basis: 100%,这会触发flex-shrink,而是将它们设置为flex-basis: 50%。现在flex-shrink 过程被避免了,你得到了你想要的。

    我将此添加到您的代码中:

    .container > .demo50 {
      flex-basis: 50%;
    }
    

    revised demo

    div.content {
      float: left;
      width: 100%;
      height: 100%;
      background-color: var(--background-color2);
      padding: 2% 10%;
    }
    
    div.banner {
      background-color: var(--scheme-color2);
      box-shadow: 0px 0px 50px 10px rgba(23, 196, 167, 0.5);
      padding: 1rem;
      text-align: center;
      margin-bottom: 2em;
    }
    
    .content-box {
      background-color: var(--background-color1);
      box-shadow: 0px 0px 10px 5px rgba(84, 84, 84, 1);
      padding: 1rem;
      overflow-wrap: break-word;
      margin-bottom: 2em;
    }
    
    .container {
      display: flex;
      align-items: flex-start;
    }
    
    .container > * {
      flex-basis: 100%;
      min-width: 0;
    }
    
    .container > :not(:first-child) {
      margin-left: 2%;
    }
    
    .two-thirds {
      flex-basis: calc(100% / 3 * 2);
    }
    
    .container > .demo50 {
      flex-basis: 50%;
    }
    
    * {
      margin: 0;
      padding: 0;
      box-sizing: border-box;
    }
    
    :root {
      --background-color1: #707070;
      --background-color2: #424242;
      --background-color3: #afafaf;
      --scheme-color1: #20f9d5;
      --scheme-color2: #17c4a7;
      --scheme-color3: #89e5d6;
      --text-color: #e3edeb;
    }
    
    body {
      font-family: "Open Sans", sans-serif;
      color: var(--text-color);
    }
    <div class="content">
      <div class="container">
        <div class="banner">
          <h1>Example</h1>
        </div>
      </div>
      <div class="container">
        <div class="content-box">
          <p>Using 'flex-basis: 100%' seems to work perfectly well for evenly sizing and spacing elements in a row. However, when you put a .container inside a .container and attempt to do something like you see two rows below, the .container element and the
            element that follows do not space themselves at half and half width.</p>
        </div>
      </div>
      <div class="container">
        <div class="content-box">
          One Half
        </div>
        <div class="content-box">
          One Half
        </div>
      </div>
      <div class="container">
        <div class="container demo50">
          <div class="content-box">
            One Sixth
          </div>
          <div class="content-box">
            One Sixth
          </div>
          <div class="content-box">
            One Sixth
          </div>
        </div>
        <div class="content-box demo50">
          One half
        </div>
      </div>
      <div class="container">
        <div class="content-box">
          One Third
        </div>
        <div class="content-box">
          Two Thirds
        </div>
        <div class="content-box">
          Three Thirds
        </div>
      </div>
      <div class="container">
        <div class="content-box two-thirds">
          Two Thirds
        </div>
        <div class="content-box">
          One Third
        </div>
      </div>
      <div class="container">
        <div class="content-box">
          One Third
        </div>
        <div class="content-box two-thirds">
          Two Thirds
        </div>
      </div>
    </div>

    【讨论】:

    • 但这并不能解决问题。我希望容器类能够容纳任意数量的元素并将它们平均分配。如果我这样写,我将不得不为包含 2 个元素的行、包含 3 个元素的行等编写单独的 css。我不知道每行中有多少个元素,所以我需要能够在不提供特定宽度的情况下完成此操作。
    • 我明白了。但随后您必须与flex-shrink 抗衡(请参阅我发布的链接)。就像我说的,这种方法是有代价的。
    • 当然,您可以禁用flex-shrink。然后你的问题就解决了。但是出现了一个新问题:元素尊重其定义的宽度:codepen.io/anon/pen/RzPKmG
    猜你喜欢
    • 2015-08-25
    • 2014-11-27
    • 2015-11-18
    • 1970-01-01
    • 2011-05-26
    • 1970-01-01
    • 2015-09-09
    • 2014-06-19
    • 2018-12-10
    相关资源
    最近更新 更多