有关于此的问题和文章,但据我所知,没有任何结论。我能找到的最好的总结是
flex-basis 允许您在计算其他任何内容之前指定元素的初始/起始大小。它可以是百分比或绝对值。
...这本身并没有说明带有 flex-basis 集的元素的行为。以我目前对 flexbox 的了解,我不明白为什么它也不能描述宽度。
我想知道在实践中 flex-basis 与 width 有何不同:
如果我用 flex-basis 替换宽度(反之亦然),视觉上会发生什么变化?
如果我将两者都设置为不同的值会发生什么?如果它们具有相同的值会发生什么?
是否有一些特殊情况,使用 width 或 flex-basis 与使用另一个有显着差异?
当与其他 flexbox 样式(例如 flex-wrap、flex-grow 和 flex-shrink)结合使用时,width 和 flex-basis 有何不同?
还有其他显着差异吗?
编辑/澄清:这个问题在 What exactly flex-basis property sets? 中以不同的格式提出,但我觉得对 flex-basis 和 的区别进行了更直接的比较或总结>width(或height)会很好。
考虑弹性方向
阅读您的问题时首先想到的是 flex-basis
并不总是适用于 width
。
当 flex-direction
为 row
时,flex-basis
控制宽度。
但当 flex-direction
为 column
时,flex-basis
控制高度。
主要区别
以下是 flex-basis
和 width
/ height
之间的一些重要区别:
flex-basis 仅适用于弹性项目。 Flex 容器(也不是 flex 项)将忽略 flex-basis 但可以使用宽度和高度。
flex-basis 仅适用于主轴。例如,如果您在 flex-direction: 列中,则需要 width 属性来水平调整弹性项目的大小。
flex-basis 对绝对定位的弹性项目没有影响。宽度和高度属性是必要的。绝对定位的弹性项目不参与弹性布局。
通过使用 flex 属性,三个属性——flex-grow、flex-shrink 和 flex-basis——可以巧妙地组合成一个声明。使用宽度,相同的规则将需要多行代码。
浏览器行为
就它们的呈现方式而言,flex-basis
和 width
之间应该没有区别,除非 flex-basis
是 auto
或 content
。
从规范:
7.2.3. flex-basis 属性 对于除 auto 和 content 之外的所有值,flex-basis 的解析方式与水平书写模式中的宽度相同。
但 auto
或 content
的影响可能很小或根本没有影响。更多来自规范:
auto 当在弹性项目上指定时, auto 关键字检索主要尺寸属性的值作为使用的弹性基础。如果该值本身是自动的,那么使用的值就是内容。 content 表示自动调整大小,基于弹性项目的内容。注意:此值在弹性盒布局的初始版本中不存在,因此一些较旧的实现将不支持它。将 auto 与 auto 的主要尺寸(宽度或高度)一起使用可以达到等效的效果。
因此,根据规范,flex-basis
和 width
解析相同,除非 flex-basis
是 auto
或 content
。在这种情况下,flex-basis
可能会使用内容宽度(据推测,width
属性也会使用)。
弹性收缩系数
记住弹性容器的初始设置很重要。其中一些设置包括:
flex-direction: row - 弹性项目将水平对齐
justify-content: flex-start - 弹性项目将堆叠在主轴线的开头
align-items: 拉伸 - 弹性项目将扩展以覆盖容器的交叉大小
flex-wrap: nowrap - 弹性项目被迫留在一行
flex-shrink: 1 - 允许收缩的弹性项目
注意最后的设置。
因为弹性项目默认允许收缩(这可以防止它们溢出容器),所以指定的 flex-basis
/ width
/ height
可能会被覆盖。
例如,flex-basis: 100px
或 width: 100px
加上 flex-shrink: 1
不一定是 100 像素。
要渲染指定的宽度——并保持它固定——你需要禁用收缩:
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-basis 在嵌套的 flex 容器中被忽略。宽度有效。
使用 flex-basis
时,容器会忽略其子级的大小,并且子级会溢出容器。但是使用 width
属性,容器尊重其子级的大小并相应地扩展。
参考:
Chrome不会根据孩子的内容展开flex parent
使用 flex-basis 时 Flex 项目溢出
width 和 flex-basis 的区别
在调整嵌套 flex 容器的大小时,将忽略 Flex-basis。
flex-basis:100px 的作用与 width:100px+flex-basis:auto 不同
例子:
https://jsfiddle.net/t419zhra/(来源:@Dremora)
https://codepen.io/anon/pen/NVxaoy(来源@Daniel)
https://jsfiddle.net/voc9grx6/(来源:Chromium Bugs)
https://jsfiddle.net/qjpat9zk/(来源:Chromium Bugs)
使用 flex-basis 和 white-space: nowrap 溢出 inline-flex 容器的弹性项目。宽度有效。
似乎设置为 inline-flex
的 flex 容器在使用 white-space: nowrap
呈现同级时无法识别子级上的 flex-basis
(尽管它可能只是宽度未定义的项目)。容器不会扩展以容纳物品。
但是,当使用 width
属性而不是 flex-basis
时,容器会考虑其子级的大小并相应地展开。这在 IE11 和 Edge 中不是问题。
参考:
内联弹性容器宽度没有增长
内联 flex 容器(显示:inline-flex)正在扩展父容器的全宽
例子:
https://jsfiddle.net/p18h0jxt/1/(来自上面的第一篇文章)
flex-basis(和 flex-grow)不适用于表格元素
参考:
为什么 flex-box 可以与 div 一起使用,但不能与 table 一起使用?
为什么 flex-grow: 1 不适用于 Safari 中的表格? (和边缘)
当祖父容器是收缩以适应元素时, flex-basis 在 Chrome 和 Firefox 中失败。该设置在 Edge 中运行良好。
绝对定位的容器没有扩展宽度以适应 flexbox 内容
就像上面链接中的示例一样,涉及 position: absolute
,使用 float
和 inline-block
也会呈现相同的有缺陷的输出 (jsfiddle demo)。
影响 IE 10 和 11 的错误:
忽略具有无单位 flex-basis 值的 flex 速记声明
flex-basis 不考虑 box-sizing: border-box
flex-basis 不支持 calc()
使用 flex 速记时忽略基于 flex 的重要性
除了 Michael_B 的出色总结之外,值得重复一下:
flex-basis 允许您在计算其他任何内容之前指定元素的初始/起始大小。它可以是百分比或绝对值。
这里重要的部分是初始的。
就其本身而言,这确实会解析为宽度/高度,直到其他 flex 增长/收缩属性发挥作用。
所以。一个孩子
.child {
flex-basis:25%;
flex-grow:1;
}
最初将是 25% 宽,但随后会立即尽可能多地扩展,直到考虑到其他元素。如果没有..它将是 100% 宽/高。
快速演示:
.flex { 宽度:80%;保证金:1em自动;高度:25px;显示:弯曲;背景:rebeccapurple; } .child { 弹性基础:自动; /* 默认 */ 背景:李子; } .value { 弹性基础:25%; } .grow { 弹性增长:1; }
尝试使用 flex-grow
、flex-shrink
和 flex-basis
(或简写 flex :fg fs fb
)...可能会产生一些有趣的结果。
flex-basis
和 width / height
都设置元素的初始/起始大小。例如 flex-basis: 200px
基本上与 flex-basis: auto; width: 200px;
的工作方式相同。看起来当 flex-basis
未设置为 auto
时,它只是覆盖了 width / height
值。我看到的唯一区别是处理内容溢出的方式。
如果我们忽略灵活大小方面 (flex-grow: 0; flex-shrink: 0;
),似乎没有人提到 flex-basis
和 width
(或 height
,取决于当前的书写模式)之间存在一个关键区别。
它源于 Flex 布局中的异常,即 flex 项的自动最小尺寸默认为 min-content
而不是通常的零。换言之,默认的 min-width: auto
计算为 min-content
而不是 0
。
结果是,flex-basis
(默认情况下)由 min-content
绑定。如果您指定一个小于 min-content
的值,例如 flex-basis: 0
,它将计算为 min-content
。这实质上意味着(默认情况下)您不能使框的内容溢出,因为框至少具有内容的大小。
这是与 width
的一个关键区别,它可以任意缩小框的大小(默认情况下),因为 min-width
默认为 0
。如果 width
的值小于 min-content
,内容将溢出框。
规范中提到了此行为,但仅在 7.1.1. Basic Values of flex
末尾错误位置的以下注释中隐含。
默认情况下,弹性项目不会缩小到其最小内容大小(最长单词或固定大小元素的长度)以下。要更改此设置,请设置 min-width 或 min-height 属性。 (参见 § 4.5 弹性项目的自动最小尺寸。)
如评论中所述,设置最小大小会降低界限,并将其设置为零有效地禁用它,使 flex-basis
再次按预期运行。
但也有缺点。首先,主轴没有最小尺寸属性。您必须为当前 flex-direction
使用正确的 min-width
/min-height
或 min-block-size
/min-inline-size
属性。如果您更改了 flex-direction
,则需要再次找到正确的最小尺寸属性。
其次,不能再使用 flex-basis
将空间分配给按比例大小的框,而不是简单地添加到它们的初始大小。有关详细信息,请参阅规范中的 Figure 7。
这是一个最小的例子。设置 min-width: 0
以使 flex-basis
再次按预期运行。
.container { 显示:弹性; } .container div { 背景颜色:浅灰色;边框:1px纯黑色;边距:0 10px; /* 禁用任何灵活的大小 */ flex-grow: 0;弹性收缩:0; /* TOGGLE ME */ /* min-width: 0; */ } .mincontent { 宽度:最小内容; } .smallerflexbasis { 弹性基础:3ex; } .smallerwidth { 宽度:3ex; }
可能最重要的一点要补充:
如果浏览器不支持 flex
怎么办?在这种情况下,width/height
接管并应用它们的值。
在元素上定义 width/height
是一个非常好的主意 - 几乎是必不可少的,即使您对 flex-basis
有一个完全不同的值。请记住通过禁用 display:flex
并查看您得到的结果来进行测试。
flex
。
如果你在包装,它会有所不同。
比如说,您将一个孩子设置为 width:0
并希望它能够换行,这不会发生。但是使用 flex-basis:0
它会换行。 (前提是溢出没有隐藏)
如果您设置了一个 div 的 min-width:600px
,如果窗口大小低于 600 像素,您将看到一个水平滚动条,这不是一个好的 ux 设计。
如果您设置它的 flex-basis:600px
,如果窗口大小低于 600 像素,则该框将缩小,您将看不到水平条。
请注意,flex-basis
仅适用于弹性项目。
min-width:100px;
怎么样?可以选择禁用收缩吗?flex-shrink
停在min-width
。等效的 flex 规则是flex: 1 0 100px
。flex: 1 0 100px
导致相同的结果,但我不确定您所说的“等效”是什么意思。flex: 0 0 100px
?