ChatGPT解决这个技术问题 Extra ChatGPT

flex-basis 和 width 有什么区别?

有关于此的问题和文章,但据我所知,没有任何结论。我能找到的最好的总结是

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)会很好。

最好的article解释弹性基础,弹性增长和收缩

M
Michael Benjamin

考虑弹性方向

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

flex-directionrow 时,flex-basis 控制宽度。

但当 flex-directioncolumn 时,flex-basis 控制高度。

主要区别

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

flex-basis 仅适用于弹性项目。 Flex 容器(也不是 flex 项)将忽略 flex-basis 但可以使用宽度和高度。

flex-basis 仅适用于主轴。例如,如果您在 flex-direction: 列中,则需要 width 属性来水平调整弹性项目的大小。

flex-basis 对绝对定位的弹性项目没有影响。宽度和高度属性是必要的。绝对定位的弹性项目不参与弹性布局。

通过使用 flex 属性,三个属性——flex-grow、flex-shrink 和 flex-basis——可以巧妙地组合成一个声明。使用宽度,相同的规则将需要多行代码。

浏览器行为

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

从规范:

7.2.3. flex-basis 属性 对于除 auto 和 content 之外的所有值,flex-basis 的解析方式与水平书写模式中的宽度相同。

autocontent 的影响可能很小或根本没有影响。更多来自规范:

auto 当在弹性项目上指定时, auto 关键字检索主要尺寸属性的值作为使用的弹性基础。如果该值本身是自动的,那么使用的值就是内容。 content 表示自动调整大小,基于弹性项目的内容。注意:此值在弹性盒布局的初始版本中不存在,因此一些较旧的实现将不支持它。将 auto 与 auto 的主要尺寸(宽度或高度)一起使用可以达到等效的效果。

因此,根据规范,flex-basiswidth 解析相同,除非 flex-basisautocontent。在这种情况下,flex-basis 可能会使用内容宽度(据推测,width 属性也会使用)。

弹性收缩系数

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

flex-direction: row - 弹性项目将水平对齐

justify-content: flex-start - 弹性项目将堆叠在主轴线的开头

align-items: 拉伸 - 弹性项目将扩展以覆盖容器的交叉大小

flex-wrap: nowrap - 弹性项目被迫留在一行

flex-shrink: 1 - 允许收缩的弹性项目

注意最后的设置。

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

例如,flex-basis: 100pxwidth: 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,使用 floatinline-block 也会呈现相同的有缺陷的输出 (jsfiddle demo)。

影响 IE 10 和 11 的错误:

忽略具有无单位 flex-basis 值的 flex 速记声明

flex-basis 不考虑 box-sizing: border-box

flex-basis 不支持 calc()

使用 flex 速记时忽略基于 flex 的重要性


min-width:100px; 怎么样?可以选择禁用收缩吗?
@Mori,是的,flex-shrink 停在 min-width。等效的 flex 规则是 flex: 1 0 100px
flex: 1 0 100px 导致相同的结果,但我不确定您所说的“等效”是什么意思。
我的意思是,为什么我们不应该认为它等于 flex: 0 0 100px
@Mori,因为那样它就等于宽度。它需要 flex-grow: 1 组件来允许元素从 flex-basis 设置的最小宽度开始增长。
P
Paulie_D

除了 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-growflex-shrinkflex-basis(或简写 flex :fg fs fb)...可能会产生一些有趣的结果。


我发现通常在 flex 上下文中,它们 flex-basiswidth / height 都设置元素的初始/起始大小。例如 flex-basis: 200px 基本上与 flex-basis: auto; width: 200px; 的工作方式相同。看起来当 flex-basis 未设置为 auto 时,它只是覆盖了 width / height 值。我看到的唯一区别是处理内容溢出的方式。
p
philmcole

如果我们忽略灵活大小方面 (flex-grow: 0; flex-shrink: 0;),似乎没有人提到 flex-basiswidth(或 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-heightmin-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; }

Lorem ipsum
Lorem ipsum
Lorem ipsum


这是我一直在寻找的答案。谢谢你。
N
Niet the Dark Absol

可能最重要的一点要补充:

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

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


在主流浏览器中,唯一不支持 flex 属性的是 IE < 10. caniuse.com/#search=flex
@Michael_B 当然,也许只有我一个人,但我也必须支持移动浏览器,包括 Nintendo 3DS 浏览器,它绝对不支持 flex
P
Pacerier

如果你在包装,它会有所不同。

比如说,您将一个孩子设置为 width:0 并希望它能够换行,这不会发生。但是使用 flex-basis:0 它会换行。 (前提是溢出没有隐藏)


Y
Yilmaz

如果您设置了一个 div 的 min-width:600px,如果窗口大小低于 600 像素,您将看到一个水平滚动条,这不是一个好的 ux 设计。

如果您设置它的 flex-basis:600px,如果窗口大小低于 600 像素,则该框将缩小,您将看不到水平条。

请注意,flex-basis 仅适用于弹性项目。