Parent flexbox container ignores child's flexbox min-width

时光总嘲笑我的痴心妄想 提交于 2021-01-27 15:50:59

问题


A very short prehistory

My story begins with struggling to make overflow-wrap: break-word; working inside a flexbox. Flexbox container didn't want to understand that its item can be shrunk despite the fact that the item can break long words:

.body {
  width: 300px;
  border: 1px solid black;
  padding: 8px;
  background-color: #ccc;
}

.flex-column {
  display: flex;
}

.item {
  overflow-wrap: break-word;
  background-color: #fff;
  padding: 8px;
}
<div class="body">
  <div class="flex-column">
    <div class="item">
      This is Spaaaaaaaaaaaaaaaarrrrrrrrrrrrrttttttttttttttaaaaaaaaaaaaaaaaaaaaaa!11 It's not a bug. Firefox is correctly implementing min-width: auto for flex items. When you change it to min-width: 0, you're just using a different value for min-width to get your example looking how you want it to look. But both values are being rendered correctly.
    </div>
  </div>
</div>

Fortunately, we can help flexbox to understand that it can shrink its item using min-width: 0; on the item:

.body {
  width: 300px;
  border: 1px solid black;
  padding: 8px;
  background-color: #ccc;
}

.flex-column {
  display: flex;
}

.item {
  overflow-wrap: break-word;
  background-color: #fff;
  padding: 8px;
  /* Okay, it fixes this */
  min-width: 0;
}
<div class="body">
  <div class="flex-column">
    <div class="item">
      This is Spaaaaaaaaaaaaaaaarrrrrrrrrrrrrttttttttttttttaaaaaaaaaaaaaaaaaaaaaa!11 It's not a bug. Firefox is correctly implementing min-width: auto for flex items. When you change it to min-width: 0, you're just using a different value for min-width to get your example looking how you want it to look. But both values are being rendered correctly.
    </div>
  </div>
</div>

However, the real world is a little bit more complicated.

The problem

In our application, we have many nested flexboxes. So the example should look like this:

.body {
  width: 300px;
  border: 1px solid black;
  padding: 8px;
  background-color: #ccc;
}

.flex {
  display: flex;
}

.flex-column {
  display: flex;
}

.item {
  min-width: 0;
  padding: 8px;
  background-color: #fff;
  overflow-wrap: break-word;
}
<div class="body">
  <div class="flex">
    <div class="flex">
      <div class="flex">
        <div class="flex-column">
            <div class="item">
              This is Spaaaaaaaaaaaaaaaarrrrrrrrrrrrrttttttttttttttaaaaaaaaaaaaaaaaaaaaaa!11 It's not a bug. Firefox is correctly implementing min-width: auto for flex items. When you change it to min-width: 0, you're just using a different value for min-width to get your example looking how you want it to look. But both values are being rendered correctly.
            </div>
          </div>
        </div>
      </div>
    </div>
  </div>
</div>

As you may see, the flex container of our flex-column ignores the fact that its children can shrink very well. I do not understand why is it behaves that way. Could you explain this to me? Why is the flexbox-container doesn't respect its child flexbox min-width: 0?

The solution that I've found is to set min-width: 0 to all flexboxes in the hierarchy which looks very hacky and dangerous because I can break our application layout in unexpected places.


回答1:


To understand this, simply add border with different colors to your items and you will see that you have overflow at different levels. More precesily, we have only one overflow that is moving to a lower lever after adding each min-width.

.body {
  width: 300px;
  border: 1px solid black;
  padding: 8px;
  background-color: #ccc;
}

.flex {
  display: flex;
}

.flex-column {
  display: flex;
}

.item {
  padding: 8px;
  background-color: #fff;
  overflow-wrap: break-word;
}
<div class="body">
  <div class="flex" style="border:5px solid red;">
    <div class="flex" style="border:5px solid green;">
      <div class="flex" style="border:5px solid blue;">
        <div class="flex-column" style="border:5px solid yellow;">
          <div class="item" style="border:5px solid pink;">
            This is Spaaaaaaaaaaaaaaaarrrrrrrrrrrrrttttttttttttttaaaaaaaaaaaaaaaaaaaaaa!11 It's not a bug. Firefox is correctly implementing min-width: auto for flex items. When you change it to min-width: 0, you're just using a different value for min-width to get
            your example looking how you want it to look. But both values are being rendered correctly.
          </div>
        </div>
      </div>
    </div>
  </div>
</div>

Every min-width will fix one overflow, allow the element to shrink and move the overflow to next level. That's why you need a cascading min-width.

Adding one:

.body {
  width: 300px;
  border: 1px solid black;
  padding: 8px;
  background-color: #ccc;
}

.flex {
  display: flex;
}

.flex-column {
  display: flex;
}

.item {
  padding: 8px;
  background-color: #fff;
  overflow-wrap: break-word;
}
<div class="body">
  <div class="flex" style="border:5px solid red;">
   <!-- adding min-width at this level -->
    <div class="flex" style="border:5px solid green;min-width:0;">
      <div class="flex" style="border:5px solid blue;">
        <div class="flex-column" style="border:5px solid yellow;">
            <div class="item" style="border:5px solid pink;">
              This is Spaaaaaaaaaaaaaaaarrrrrrrrrrrrrttttttttttttttaaaaaaaaaaaaaaaaaaaaaa!11 It's not a bug. Firefox is correctly implementing min-width: auto for flex items. When you change it to min-width: 0, you're just using a different value for min-width to get your example looking how you want it to look. But both values are being rendered correctly.
            </div>
          </div>
        </div>
      </div>
    </div>
  </div>
</div>

Adding another:

.body {
  width: 300px;
  border: 1px solid black;
  padding: 8px;
  background-color: #ccc;
}

.flex {
  display: flex;
}

.flex-column {
  display: flex;
}

.item {
  padding: 8px;
  background-color: #fff;
  overflow-wrap: break-word;
}
<div class="body">
  <div class="flex" style="border:5px solid red;">
    <div class="flex" style="border:5px solid green;min-width:0;">
      <!-- adding min-width at this level -->
      <div class="flex" style="border:5px solid blue;min-width:0">
        <div class="flex-column" style="border:5px solid yellow;">
          <div class="item" style="border:5px solid pink;">
            This is Spaaaaaaaaaaaaaaaarrrrrrrrrrrrrttttttttttttttaaaaaaaaaaaaaaaaaaaaaa!11 It's not a bug. Firefox is correctly implementing min-width: auto for flex items. When you change it to min-width: 0, you're just using a different value for min-width to get
            your example looking how you want it to look. But both values are being rendered correctly.
          </div>
        </div>
      </div>
    </div>
  </div>
</div>

Again:

.body {
  width: 300px;
  border: 1px solid black;
  padding: 8px;
  background-color: #ccc;
}

.flex {
  display: flex;
}

.flex-column {
  display: flex;
}

.item {
  padding: 8px;
  background-color: #fff;
  overflow-wrap: break-word;
}
<div class="body">
  <div class="flex" style="border:5px solid red;">
    <div class="flex" style="border:5px solid green;min-width:0;">
      <div class="flex" style="border:5px solid blue;min-width:0">
       <!-- adding min-width at this level -->
        <div class="flex-column" style="border:5px solid yellow;min-width:0;">
          <div class="item" style="border:5px solid pink;">
            This is Spaaaaaaaaaaaaaaaarrrrrrrrrrrrrttttttttttttttaaaaaaaaaaaaaaaaaaaaaa!11 It's not a bug. Firefox is correctly implementing min-width: auto for flex items. When you change it to min-width: 0, you're just using a different value for min-width to get
            your example looking how you want it to look. But both values are being rendered correctly.
          </div>
        </div>
      </div>
    </div>
  </div>
</div>

The last one:

.body {
  width: 300px;
  border: 1px solid black;
  padding: 8px;
  background-color: #ccc;
}

.flex {
  display: flex;
}

.flex-column {
  display: flex;
}

.item {
  padding: 8px;
  background-color: #fff;
  overflow-wrap: break-word;
}
<div class="body">
  <div class="flex" style="border:5px solid red;">
    <div class="flex" style="border:5px solid green;min-width:0;">
      <div class="flex" style="border:5px solid blue;min-width:0">
        <div class="flex-column" style="border:5px solid yellow;min-width:0;">
         <!-- adding min-width at this level -->
          <div class="item" style="border:5px solid pink;min-width:0">
            This is Spaaaaaaaaaaaaaaaarrrrrrrrrrrrrttttttttttttttaaaaaaaaaaaaaaaaaaaaaa!11 It's not a bug. Firefox is correctly implementing min-width: auto for flex items. When you change it to min-width: 0, you're just using a different value for min-width to get
            your example looking how you want it to look. But both values are being rendered correctly.
          </div>
        </div>
      </div>
    </div>
  </div>
</div>


来源:https://stackoverflow.com/questions/53209171/parent-flexbox-container-ignores-childs-flexbox-min-width

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!