flex-basis和width之间有什么区别?

时间:2015-12-18 09:17:23

标签: css css3 flexbox

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

  

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

......这本身并没有说明使用 flex-basis 设置的元素的行为。根据我目前对flexbox的了解,我不明白为什么它也无法描述 width

我想知道 flex-basis 在实践中与 width 有何不同之处:

  • 如果我用 flex-basis 替换 width (反之亦然),会有什么视觉上的变化?
  • 如果我将两者设置为不同的值,会发生什么?如果它们具有相同的值会发生什么?
  • 是否有一些特殊情况,使用 width flex-basis 会对使用另一个产生重大影响?
  • width flex-basis 与其他flexbox样式结合使用时有何不同,例如 flex-wrap flex-grow flex-shrink
  • 还有其他重大差异吗?

编辑/澄清:在What exactly flex-basis property sets?中以不同的格式提出了这个问题,但我对 flex-basis 的差异进行了更直接的比较或总结em>和 width (或 height )会很不错。

6 个答案:

答案 0 :(得分:265)

考虑flex-direction

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

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

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

主要差异

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

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

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

  • flex-basis对绝对定位的弹性项目没有影响。 widthheight属性是必要的。 Absolutely-positioned flex items do not participate in flex layout

  • 通过使用flex属性,三个属性 - flex-growflex-shrinkflex-basis - 可以巧妙地合并为一个声明。使用width,相同的规则需要多行代码。

浏览器行为

就其呈现方式而言,flex-basiswidth之间应该无差异,除非flex-basisauto或{ {1}}。

来自规范:

  

7.2.3. The flex-basis property

     

对于除contentauto以外的所有值,content在水平书写模式下的解析方式与flex-basis相同。

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

  

auto

     

在Flex项目上指定时,content关键字将检索该值   使用的主要大小属性auto。如果那个值是   本身flex-basis,然后使用的值为auto

     

content

     

表示基于弹性项目内容的自动调整大小。

     

注意:此值在Flexible的初始版本中不存在   Box Layout,因此一些较旧的实现将不支持它。   使用content和a一起使用可以达到相同的效果   auto的主要尺寸(widthheight)。

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

width因子

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

  • flex-shrink - 弹性项目将水平对齐
  • flex-direction: row - 弹性项目将叠加在主轴上的行的开头
  • justify-content: flex-start - flex项目将展开以涵盖容器的交叉大小
  • align-items: stretch - Flex项目被强制保留在一行
  • flex-wrap: nowrap - 允许灵活项目缩小

请注意上一次设置。

由于默认情况下允许弹性项目缩小(这会阻止它们溢出容器),因此可以覆盖指定的flex-shrink: 1 / flex-basis / width

例如,heightflex-basis: 100px加上width: 100px,不一定是100px。

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

flex-shrink: 1

OR

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

OR,根据规范建议:

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

7.2. Components of Flexibility

     

鼓励作者使用flex: 0 0 100px; /* don't grow, don't shrink, stay fixed at 100px */ 简写来控制灵活性   而不是直接用它的速记属性,作为速记   正确地重置任何未指定的组件以容纳common uses

浏览器错误

影响所有主流浏览器的Bug,IE 11&边缘:

在嵌套的Flex容器中忽略

flexflex-basis有效。

在嵌套的Flex容器中调整flex项目时发现了一个问题。

使用width时,容器会忽略其子项的大小,子容器会溢出容器。但是使用flex-basis属性,容器会考虑其子项的大小并相应地扩展。这在IE11和Edge中不是问题。

参考文献:

示例:

使用widthflex-basis溢出white-space: nowrap容器展示项目。 inline-flex有效。

在使用width渲染兄弟时,似乎设置为inline-flex的弹性容器无法识别孩子flex-basis(尽管它可能只是一个未定义的项目宽度)。容器不会扩展以容纳物品。

但是当使用white-space: nowrap属性而不是width时,容器会考虑其子项的大小并相应地扩展。这在IE11和Edge中不是问题。

参考文献:

示例:

影响IE 10和11的错误:

答案 1 :(得分:27)

除了Michael_B的优秀摘要之外,值得重复一遍:

  

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

这里的重要部分是初始

本身确实解决了宽度/高度,直到其他flex增长/缩小属性发挥作用。

因此。

的孩子
.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)...可以带来一些有趣的结果。

答案 2 :(得分:4)

可能是最重要的一点:

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

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

答案 3 :(得分:2)

似乎没有人提到flex-basiswidth(或height,取决于当前的书写方式)之间有一个关键的区别,如果我们忽略了灵活的尺寸调整方面({ {1}}。

它源自Flex布局中的例外,即弹性项目的自动最小尺寸默认为flex-grow: 0; flex-shrink: 0;,而不是通常的零。换句话说,默认的min-content会计算为min-width: auto而不是min-content

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

这与min-content的主要不同之处在于,width默认为min-width,因此可以将盒子的尺寸任意缩小(默认情况下)。如果0的值小于width,则内容将溢出框。

此规范中提到了此行为,但仅在7.1.1. Basic Values of flex末尾错误位置的以下注释中隐含了此行为。

默认情况下,弹性项目不会缩小到其最小内容大小(最长的单词或固定大小的元素的长度)以下。要更改此设置,请设置min-width或min-height属性。 (请参见第4.5节“弹性商品的自动最小尺寸”。)

如评论中所述,设置最小大小会降低边界,将其设置为零会禁用该边界,使min-content再次表现出预期的效果。

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

第二,flex-direction不再用于将空间分配给按比例大小的盒子,而不是简单地增加其初始大小。有关更多详细信息,请参见规范中的Figure 7

这是一个最小的示例。设置flex-basis可使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;
}

答案 4 :(得分:0)

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

说,您将一个孩子设置为width:0并期望它能包裹起来,那不会发生。但是使用flex-basis:0它将自动换行。 (提供的溢出不会隐藏)

答案 5 :(得分:0)

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

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

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