Search code examples
htmlcssflexbox

How to make flex-box work with a nested child that needs truncated text?


To let a flex-child have truncated text with ellipsis one can give the parent an min-with:0. In my project the child is nested in almost 10 different flex containers. Do I need to give all parents a min-width:0 or is ther a better work around?

sandbox

body {
  width: 400px;
}

.flex-parent {
  display: flex;
  padding: 10px;
  border: solid;
}

.flex-parent-parent {
  display: flex;
  border: solid;
  padding: 10px;
}

.flex-parent-parent-parent {
  display: flex;
  border: solid;
  padding: 10px;
}

.long-and-truncated {
  flex: 1;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
<div class="flex-parent-parent-parent">
  <div class="flex-parent-parent">
    <div class="flex-parent">
      <div class="flex-child long-and-truncated">
        1. This is a long string that is OK to truncate please and thank you
      </div>
    </div>
  </div>
</div>


Solution

  • This is due to the automatic minimum size of flex items. There is an excellent answer explaining this behavior which says:

    If you're dealing with flex items on multiple levels of the HTML structure, it may be necessary to override the default min-width: auto / min-height: auto on items at higher levels.

    Basically, a higher level flex item with min-width: auto can prevent shrinking on items nested below with min-width: 0.

    You need to override min-width in some way on each flex container up the chain. It does not have to be 0 just any value other than auto. For example:

    body {
      width: 400px;
    }
    
    .flex-parent,
    .flex-parent-parent,
    .flex-parent-parent-parent {
      display: flex;
      padding: 10px;
      border: solid;
      min-width: 200px;
    }
    
    .flex-parent {
      min-width: 0;
    }
    
    .long-and-truncated {
      flex: 1;
      white-space: nowrap;
      overflow: hidden;
      text-overflow: ellipsis;
    }
    <div class="flex-parent-parent-parent">
      <div class="flex-parent-parent">
        <div class="flex-parent">
          <div class="flex-child long-and-truncated">
        1. This is a long string that is OK to truncate please and thank you
          </div>
        </div>
      </div>
    </div>

    In my example, I set all flex containers to have the same min-width value but this is not necessary. You could set each to be unique to it's needs in your layout.

    .flex-parent { min-width: 0; }
    .flex-parent-parent { min-width: 100px; }
    .flex-parent-parent-parent { min-width: 400px; }
    

    There is one other way to achieve this behavior, but still involves all nested flex containers:

    .flex-parent,
    .flex-parent-parent,
    .flex-parent-parent-parent {
      display: flex;
      box-sizing: border-box;
      max-width: 100%;
    }
    

    By setting some combination of min-width and/or max-width on each of your nested flex containers you should be able to get your text to truncate.