skip to Main Content

I have some div .test with grid-template-columns: auto auto auto; because I want the column width to be like flex effect which depends on the element width, and also justify-content: start; to align the column to the left and this is also why I use auto and not 1fr because I don’t want the columns being stretched to the longer width possible.

The problem is that I don’t know how to align the column neatly like a table does, s you can see from the example below, the p .target from the second div .test is longer than the first one, what I try to achieve is to make all other column width follow the longest one.

P.S.: I don’t want to use table. I also can use JavaScript to find the longest one and set all others’ width to this. I just want to see if there is an easy solution with CSS only.

p {
  margin: 0;
}

.test {
    column-gap: 30px;
    display: grid;
    grid-template-columns: auto auto auto;
    justify-content: start;
}

p:nth-child(2) {
    position: relative;
    width: 120px;
}

.flex {
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    position: absolute;
    left: 0;
    right: 0;
}
<div class="test">
  <p class="target">Hello</p>
  <p><span class="flex">Helloooooooooooooo</span></p>
  <p>Hello</p>
</div>
<div class="test">
    <p class="target">Hellooo</p>
  <p><span class="flex">Helloooooooooooooo</span></p>
  <p>Hello</p>
</div>

For example, it looks like this in a table:

td:nth-child(2) {
    position: relative;
  width: 120px;
}

.flex {
  white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
  position: absolute;
  left: 0;
  right: 0;
  top: 0;
}
<table>
<tbody>
  <tr>
    <td>Hello</td>
    <td><span class="flex">Helloooooooooooooo</span></td>
    <td>Hello</td>
  </tr>
  <tr>
    <td>Hellooo</td>
    <td><span class="flex">Helloooooooooooooo</span></td>
    <td>Hello</td>
  </tr>
</tbody>
</table>

Note that the all the second columns start together even the first column "hellooo" is longer from the second row.

2

Answers


  1. Refactor your HTML so as to add all items inside a single grid and use inline-grid:

    <div class="test">
      <p class="target">Hello</p>
      <p><span class="flex">Helloooooooooooooo</span></p>
      <p>Hello</p>
      <p class="target">Hellooo</p>
      <p><span class="flex">Helloooooooooooooo</span></p>
      <p>Hello</p>
    </div>
    
    .test {
      display: inline-grid;
    }
    

    Note that you will have to target the second element of each row with a more complex nth-child:

    p:nth-child(3n + 2) {}
    

    Try it:

    .test {
      display: inline-grid;
    }
    
    p:nth-child(3n + 2) {
      position: relative;
      width: 120px;
    }
    
    
    /* Demo only */
    
    p {
      margin: 0;
      background: #ddd;
    }
    
    .test {
      column-gap: 30px;
      grid-template-columns: auto auto auto;
      justify-content: start;
    }
    
    .flex {
      white-space: nowrap;
      overflow: hidden;
      text-overflow: ellipsis;
      position: absolute;
      left: 0;
      right: 0;
    }
    <div class="test">
      <p class="target">Hello</p>
      <p><span class="flex">Helloooooooooooooo</span></p>
      <p>Hello</p>
      <p class="target">Hellooo</p>
      <p><span class="flex">Helloooooooooooooo</span></p>
      <p>Hello</p>
    </div>
    Login or Signup to reply.
  2. If you want the grid columns to behave like a table you need to place your items in a single grid container, not 2 separate ones:

    <div class="test">
        <p class="target">Hello</p>
        <p><span class="flex">Helloooooooooooooo</span></p>
        <p>Hello</p>
        <p class="target">Hellooo</p>
        <p><span class="flex">Helloooooooooooooo</span></p>
        <p>Hello</p>
    </div>
    

    To set the width of the second element of each row, you can simply specify the width in your grid layout:

    grid-template-columns: auto 120px auto;
    

    But if we get rid of the p:nth-child(2) selector now, we’d have the .flex element positioned absolutely against the grid, and not the p element, which messes up the layout.

    But you can actually get rid of the absolute positioning altogether without messing up your layout and apply your overflow properties to all the grid items like this:

    .test > * {
        white-space: nowrap;
        overflow: hidden;
        text-overflow: ellipsis;
    }
    

    And here is the resulting, cleaner code:

    p {
      margin: 0;
    }
    
    .test {
      column-gap: 30px;
      display: grid;
      grid-template-columns: auto 120px auto;
      justify-content: start;
    }
    
    .test > * {
      white-space: nowrap;
      overflow: hidden;
      text-overflow: ellipsis;
    }
    <div class="test">
      <p class="target">Hello</p>
      <p><span class="flex">Helloooooooooooooo</span></p>
      <p>Hello</p>
      <p class="target">Hellooo</p>
      <p><span class="flex">Helloooooooooooooo</span></p>
      <p>Hello</p>
    </div>
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search