【问题标题】:CSS flexbox (flex-grow / flex-basis) - Same width, but doesn't wrap anymoreCSS flexbox (flex-grow / flex-basis) - 相同的宽度,但不再换行
【发布时间】:2017-08-30 04:14:34
【问题描述】:

我使用弹性框来组织页面上的元素。

我希望弹性框使用所有可用的水平空间,所以我添加了flex-grow:1

然后我希望同一行上的每个项目具有相同的大小(例如,如果有两个项目,每个项目 50%,如果有三个项目,则 33%,等等),所以我添加 flex-basis:0

但在第三步,这些项目不再包装。如果我更改窗口宽度,每行的项目数始终保持不变,并且它们的内容会被压缩。我不想要那个。我希望一个项目在其宽度变得小于其内容时放在下一行,因为它在前两个步骤中起作用。我尝试玩flex-shrink 和其他东西,但没有成功。

我能做什么?谢谢!

回答 TL;DR: 添加 min-width: fit-content 有效!

JSFiddle

【问题讨论】:

    标签: html css flexbox


    【解决方案1】:

    虽然您将flex-wrap 设置为wrap,但没有为弹性项目(li)定义width,并且您将flex-basis 设置为0。这意味着初始主大小弹性项目为 0。它不会换行,因为它可以缩小到零(即使 flex-shrink 属性为 0)。

    解决方案 #1

    您可以做的一件事是将flex-basis 属性设置为contentauto

    li { flex-basis: auto; }
    

    这告诉弹性项目考虑其内容的宽度。

    jsfiddle demo

    flex-basis

    弹性项目的初始主尺寸。

    auto

    当在弹性项目上指定时,auto 关键字检索值 的主要尺寸属性作为使用的flex-basis。如果该值为 还有auto,那么使用的值为content

    content

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

    注意:请注意,content 在初始版本中不存在 灵活的盒子布局,因此一些较旧的实现不会 支持它。一起使用auto可以达到同等效果 主尺寸(宽度或高度)为auto

    来自flexbox spec 的这张图试图解释flex-basis: 0flex-basis: auto 之间的区别。 Here's a more complete explanation.


    解决方案 #2

    另一种在较小屏幕上垂直堆叠弹性项目的方法是更改​​媒体查询中的flex-direction

    @media screen and ( max-width: 500px ) {
        ul { flex-direction: column; }
        li { flex-basis: auto; }
    }
    

    jsfiddle demo

    【讨论】:

    • 感谢您的详细解答。但是,对于解决方案 #1,同一行上的项目不再具有相同的宽度(为此,我必须将 flex-basis 保留为 0)。解决方案 2 可能有效,但消除了使用 flexbox 的好处之一,即自动适应项目和屏幕宽度(没有以像素为单位的“硬数字”)。
    • 媒体查询中的 500px 仅用于演示。您也可以使用相对单位和calc
    【解决方案2】:

    如果项目对于窗口宽度来说太大,我会使用媒体查询将元素的flex-direction 更改为column。这会将列表中的项目置于彼此下方。

    HTML

    <ul class="grid__row grid__row--sm">
        <li>1 small</li>
        <li>1 wide wide wide wide wide wide</li>
    </ul>
    <ul class="grid__row grid__row--sm">
        <li>2 medium medium</li>
        <li>2 small</li>
    </ul>
    <ul class="grid__row grid__row--md">
        <li>3 small</li>
        <li>3 wide wide wide wide wide wide</li>
        <li>3 medium medium</li>
    </ul>
    

    CSS

    .grid__row {
        margin: auto;
        padding: 0;
        list-style-type: none;
        display: flex;
        flex-direction: column;
    }
    
    .grid__row li {
        background: green;
        color: white;
        margin: 1px;
        padding: 15px;
        display:flex;
        flex: 1;
    }
    
    @media (min-width: 480px) {
        .grid__row--sm {
            flex-direction: row;
        }
    }
    
    @media (min-width: 768px) {
        .grid__row--md {
            flex-direction: row;
        }
    }
    

    JSFiddle

    【讨论】:

      【解决方案3】:

      您不能将 flex-basis 设置为 autocontent,因为您希望所有框的大小相同,因此 flex-basis 必须为 0flex-grow 设置为 1,正如你所做的那样。你现在需要做的是在弹性项目上设置min-width(例如200px)。你的里程可能会有所不同,我相信 safari(自从谷歌眨眼以来,webkit 一直在努力跟上)可能会在min-width 上出现flex-items 上的错误。

      或者,您可以将 flex-basis 设置为应该可以工作的 min-width 属性,即使在 safari (flex: 1 0 200px) 中也是如此

      ul {
          margin: auto;
          padding: 0;
          list-style-type: none;
          display: flex;
          flex-wrap: wrap;
      }
      li {
          background: green;
          margin: 1px;
          flex: 1 0 200px;
      }
      <ul>
          <li>1 small</li>
          <li>1 wide wide wide wide wide wide</li>
      </ul>
      <ul>
          <li>2 medium medium</li>
          <li>2 small</li>
      </ul>
      <ul>
          <li>3 small</li>
          <li>3 wide wide wide wide wide wide</li>
          <li>3 medium medium</li>
      </ul>

      【讨论】:

      • 感谢您的回答。我不想在代码中以像素为单位添加“硬数字”,因为使用弹性框的好处之一是自动适应项目和屏幕宽度。然而,正如你所说,答案在min-width
      【解决方案4】:

      感谢 Michael_B 和 Adam,我找到了解决问题的方法。

      flex-grow: 1;
      flex-basis: 0;
      min-width: fit-content;
      

      min-widthfit-content 值是这里的关键。它是实验性的(您可能必须添加浏览器前缀),但它完全符合我的要求:相同的宽度,带换行!

      【讨论】:

        猜你喜欢
        • 2019-07-07
        • 2020-12-08
        • 2020-01-04
        • 2018-03-24
        • 2018-08-12
        • 1970-01-01
        • 1970-01-01
        • 2020-12-16
        • 1970-01-01
        相关资源
        最近更新 更多