如何使 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-basis
为0
(因此所有元素都具有相同的起点),并允许它们增长:
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-grow
、flex-shrink
和flex-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: 1
和flex-direction: column
遇到了完全相同的问题。当其他元素放置在子元素中时,子元素的高度不同。唯一修复它的是设置flex: 1 1 0
。它今天仍然与铬 55.0.2883.87
@JoshCrozier 确认flex: 1
与flex: 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
而不设置width
或right
,或者
将其放入带有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中的孩子数量的情况下获得相同的效果? @Davoringrid-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 具有相同的间距? [复制]
三 div / 两列布局 - 可以使用 Flexbox 吗?