skip to Main Content

Preconditions: I am limited to old browsers (around Chrome 25), which do not support a lot of CSS features. Also, the table structure with 3 columns needs to remain, and the first column should not take more space, than it needs.

Goal: I have an info element, which specifies the overall width and a red box within the cell, which already takes up some space. Furthermore, I want the text element to fill the remaining space, without pushing the red box out of the boundaries. Note, that the parent width and the box width could be dynamic values, depending on the screen resolution. I tried to wrap the according cell in another flex box combined with "flex: 1 1 0" and many other things, and ChatGPT also had no answer.

Do you have a solution? Or is it not solvable with the requirements?

.info {
  width: 600px; /* dynamic */
  background: lightgray;
}

.container {
  background: gray;
}

.table {
  display: table;
}

.row {
  display: table-row;
}

.row :first-child {
  border-right: solid black 20px;
}

.cell {
  display: table-cell;
}

.flex {
  display: flex;
}

.box {
  width: 300px; /* dynamic */
  background: red;
}

.text {
  white-space: nowrap; /* needs to fill the remaining space, without pushing the box out of its parent */
}
<div class="info">
  <div class="container">
    <div class="table">
      <div class="row">
        <div class="cell">1.1</div>
        <div class="cell ">1.2</div>
        <div class="cell ">1.3</div>
      </div>
      <div class="row">
        <div class="cell">2.1</div>
        <div class="cell">
          <div class="flex">
            <div class="text">This is a text, too long to fit inside the container</div>
            <div class="box"></div>
          </div>
        </div>
        <div class="cell">2.3</div>
      </div>
    </div>
  </div>
</div>

Each row can only consist of a single line, thus white-space: nowrap is required. That part of the text, that needs to be cut of, should be hidden with overlap: hidden.

Current Layout:
enter image description here

Expected Layout:
enter image description here

2

Answers


  1. Updated to reflect question edit

    Here is an example using table markup.

    The only way I can think of to make this work is using CSS grid and subgrid* to ensure consistent cell alignment across table rows

    Please note that changing the display type on tables and lists affects accessibility – why you probably would have to add aria roles to support screen readers

    *subgrid support

    .info {
      max-width: 600px;
    }
    
    
    /*
      main grid to ensure table row grids stay alligned 
      
      note! <tbody> is rendered by default why we define
      the grid here and not on the <table>
    */
    
    tbody {
      display: grid;
      gap: 10px;
      grid-template-columns: repeat(3, auto);
    }
    
    tr {
      /* span all cells in the main grid*/
      grid-column: span 3;
      display: grid;
      /* pass main grid cells to <td> children */
      grid-template-columns: subgrid;
    }
    
    td {
      /* add flex layout to cells and hide overflows */
      display: flex;
      align-items: center;
      overflow: hidden;
    }
    
    .text {
      /* ellipsis text block */
      white-space: nowrap;
      overflow: hidden;
      text-overflow: ellipsis;
    }
    
    .box {
      /* non shrinking box content */
      width: 300px;
      height: 25px;
      flex-shrink: 0;
    }
    
    
    /* just a bit of styling to show layout */
    
    .info {
      padding: .5rem;
      outline: 1px dashed blue;
      background: skyblue;
    }
    
    tbody {
      padding: .5rem;
      outline: 1px dashed red;
      background: tomato;
    }
    
    tr {
      padding: .5rem;
      outline: 1px dashed olive;
      background: yellowgreen;
    }
    
    td {
      padding: .5rem;
      outline: 1px dashed orange;
      background: gold;
    }
    
    
    .text {
      background: white;
    }
    .box {
      background: black;
    }
    <div class="info">
      <table>
        <tr>
          <td>First cell</td>
          <td>1.2</td>
          <td>1.3</td>
        </tr>
        <tr>
          <td>2.1</td>
          <td>
            <span class="text">
              This is a very long text This is a very long text This is a very long text
            </span>
            <div class="box"></div>
          </td>
          <td>2.3</td>
        </tr>
      </table>
    </div>
    Login or Signup to reply.
  2. If you have a table, use <table>.
    Although it is quite dirty, you can wrap the text in <div> and add position: absolute;
    Example:

    .info {
      max-width: 600px;
    }
    
    table {
      width: 100%;
      white-space: nowrap;
    }
    
    table td {
      width: 0;
      border: solid 1px #ccc;
    }
    
    .content {
      position: relative;
      min-width: 400px;
      overflow: hidden;
    }
    
    .text {
      position: absolute;
      left: 0;
      top: 0;
      right: 300px;
      bottom: 0;
      text-overflow: ellipsis;
      overflow: hidden;
      line-height: 24px;
    }
    
    .box {
      background-color: black;
      width: 300px;
      height: 24px;
      float: right;
    }
    <div class="info">
      <table>
        <tr>
          <td>1.1</td>
          <td>1.2</td>
          <td>1.3</td>
        </tr>
        <tr>
          <td>2.1</td>
          <td>
            <div class="content">
              <div class="text">
                This is a very long text This is a very long text This is a very long text
              </div>
              <div class="box"></div>
            </div>
          </td>
          <td>2.3</td>
        </tr>
      </table>
    </div>
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search