Search code examples
htmlcssflexboxalignment

Create scalable flex children


I have a container element that can have a variable amount of child elements and I want to scale the width of those child elements.

I've set up a simple plunker:

https://plnkr.co/edit/ef0AGPsK7FJJyBqgWuMi?p=preview

In this plunker you can shrink the DOM and the name and number elements will use their ellipsis to fit the content in the parent. This is fine.

But when you enlarge the DOM you see that the child elements are spread out so they are equally divided over the parent. this is because of the flex: 1. But I would like the container elements to be the the max width of what they would need to show the content correctly instead of filling up the parent container element.

/* Styles go here */

.conversation-container {
  display: flex;
  width: calc(100% - 20px);
  border: 1px solid black;
  background-color: green;
  padding: 10px;
}

.conversation-container .conversation-holder {
  flex: 1;
  background-color: yellow;
  padding: 5px;
  border: 1px solid white;
  margin-right: 5px;
}

.conversation-container .conversation-holder .name {
  white-space: nowrap; 
  overflow: hidden;
  text-overflow: ellipsis;
  width: 50%;
  display: inline-block;
}

.conversation-container .conversation-holder .number {
  float: left;
  white-space: nowrap; 
  overflow: hidden;
  text-overflow: ellipsis;
  width: 50%;

}

.conversation-container1 {
  display: flex;
  width: calc(100% - 20px);
  border: 1px solid black;
  background-color: green;
  padding: 10px;
}

.conversation-container1 .conversation-holder {

  background-color: yellow;
  padding: 5px;
  border: 1px solid white;
  margin-right: 5px;
}

.conversation-container1 .conversation-holder .name {
  white-space: nowrap; 
  overflow: hidden;
  text-overflow: ellipsis;
  width: 50%;
  display: inline-block;
}

.conversation-container1 .conversation-holder .number {
  float: left;
  white-space: nowrap; 
  overflow: hidden;
  text-overflow: ellipsis;
  width: 50%;

}
<h1>Scalable content using flex, example 1</h1>
  <div class="conversation-container">
    <div class="conversation-holder">
      <span class="name">Namefrom Someone</span>
      <span class="number">555666444213321</span>
    </div>
    <div class="conversation-holder">
      <span class="name">Namefrom Someone</span>
      <span class="number">555666444123123</span>
    </div>
    <div class="conversation-holder">
      <span class="name">Namefrom Someone</span>
      <span class="number">555666444123321</span>
    </div>
  </div>
  
  <h1>Scalable content using flex, example 2</h1>
  <div class="conversation-container1">
    <div class="conversation-holder">
      <span class="name">Namefrom Someone</span>
      <span class="number">555666444213321</span>
    </div>
    <div class="conversation-holder">
      <span class="name">Namefrom Someone</span>
      <span class="number">555666444123123</span>
    </div>
    <div class="conversation-holder">
      <span class="name">Namefrom Someone</span>
      <span class="number">555666444123321</span>
    </div>
  </div>


Solution

  • You can add flex: 0 1 auto (tell it not to grow but shrink is okay, and set flex-basis property to auto) to your conversation-holder (and maybe min-width: 0 if you want to shrink the coversation-holder more).

    Now instead of having width: 50% on both name and number and floating the number element to left, you can use a row-reverse flexbox on conversation-holder. See demo below:

    .conversation-container {
      display: flex;
      width: calc(100% - 20px);
      border: 1px solid black;
      background-color: green;
      padding: 10px;
    }
    
    .conversation-container .conversation-holder {
      flex: 0 1 auto; /* CHANGED */
      min-width: 0; /* ADDED */
      background-color: yellow;
      padding: 5px;
      border: 1px solid white;
      margin-right: 5px;
      /* ADDED BELOW */
      display: flex;
      flex-direction: row-reverse;
    }
    
    .conversation-container .conversation-holder .name {
      white-space: nowrap;
      overflow: hidden;
      text-overflow: ellipsis;
      /* width: 50%; */
      display: inline-block;
    }
    
    .conversation-container .conversation-holder .number {
      /* float: left; */
      white-space: nowrap;
      overflow: hidden;
      text-overflow: ellipsis;
      /* width: 50%; */
    }
    <div class="conversation-container">
      <div class="conversation-holder">
        <span class="name">Namefrom Someone</span>
        <span class="number">555666444213321</span>
      </div>
      <div class="conversation-holder">
        <span class="name">Namefrom Someone</span>
        <span class="number">555666444123123</span>
      </div>
      <div class="conversation-holder">
        <span class="name">Namefrom Someone</span>
        <span class="number">555666444123321</span>
      </div>
    </div>