skip to Main Content

I am trying to solve a problem where I have 3 items in a row and when resizing window I wanna first to truncate second item and after its at minWidth then start truncating first item. Currently all items are truncating at the same time.

.container {
  display: flex;
  flex-wrap: nowrap;
  align-items: center;
  gap: 10px;
}

.child {
  border: 1px solid;
  height: 40px;
}

.truncate {
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis
}

.btn {
  min-width: 30px
}

.label {
  overflow: hidden
}
<div class="container">
  <div class="child label">
    <h3 class="truncate">Item label</h3>
  </div>
  <div class="child btn truncate">
    Item Button
  </div>
  <div class="child">
    Item Status
  </div>
</div>

https://jsfiddle.net/e08m4Lcp/

2

Answers


  1. TL;DR If you need to favor 1 child shrinking over another inside a flex parent, you can use the flex-shrink CSS property. If you’d rather read a more official explanation, here’s the MDN docs for flex-shrink

    Solution In your example, adding flex-shrink: 9999; to .btn will make that component shrink exclusively, until it hits its min-width.

    Sample

    div {
      gap: 10px;
      display: flex;
      white-space: nowrap;
    }
    
    p:nth-child(1) {
      overflow: hidden;
      text-overflow: ellipsis;
    }
    
    p:nth-child(2) {
      overflow: hidden;
      text-overflow: ellipsis;
      flex-shrink: 999999;
      min-width: 50px;
    }
    <div>
      <p>Lorem ipsum dolor sit amet
      <p>Lorem ipsum dolor sit amet
      <p>Lorem ipsum
    </div>

    Explanation

    flex-shrink works as a ratio of all values. So if you have 2 elements, flex-shrink: 1 and flex-shrink: 2 next to one another, the 2 will shrink twice as fast as the 1.

    In order to achieve your desired result, simply set an arbitrarily large value, like flex-shrink:9999 on an item so it will shrink exclusively (until other properties like min-width stops it, at which point the next item(s) will start shrinking).

    Login or Signup to reply.
  2. Following Sheraff‘s answer, I had some issues adapting it to the OP’s HTML code.

    The result: jsfiddle.net

    .container {
      display: flex;
      flex-wrap: nowrap;
      align-items: center;
      gap: 10px;
      white-space: nowrap;
    }
    
    .child.label {
      overflow: hidden;
    }
    
    .child.label h3 {
      white-space: nowrap;
      overflow: hidden;
      text-overflow: ellipsis;
      margin: 0;
    }
    
    .child.btn {
      overflow: hidden;
      text-overflow: ellipsis;
      flex-shrink: 999999;
      min-width: 30px;
    }
    
    .child {
      border: 1px solid;
      height: 40px;
    }
    <div class="container">
      <div id="label" class="child label">
    <h3 id="labelText" class="truncate">Item label</h3>
      </div>
      <div id="button" class="child btn truncate">
    Item Button
      </div>
      <div class="child">
    Item Status
      </div>
    </div>

    The flex-shrink property determines how a flex item will shrink relative to the rest of the items in the flex container when there is not enough space. The default value is 1, meaning each flex item will shrink equally to fit the container if required.

    In .child.btn CSS rule, setting flex-shrink: 999999;, a high value in comparison to the other items essentially instructs the browser to preferentially shrink this item first when the window size decreases. It is like saying, "When space is tight, this is the item that should bear the brunt of the squeezing."

    The min-width: 30px; on .child.btn acts as a lower limit; once the button reaches this width, it will not shrink any further.

    The problem was the label, which was not truncated initially: the inner <h3> tag was not set to truncate. A block-level element (like <h3>) inside a flex item can sometimes not honor the overflow property of its parent, which in this case is .child.label. So, I had to explicitly set the overflow and text-overflow properties on the <h3> element itself to make sure the text truncates as expected.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search