如何使 flexbox 项目的大小相同?

Posted

技术标签:

【中文标题】如何使 flexbox 项目的大小相同?【英文标题】:How to make flexbox items the same size? 【发布时间】: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

【问题讨论】:

【参考方案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) );

以上是关于如何使 flexbox 项目的大小相同?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 Flexbox 使一个弹性项目居中对齐并右对齐另一个

如何使用 flexbox 使 flex 容器的子 div 具有相同的间距? [复制]

如何使用 flexbox 使两个项目一个中心一个底部

三 div / 两列布局 - 可以使用 Flexbox 吗?

Flexbox布局:如何在多行中设置每个项目相同的宽度? [复制]

Flexbox 忽略链接上的填充和宽度