弹性基和宽度有什么区别?

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

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

...它本身并没有说明flex-basis集合的元素的行为。以我目前对flexbox的了解,我不明白为什么不能描述宽度

我想知道在实践中flex-basis宽度到底有什么不同:

  • 如果我用flex-basis替换宽度(反之亦然),视觉上会有什么变化?
  • 如果我将两者设置为不同的值会发生什么?如果它们具有相同的值会发生什么?
  • 是否存在一些特殊情况,使用宽度flex-basis会与使用另一个有显著差异?
  • 宽度flex-basis与其他flexbox风格(如flex-wrapflex-growflex-shrink)一起使用时,有什么不同?
  • 还有其他显著差异吗?

编辑/澄清:这个问题在弹性基属性集到底是什么?中以不同的格式提出,但我觉得对flex-basis宽度(或高度)的差异进行更直接的比较或总结会更好。

116847 次浏览

考虑flex-direction

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

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

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


关键的不同点

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

  • flex-basis只适用于伸缩项。伸缩容器(也不是伸缩项目)将忽略flex-basis,但可以使用widthheight

  • flex-basis只在主轴上工作。例如,如果您在flex-direction: column中,则需要width属性来水平调整伸缩项的大小。

  • flex-basis对绝对定位的伸缩项没有影响。widthheight属性是必要的。绝对定位的伸缩项目不参与伸缩布局. >

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


浏览器的行为

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

来自规范:

7.2.3。flex-basis属性

对于除autocontent之外的所有值,在水平写入模式下,flex-basis的解析方式与width相同。

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

auto

当在伸缩项上指定时,auto关键字检索值 作为使用的flex-basis的主size属性。如果这个值是 如果它本身是auto,则使用的值是content.

.

content

指示根据伸缩项的内容自动调整大小。

备注:Flexible最初版本中没有此值 框布局,因此一些旧的实现将不支持它。 同样的效果可以通过使用auto和a auto的主要大小(widthheight) .

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


flex-shrink因子

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

  • flex-direction: row - flex项目将水平对齐
  • justify-content: flex-start - flex项将堆叠在主轴上的行开始处
  • align-items: stretch -伸缩项将展开以覆盖容器的交叉大小
  • flex-wrap: nowrap - flex项被强制保持在一行中
  • flex-shrink: 1 -允许收缩伸缩项

注意最后一个设置。

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

例如,flex-basis: 100pxwidth: 100px,加上flex-shrink: 1,不一定是100px。

渲染指定的宽度–并保持固定 mdash;你需要禁用收缩:

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。的组件 < /灵活性强> < / > < / p > 鼓励作者使用flex简写来控制灵活性 而不是直接用它的速记属性 正确重置任何未指定的组件,以适应通用 使用< / > . < / p >


浏览器的bug

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

在嵌套的伸缩容器中忽略flex-basiswidth作品。

当使用flex-basis时,容器忽略子容器的大小,并且子容器溢出。但是使用width属性,容器会尊重子容器的大小并相应地进行扩展。

引用:

例子:


使用flex-basiswhite-space: nowrap溢出inline-flex容器的伸缩项。width作品。

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

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

引用:

例子:


flex-basis(和flex-grow)不能作用于表元素

引用:


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

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


影响ie10和ie11的bug:

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

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

这里重要的部分是最初的

它本身确实会解析为width/height 直到,其他伸缩增长/收缩属性也会起作用。

所以。一个孩子

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

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

一个简单的演示:

.flex {
width: 80%;
margin: 1em auto;
height: 25px;
display: flex;
background: rebeccapurple;
}
.child {
flex-basis: auto;
/* default */
background: plum;
}
.value {
flex-basis: 25%;
}
.grow {
flex-grow: 1;
}
<div class="flex">
<div class="child auto">Some Content</div>
</div>
<div class="flex">
<div class="child value">Some Content</div>
</div>
<div class="flex">
<div class="child grow">Some Content</div>
</div>

实验flex-growflex-shrinkflex-basis (或缩写flex :fg fs fb)…可以导致一些有趣的结果。

可能最重要的一点是:

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

在元素上定义width/height是一个非常好的想法——几乎是必要的——即使你有一个完全不同的flex-basis值。记得通过禁用display:flex进行测试,看看你得到了什么。

如果我们忽略了灵活的大小调整方面(flex-grow: 0; flex-shrink: 0;),似乎没有人会提到flex-basiswidth(或height,取决于当前的写入模式)之间的一个关键区别。

它源于Flex Layout中的一个异常,即Flex项的自动最小大小默认为min-content,而不是通常的0。换句话说,默认的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. flex的基本值末尾的错误位置。

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

正如注释中提到的,设置最小大小会降低边界,而将其设置为零则会有效地禁用边界,使flex-basis再次按预期运行。

但也有缺点。首先,主轴没有最小尺寸属性。你必须为当前的flex-direction使用正确的min-width/min-heightmin-block-size/min-inline-size属性。如果你改变了flex-direction,你将需要再次找到正确的最小大小属性。

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

下面是一个简单的例子。设置min-width: 0使flex-basis再次像预期的那样运行。

.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并期望它自动换行,这是不会发生的。但是对于flex-basis:0,它将自动换行。(如果溢出未隐藏)

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

如果你设置它的flex-basis:600px,如果窗口大小小于600px,这个框将会缩小,你将看不到一个水平条。

注意flex-basis只应用于伸缩项。