【问题标题】:How to make flexbox items the same size?如何使 flexbox 项目的大小相同?
【发布时间】:2015-06-12 17:41:06
【问题描述】:

我想使用一些具有相同宽度的项目的弹性框。我注意到 flexbox 是均匀地分配空间,而不是空间本身。

例如:

.header {
  display: flex;
}

.item {
  flex-grow: 1;
  text-align: center;
  border: 1px solid black;
}
<div class="header">
  <div class="item">asdfasdfasdfasdfasdfasdf</div>
  <div class="item">z</div>
</div>

第一项比第二项大很多。如果我有 3 个项目、4 个项目或 n 个项目,我希望它们都出现在同一行,每个项目的空间量相等。

有什么想法吗?

http://codepen.io/anon/pen/gbJBqM

【问题讨论】:

    标签: css flexbox


    【解决方案1】:

    设置它们,使它们的flex-basis0(因此所有元素都具有相同的起点),并允许它们增长:

    flex: 1 1 0px
    

    您的 IDE 或 linter 可能会提到 the unit of measure 'px' is redundant。如果你忽略它(例如:flex: 1 1 0),IE 将无法正确呈现它。所以px需要支持Internet Explorer,正如@fabb在cmets中提到的那样;

    【讨论】:

    • 需要注意的是flex属性是flex-growflex-shrinkflex-basis属性的简写属性。建议在各个属性上使用速记,因为速记会正确重置任何未指定的组件以适应常见用途。初始值为0 1 auto
    • 请注意,IE11 会忽略无单位的 flex-basis 值:github.com/philipwalton/flexbugs#flexbug-4
    • 我必须添加min-width: 0 来实现使用带有溢出文本的子元素。见css-tricks.com/flexbox-truncated-text
    • 这可以正常工作,除非您没有在 iPhone 上使用 Safari。我想出了相同的解决方法,当我看到该网站在 iPhone 上的外观后,我差点心脏病发作。 p.s.在 Chrome/Firefox 上进行移动预览时看起来还不错,只有 iPhone 的 Safari 不理解 flex-basis: 0。
    • 我只想提一下,应该忽略 Internet Explorer (IE)。这是一个过时的浏览器,例如网景导航器。 IE 被 Microsoft Edge 正式取代。最新版本也可以在 Chromium 上运行(如 Chrome 和其他现代浏览器)。作为 Web 开发人员,我们不应再支持 IE。摆脱这个拐杖是你的责任。 :) 永远不要再谈论 IE。
    【解决方案2】:

    您可以添加flex-basis: 100% 来实现此目的。

    Updated Example

    .header {
      display: flex;
    }
    
    .item {
      flex-basis: 100%;
      text-align: center;
      border: 1px solid black;
    }
    

    对于它的价值,您也可以使用flex: 1 来获得相同的结果。

    flex: 1的简写与flex: 1 1 0相同,相当于:

    .item {
      flex-grow: 1;
      flex-shrink: 1;
      flex-basis: 0;
      text-align: center;
      border: 1px solid black;
    }
    

    【讨论】:

    • 这是不正确的。默认的弹性值是flex: 0 1 auto。这意味着设置flex: 1 将导致flex: 1 1 auto。这行不通。正确答案是 flex: 1 1 0 如上所述亚当
    • @r.sendecky 不,你是不正确的人。正如我在回答中所说,flex: 1 的简写会导致 flex: 1 1 0 not flex: 1 1 auto 就像您声称的那样。看看'flex shorthand' section下的官方W3规范:当flex-basis是“从flex简写中省略时,其指定值为0”,而不是auto。感谢您的随机投票。
    • @r.sendecky - 另外,看看我创建的this example 以可视化变化。
    • 伙计,我不会随机投反对票。我在写之前测试。我确实测试了它。你的答案不起作用 - 就这么简单。不久前flex: 1flex-direction: column 遇到了完全相同的问题。当其他元素放置在子元素中时,子元素的高度不同。唯一修复它的是设置flex: 1 1 0。它今天仍然与铬 55.0.2883.87
    • @JoshCrozier 确认flex: 1flex: 1 1 0 具有相同的行为,而flex: 0 1 auto 具有不同的行为。
    【解决方案3】:

    如果项目的内容使其变大,您需要添加width: 0 以使列相等。

    .item {
      flex: 1 1 0;
      width: 0;
    }
    

    【讨论】:

    • 如果.item 的内容使其变得比.item 自然要宽,这似乎是必要的。
    • 我想你的意思是flex: 1 1 0;,而不是flex-grow: 1 1 0;
    • 仅供参考,链接已损坏
    • 在我的用例中,我包装了动态调整到其父级大小的图表,宽度 0 是它们工作所必需的。我不确定他们如何确定合适的宽度,但 flex 基础肯定不适用于 chrome 72(2019 年 1 月发布)。
    • 这应该是公认的答案!
    【解决方案4】:

    Adam (flex: 1 1 0) 接受的答案非常适用于宽度固定或由祖先确定的 flexbox 容器。您希望孩子适合容器的情况。

    但是,您可能会遇到这样的情况,即您希望容器适合子级,而子级的大小与最大的子级相同。您可以通过以下任一方式使 flexbox 容器适合其子容器:

    • 设置position: absolute而不设置widthright,或者
    • 将其放入带有display: inline-block 的包装器中

    对于这样的 flexbox 容器,接受的答案确实工作,孩子的大小不相等。我认为这是 flexbox 的限制,因为它在 Chrome、Firefox 和 Safari 中的行为相同。

    解决方案是使用网格而不是弹性框。

    演示:https://codepen.io/brettdonald/pen/oRpORG

    <p>Normal scenario — flexbox where the children adjust to fit the container — and the children are made equal size by setting {flex: 1 1 0}</p>
    
    <div id="div0">
      <div>
        Flexbox
      </div>
      <div>
        Width determined by viewport
      </div>
      <div>
        All child elements are equal size with {flex: 1 1 0}
      </div>
    </div>
    
    <p>Now we want to have the container fit the children, but still have the children all equally sized, based on the largest child. We can see that {flex: 1 1 0} has no effect.</p>
    
    <div class="wrap-inline-block">
    <div id="div1">
      <div>
        Flexbox
      </div>
      <div>
        Inside inline-block
      </div>
      <div>
        We want all children to be the size of this text
      </div>
    </div>
    </div>
    
    <div id="div2">
      <div>
        Flexbox
      </div>
      <div>
        Absolutely positioned
      </div>
      <div>
        We want all children to be the size of this text
      </div>
    </div>
    
    <br><br><br><br><br><br>
    <p>So let's try a grid instead. Aha! That's what we want!</p>
    
    <div class="wrap-inline-block">
    <div id="div3">
      <div>
        Grid
      </div>
      <div>
        Inside inline-block
      </div>
      <div>
        We want all children to be the size of this text
      </div>
    </div>
    </div>
    
    <div id="div4">
      <div>
        Grid
      </div>
      <div>
        Absolutely positioned
      </div>
      <div>
        We want all children to be the size of this text
      </div>
    </div>
    
    body {
      margin: 1em;
    }
    
    .wrap-inline-block {
      display: inline-block;
    }
    
    #div0, #div1, #div2, #div3, #div4 {
      border: 1px solid #888;
      padding: 0.5em;
      text-align: center;
      white-space: nowrap;
    }
    
    #div2, #div4 {
      position: absolute;
      left: 1em;
    }
    
    #div0>*, #div1>*, #div2>*, #div3>*, #div4>* {
      margin: 0.5em;
      color: white;
      background-color: navy;
      padding: 0.5em;
    }
    
    #div0, #div1, #div2 {
      display: flex;
    }
    
    #div0>*, #div1>*, #div2>* {
      flex: 1 1 0;
    }
    
    #div0 {
      margin-bottom: 1em;
    }
    
    #div2 {
      top: 15.5em;
    }
    
    #div3, #div4 {
      display: grid;
      grid-template-columns: repeat(3,1fr);
    }
    
    #div4 {
      top: 28.5em;
    }
    

    【讨论】:

    • 有没有办法在不硬编码css中的孩子数量的情况下获得相同的效果?
    • @Davorin grid-template-columns: repeat(auto-fill, minmax(100px, auto)); 更多详情css-tricks.com/…
    【解决方案5】:

    我不是 flex 方面的专家,但我通过将我正在处理的两个项目的基础设置为 50% 来实现这一目标。增长到 1,缩小到 0。

    内联样式:flex: '1 0 50%',

    【讨论】:

      【解决方案6】:

      这些答案都没有解决我的问题,即当我的临时 flexbox 表缩小到太小的宽度时,项目的宽度不一样。

      对我来说,解决方案就是将overflow: hidden; 放在flex-grow: 1; 单元格上。

      【讨论】:

      • 或者,当浏览器窗口低于某个宽度时,您可以使用@Josh_Crozier 的答案并有条件地设置flex-wrap: wrap;。这将导致项目包裹并占据父宽度的 100%。
      【解决方案7】:

      这些解决方案都不适合我,所以我想我应该分享一下。

      .header {
        display: flex;
      }
      
      .item {
        width: 100%;
      }
      
      
      /* Demo styles, for aesthetics. */
      
      .demo {
        margin: 3rem;
      }
      
      .demo .item {
        text-align: center;
        padding: 3rem;
        background-color: #eee;
        margin: 0 1.5rem;
      }
      <div class="demo">
        <div class="header">
          <div class="item">
            1
          </div>
          <div class="item">
            2
          </div>
          <div class="item">
            3
          </div>
        </div>
      </div>
      
      <div class="demo">
        <div class="header">
          <div class="item">
            1
          </div>
          <div class="item">
            2
          </div>
        </div>
      </div>
      
      <div class="demo">
        <div class="header">
          <div class="item">
            1
          </div>
          <div class="item">
            2
          </div>
          <div class="item">
            3
          </div>
          <div class="item">
            4
          </div>
          <div class="item">
            5
          </div>
        </div>
      </div>

      【讨论】:

      • 一些解释会很棒。代码转储不是一个理想的答案。请参阅How to Answer
      【解决方案8】:

      即使您包装项目(例如网格)也可以使用,但不是那么简单,您应该在媒体查询中显示它将包装的位置))

      例子:

      .flex-item{
           flex: 0 0 calc(25% - (45px / 4 ))
      }
      

      像这样工作:

      $n: 4; // number of columns
      $gap: 15px; // margin pixels
      
      .flex-parent{
          display: flex;
          gap: $gap;
      }
      .flex-item{
           flex: 0 0 calc(100% / $n - (($n - 1) * $gap / $n ) );
      }
      

      【讨论】:

      • 4 cols) flex: 0 0 calc(25% - (30px / 4) ); 3 cols) flex: 0 0 calc(33.3% - (20px / 3) ); 2 cols) flex: 0 0 calc(50% - (10px / 2) );
      猜你喜欢
      • 2020-08-25
      • 1970-01-01
      • 1970-01-01
      • 2019-05-06
      • 2016-05-11
      • 1970-01-01
      • 2020-03-22
      • 1970-01-01
      相关资源
      最近更新 更多