Home > Net >  Flexbox inside table column using white-space: nowrap
Flexbox inside table column using white-space: nowrap

Time:12-07

My white-space nowrap text inside a flexbox container is overflowing the page as far as it goes.

I seem to have hit a weird edge- case in CSS layout.

I have a table, and inside one column I have a flex container with two columns. The first column contains a select, the second text that needs to stay in one line and end in an ellipsis if its too long (text is dynamic)

To be clear, I have no control over the table html. Only inside the column, I can add HTML.

Overflowing text inside a flexbox seems to be a common problem, but all its normal solutions don't work in my case. What I have tried:

  • Add min-width: 0; to flex container
  • Add flex-shrink: 0; to flex box with text
  • Add flex-grow: 1; to flex box with select
  • Lots of smaller stuff (width of container to 100%, ect ect)

That were all the solutions I found on many different stackoverflow articles and for me, nothing worked. It all works perfectly fine if the flex container is outside the table, but again, that's not an option for me.

This will show what I mean clearly:

.container {
    display: flex;
    min-width: 0;
    width: 100%;
    column-gap: 3rem;
}

.text {
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
<!-- Works perfectly (just a test)-->
<b>This is what i need:</b>
<div class='container'>
  <div class='child select'>
    <select>
      <option>Option 1 is a long option</option>
      <option>Option 2 is shorter</option>
    </select>
  </div>
  <div class='child text'>
    Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua.
  </div>
</div>
<br><br>

<!-- Overflows page (this needs to actually work) -->
<b>This is where it needs to work (inside table):</b>
<table>
  <tbody>
    <tr>
      <th scope="row">
        <label for="select-id">Description field</label>
      </th>
      <td>
        <div class='container'>
          <div class='child select'>
            <select id='select-id'>
              <option>Option 1 is a long option</option>
              <option>Option 2 is shorter</option>
            </select>
          </div>
          <div class='child text'>
            Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua.
          </div>
        </div>
      </td>
    </tr>
  </tbody>
</table>

I am fine with the solution to only work in the very latest browsers, or even if needed a specific browser.

CodePudding user response:

By default a table width will adjust based on its content. You have to update the algorithm using table-layout: fixed; and also add width: 100%; to restrict its width:

.container {
  display: flex;
  min-width: 0;
  width: 100%;
  column-gap: 3rem;
}

table {
  table-layout: fixed;
  width: 100%;
}

.text {
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
<!-- Works perfectly (just a test)-->
<b>This is what i need:</b>
<div class='container'>
  <div class='child select'>
    <select>
      <option>Option 1 is a long option</option>
      <option>Option 2 is shorter</option>
    </select>
  </div>
  <div class='child text'>
    Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua.
  </div>
</div>
<br><br>

<!-- Overflows page (this needs to actually work) -->
<b>This is where it needs to work (inside table):</b>
<table>
  <tbody>
    <tr>
      <th scope="row">
        <label for="select-id">Description field</label>
      </th>
      <td>
        <div class='container'>
          <div class='child select'>
            <select id='select-id'>
              <option>Option 1 is a long option</option>
              <option>Option 2 is shorter</option>
            </select>
          </div>
          <div class='child text'>
            Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua.
          </div>
        </div>
      </td>
    </tr>
  </tbody>
</table>

CodePudding user response:

You can kinda of hack this to work by assigning width to .text using the vw unit.

So for example this is what happens when I simply add width: 50vw; to .text

.container {
    display: flex;
    min-width: 0;
    width: 100%;
    column-gap: 3rem;
}

.text {
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  width: 50vw;
}
<!-- Works perfectly (just a test)-->
<b>This is what i need:</b>
<div class='container'>
  <div class='child select'>
    <select>
      <option>Option 1 is a long option</option>
      <option>Option 2 is shorter</option>
    </select>
  </div>
  <div class='child text'>
    Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua.
  </div>
</div>
<br><br>

<!-- Overflows page (this needs to actually work) -->
<b>This is where it needs to work (inside table):</b>
<table>
  <tbody>
    <tr>
      <th scope="row">
        <label for="select-id">Description field</label>
      </th>
      <td>
        <div class='container'>
          <div class='child select'>
            <select id='select-id'>
              <option>Option 1 is a long option</option>
              <option>Option 2 is shorter</option>
            </select>
          </div>
          <div class='child text'>
            Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua.
          </div>
        </div>
      </td>
    </tr>
  </tbody>
</table>

  • Related