首页 文章

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

提问于
浏览
159

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

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

...这本身并没有说明基于柔性基组的元素的行为 . 根据我目前对flexbox的了解,我也没有描述宽度 .

我想知道flex-basis与实际宽度的不同之处:

  • 如果我用flex-basis替换宽度(反之亦然),那么会在视觉上改变什么?

  • 如果我将两者设置为不同的值会怎样?如果它们具有相同的值会发生什么?

  • 是否存在一些特殊情况,使用宽度或柔性基础与使用另一个有明显区别?

  • 当与其他flexbox样式(如flex-wrap,flex-grow和flex-shrink)结合使用时,width和flex-basis的差异如何?

  • 还有其他重大差异吗?


Edit/clarification :这个问题已在What exactly flex-basis property sets?中以不同的格式提出,但我觉得更直接的比较或总结柔性基础和宽度(或高度)的差异会很好 .

3 回答

  • 24

    考虑弯曲方向

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

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

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


    主要差异

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

    • flex-basis 仅适用于弹性项目 . Flex容器(也不是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-basisautocontent .

    从规格:

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

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

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

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


    弹性收缩因子

    记住flex容器的初始设置很重要 . 其中一些设置包括:

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

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

    • align-items: stretch - flex项目将展开以覆盖容器的交叉大小

    • flex-wrap: nowrap - Flex项目被强制保留在一行中

    • flex-shrink: 1 - 允许弹性项目缩小

    请注意最后的设置 .

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

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

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

    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速记来控制灵活性,而不是直接使用其纵向属性,因为速记正确地重置任何未指定的组件以适应常见用途 .


    浏览器错误

    影响所有主流浏览器的错误,IE 11和Edge除外:

    flex-basis在嵌套的Flex容器中被忽略 . 宽度有效 .

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

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

    参考文献:

    例子:

    flex项使用flex-basis和white-space:nowrap溢出inline-flex容器 . 宽度有效 .

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

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

    参考文献:

    例:


    影响IE 10和11的错误:

  • 235

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

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

    这里重要的部分是 initial .

    就其本身而言,这确实解决了宽度/高度,直到其他弹性增长/收缩属性发挥作用 .

    所以 . 一个孩子

    .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 )......可以产生一些有趣的结果 .

  • 3

    可能是最重要的一点:

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

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

相关问题