flex-basis和width有什么区别?


224

关于此有很多问题和文章,但据我所知,尚无定论。我能找到的最佳总结是

flex-basis允许您在计算其他任何内容之前指定元素的初始/开始大小。它可以是百分比或绝对值。

...这本身并没有过多说明具有flex-basis设置的元素的行为。以我目前对flexbox的了解,我不明白为什么那也不能描述宽度

我想知道flex-basis与实际宽度有何不同:

  • 如果我用flex-basis代替width(反之亦然),那么视觉上会发生什么变化?
  • 如果将两者都设置为不同的值会怎样?如果它们具有相同的值会怎样?
  • 在某些特殊情况下,使用widthflex-basis与使用其他宽度flex-basis会有很大区别吗?
  • 如何宽度柔性基础上与其他Flexbox的风格,如配合使用时,不同的柔性包装柔性成长弹性收缩
  • 还有其他重大区别吗?

编辑/说明:在“究竟什么是flex-basis属性集”中以另一种格式提出了此问题但是我觉得更直接地比较或总结flex-basiswidth(或height)的区别是不错的。


解释弹性基础,弹性共成长和收缩的最佳文章
ZenVentzi

Answers:


339

考虑 flex-direction

阅读问题时首先想到的是,flex-basis这并不总是适用于width

flex-directionrowflex-basis控制宽度。

但是,当flex-directioncolumnflex-basis控制高度。


关键差异

以下是flex-basiswidth/ 之间的一些重要区别height

  • flex-basis仅适用于弹性商品。Flex容器(也不是flex项目)将忽略,flex-basis但可以使用widthheight

  • flex-basis仅在主轴上起作用。例如,如果您在中flex-direction: column,则width需要该属性以水平调整弹性项目的大小。

  • flex-basis对绝对放置的弹性项目没有影响。widthheight属性将是必要的。绝对定位的弹性项目不参与弹性布局

  • 通过使用flex属性,三种属性- flex-growflex-shrinkflex-basis-可整齐地组合成一个声明。使用width,相同的规则将需要多行代码。


浏览器行为

就它们的呈现方式而言,和之间应该没有区别,除非是或。flex-basiswidthflex-basisautocontent

从规格:

7.2.3。该flex-basis物业

对于auto和以外的所有值contentflex-basis其解析方式与width水平写入模式相同。

但是的影响autocontent可能很小或根本没有影响。规格中的更多内容:

auto

在弹性商品上指定时,auto关键字将检索main size属性的值作为used flex-basis。如果该值本身是auto,则使用的值为content

content

指示根据弹性项目的内容自动调整大小。

注意:此值在“ Flexible Box Layout”的初始发行版中不存在,因此某些较早的实现不支持该值。可以通过将auto主尺寸(widthheight)与一起使用来达到同等效果auto

因此,根据规范,flex-basis并进行width相同的解析,除非flex-basisautocontent。在这种情况下,flex-basis可以使用内容宽度(大概也可以使用该width属性的宽度)。


flex-shrink因素

记住Flex容器的初始设置很重要。其中一些设置包括:

  • flex-direction: row -伸缩项目将水平对齐
  • justify-content: flex-start -flex项目将堆叠在主轴线的开始处
  • align-items: stretch -伸缩物品将扩展以覆盖容器的横向尺寸
  • flex-wrap: nowrap -弹性项目被迫停留在一行
  • flex-shrink: 1 -伸缩项目允许收缩

注意最后的设置。

因为默认情况下允许弹性项目收缩(这可以防止它们溢出容器),所以指定的flex-basis/ width/ height可能会被覆盖。

例如, flex-basis: 100pxwidth: 100px与结合使用flex-shrink: 1,不一定是100px。

要渲染指定的宽度(并保持不变),您将需要禁用缩小:

div {
   width: 100px;
   flex-shrink: 0;
}  

要么

div {
  flex-basis: 100px;
  flex-shrink: 0;
}

或者,按照规范的建议:

flex: 0 0 100px;    /* don't grow, don't shrink, stay fixed at 100px */

7.2。灵活性的组成部分

鼓励作者使用flex速记而不是直接使用其速记属性来控制灵活性,因为速记会正确重置任何未指定的组件以适应常见用途


浏览器错误

某些浏览器无法在嵌套的flex容器中调整flex项的大小。

flex-basis在嵌套的flex容器中被忽略。width作品。

使用时flex-basis,容器将忽略其子容器的大小,并且子容器会溢出容器。但是在拥有该width属性的情况下,该容器尊重其子级的大小并相应地扩展。

参考文献:

例子:


使用flex-basiswhite-space: nowrap溢出inline-flex容器显示项目。 width作品。

似乎将设置为的flex容器在与呈现同级时inline-flex无法flex-basis在子对象上识别white-space: nowrap(尽管它可能只是宽度未定义的项目)。容器不会扩展以容纳物品。

但是,当使用该width属性代替时flex-basis,容器会尊重其子级的大小并相应地扩展。在IE11和Edge中这不是问题。

参考文献:

例:


flex-basis(和flex-grow)不适用于表格元素

参考文献:


flex-basis当祖父母容器是缩小至适合元素时,在Chrome和Firefox中失败。该设置在Edge中工作正常。

就像在上面的链接中提供的示例一样,包含position: absolute,使用floatinline-block也将呈现相同的有缺陷的输出(jsfiddle demo)。


影响IE 10和11的错误:


2
怎么min-width:100px;样 可以禁用收缩吗?

1
@Mori是的,flex-shrink在停留min-width。等效的flex规则为flex: 1 0 100px
Michael Benjamin

flex: 1 0 100px会导致相同的结果,但是我不确定您所说的“等效”是什么意思。

我的意思是为什么我们不应该认为它等于flex: 0 0 100px

2
@Mori,因为那样就等于width。它需要flex-grow:1组件,以允许元素从flex-basis设置的最小宽度开始增长。
Michael Benjamin

33

除了Michael_B的出色总结,还值得重复一遍:

flex-basis允许您在计算其他任何内容之前指定元素的初始/开始大小。它可以是百分比或绝对值。

这里的重要部分是初始的

就其本身而言,这确实解析为宽度/高度,直到其他flex增长/收缩属性起作用为止

所以。一个孩子

.child {
 flex-basis:25%;
 flex-grow:1;
}

最初将为25%宽,但随后会立即尽可能地扩大,直到考虑到其他元素为止。如果没有其他元素,则它将为100%宽/高。

快速演示:

与试验flex-growflex-shrink以及flex-basis (或缩写flex :fg fs fb)......可能会导致一些有趣的结果。


我发现,通常在弯曲方面,它们都flex-basiswidth / height设置一个元件的初始/起始尺寸。例如,flex-basis: 200px基本上与相同flex-basis: auto; width: 200px;。看起来,当flex-basis未设置auto为时,它将覆盖width / height值。我看到的唯一区别是内容溢出的处理方式。
Karolis

5

可能最重要的一点是要添加:

如果浏览器不支持flex怎么办?在这种情况下,width/height接管并应用其值。

定义width/height元素是一个非常好的主意-几乎是必不可少的- 即使您对拥有完全不同的值flex-basis。记得通过禁用display:flex并查看得到的内容进行测试。


2
在主要的浏览器中,唯一不支持flex属性的浏览器是IE < 10。caniuse.com/#search=flex
Michael Benjamin

1
@Michael_B当然,也许只是我一个人,但我也必须支持移动浏览器,直到并包括Nintendo 3DS浏览器,但绝对不支持flex
Niet the Dark Absol
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.