关于这一点有很多问题和文章,但据我所知,没有任何结论性的东西。我能找到的最好的总结就是

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

...它本身并没有说明多少具有弹性基集合的元素的行为。以我目前对flexbox的了解,我不明白为什么它不能描述宽度。

我想知道在实践中弹性基准与宽度的确切区别:

如果我用flex- base替换width(反之亦然),视觉上会有什么变化? 如果我将两者设置为不同的值会发生什么?如果它们具有相同的值会发生什么? 在某些特殊情况下,使用宽度或弹性基是否会与使用另一种有显著差异? 当与其他flex样式(如flex-wrap、flex-grow和flex-shrink)结合使用时,宽度和弹性基准有何不同? 还有其他显著差异吗?


编辑/澄清:这个问题在《What exactly flex- base属性集?》中以不同的格式提出过。但我觉得更直接地比较或总结弹性基和宽度(或高度)的差异会更好。


考虑flex-direction

读到你的问题时,我首先想到的是,弹性基准并不总是适用于宽度。

当弯曲方向为行时,弯曲基控制宽度。

但当弯曲方向为圆柱时,弯曲基控制高度。


关键的不同点

下面是弹性基准和宽度/高度之间的一些重要区别:

flex-basis applies only to flex items. Flex containers (that aren't also flex items) will ignore flex-basis but can use width and height. flex-basis works only on the main axis. For example, if you're in flex-direction: column, the width property would be needed for sizing flex items horizontally. flex-basis has no effect on absolutely-positioned flex items. width and height properties would be necessary. Absolutely-positioned flex items do not participate in flex layout. By using the flex property, three properties – flex-grow, flex-shrink and flex-basis – can be neatly combined into one declaration. Using width, the same rule would require multiple lines of code.


浏览器的行为

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

来自规范:

7.2.3. 弹性基的性质 对于auto和content以外的所有值,flex-basis的解析方式与水平书写模式中的width相同。

但auto或content的影响可能很小,甚至根本没有影响。更多来自规范:

auto When specified on a flex item, the auto keyword retrieves the value of the main size property as the used flex-basis. If that value is itself auto, then the used value is content. content Indicates automatic sizing, based on the flex item’s content. Note: This value was not present in the initial release of Flexible Box Layout, and thus some older implementations will not support it. The equivalent effect can be achieved by using auto together with a main size (width or height) of auto.

因此,根据规范,flex- base和width的解析是相同的,除非flex- base是auto或content。在这种情况下,flex- base可以使用内容宽度(想必width属性也会使用)。


伸缩系数

记住flex容器的初始设置非常重要。这些设置包括:

弯曲方向:行-弯曲项目将水平对齐 调整-内容:flex-start - flex项目将堆叠在主线上的行开始处 对齐项目:拉伸-伸缩项目将展开以覆盖容器的交叉尺寸 弹性包裹:nowrap -弹性物品被强制保持在一条直线上 弹性收缩:1 -一个弹性项目被允许收缩

注意最后一个设置。

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

例如,flex- base: 100px或width: 100px,加上flex-shrink: 1,不一定是100px。

要渲染指定的宽度-并保持它固定-你需要禁用收缩:

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

OR

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

或,如规范所推荐的:

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

7.2. 的组件 灵活性 鼓励作者使用伸缩简写来控制灵活性 而不是直接用它的速记属性 正确地重置任何未指定的组件以适应公共 用途。


浏览器的bug

有些浏览器在调整嵌套伸缩容器中的伸缩项大小时遇到问题。

在嵌套的flex容器中忽略flex基础。宽度的作品。

使用弹性基准时,容器会忽略子容器的大小,子容器会溢出容器。但是使用width属性,容器会尊重子容器的大小并相应地进行扩展。

引用:

Chrome不会根据孩子的内容扩展伸缩父母 使用Flex -basis时,Flex项溢出 宽度和弹性基之间的区别 在调整嵌套伸缩容器的大小时,会忽略flex - base。 flex- base:100px与width:100px+flex- base: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 overflow内联伸缩容器。宽度的作品。

当呈现带有white-space: nowrap的兄弟容器时,设置为inline-flex的伸缩容器似乎不能识别子容器上的flex- base(尽管它可能只是一个宽度未定义的项)。容器不会扩展以容纳这些物品。

但是当使用width属性而不是基于flex时,容器会尊重其子容器的大小并相应地进行扩展。这在IE11和Edge中不是问题。

引用:

内联伸缩容器宽度不增长 内联伸缩容器(display: Inline -flex)正在展开父容器的全宽度

例子:

https://jsfiddle.net/p18h0jxt/1/(来自上面的第一篇文章)


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

引用:

为什么flex-box可以使用div,而不能使用表? 为什么flex-grow: 1不能在Safari中为表工作?(边缘)


在Chrome和Firefox中,当祖父容器是收缩到适合的元素时,flex-basis会失败。这种设置在Edge中运行良好。

绝对定位的容器没有扩大宽度以适应flexbox内容

就像上面链接中给出的例子一样,涉及position: absolute,使用float和inline-block,也会呈现同样有缺陷的输出(jsfiddle演示)。


影响ie10和ie11的bug:

具有无单位Flex基值的Flex简写声明将被忽略 弹性基准没有考虑box-sizing: border-box flex基础不支持calc() 在使用伸缩简写时,在伸缩基础上忽略了重要性


除了Michael_B的精彩总结外,还有必要重复一下:

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

这里最重要的部分是初始。

它本身会解析为宽度/高度,直到其他伸缩增长/收缩属性开始发挥作用。

所以。一个孩子

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

最初会有25%的宽度,但随后会立即尽可能扩大,直到其他元素被考虑进来。如果没有,它将是100%宽/高。

一个简单的演示:

.flex { 宽度:80%; 保证金:1em自动; 高度:25 px; 显示:flex; 背景:rebeccapurple; } .child { flex-basis:汽车; /*默认*/ 背景:李子; } value { flex-basis: 25%; } .grow { flex-grow: 1; } flex < div class = " " > <div class="child auto">一些内容</div> < / div > flex < div class = " " > <div class="child value">Some Content</div> . < / div > flex < div class = " " > <div class="child grow">一些内容</div> < / div >

试验了弹性增长,弹性收缩和弹性基础 (或flex的简写:fg fs fb)…会导致一些有趣的结果。


可能最重要的一点是:

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

在元素上定义宽度/高度是一个非常好的想法(几乎是必要的),即使你有一个完全不同的弹性基底值。记得通过禁用display:flex来测试,看看你得到了什么。


如果我们忽略了弹性大小方面(flex-grow: 0;flex-shrink: 0;)。

它源于Flex Layout中的一个异常,即Flex项的自动最小大小默认为min-content,而不是通常的0。换句话说,默认的min-width: auto计算min-content而不是0。

结果是,flex- base(默认情况下)由min-content约束。如果指定的值小于min-content,例如flex-basis: 0,它将计算为min-content。这本质上意味着(默认情况下)您不能使框的内容溢出,因为框至少具有内容的大小。

这是与width的关键区别,后者可以将框的大小设置为任意小(默认情况下),因为min-width默认为0。如果width值小于min-content,则内容将溢出框。

规范中提到了这种行为,但只隐式地出现在7.1.1末尾错误的注释中。flex的基本价值。

默认情况下,伸缩项不会缩小到其最小内容大小(最长单词或固定大小元素的长度)以下。要改变这一点,请设置min-width或min-height属性。(参见§ 4.5 Flex物品的自动最小尺寸。)

正如评论中所提到的,设置最小大小会降低界限,而将其设置为零则会有效地禁用界限,从而使弹性基准再次像预期的那样运行。

但也有缺点。首先,主轴没有最小尺寸属性。您必须为当前的flex方向使用正确的min-width/min-height或min-block-size/min-inline-size属性。如果更改了伸缩方向,则需要再次找到正确的最小大小属性。

其次,弹性基准不能再用于按比例大小的盒子分配空间,而不是简单地增加它们的初始大小。有关详细信息,请参见规范中的图7。

下面是一个简单的例子。设置min-width: 0使弹性基准再次表现为预期。

.container { display: flex; } .container div { background-color: lightgrey; border: 1px solid black; margin: 0 10px; /* disable any flexible sizing */ flex-grow: 0; flex-shrink: 0; /* TOGGLE ME */ /* min-width: 0; */ } .mincontent { width: min-content; } .smallerflexbasis { flex-basis: 3ex; } .smallerwidth { width: 3ex; } <div class="container"> <div class="mincontent">Lorem ipsum</div> <div class="smallerflexbasis">Lorem ipsum</div> <div class="smallerwidth">Lorem ipsum</div> </div>


如果你用包装的话,效果就不一样了。

比如说,你设置一个子对象为width:0并期望它自动换行,这是不可能发生的。但是对于弹性基底:0它会自动换行。(如果溢出未隐藏)


如果你设置一个div的最小宽度:600px,如果窗口大小低于600px,你会看到一个水平滚动条,这不是一个好的用户体验设计。

如果你设置它的弹性基准:600px,如果窗口大小低于600px,该方框将缩小,你将看不到一个水平条。

注意,flex- base仅适用于伸缩项。