Home > other >  Table with CSS Grid: give all columns of same type width of entry with widest content?
Table with CSS Grid: give all columns of same type width of entry with widest content?

Time:08-02

I have the following table design, laid out with CSS Grid (see first snippet).

Is it possible to make all columns of the same type/class (e.g. .Table_col_day) as wide as the column of that type/class with the widest content, with CSS/without JS? The solution doesn’t have to be CSS Grid based.

See the second code snippet for a quick JS-based solution, to illustrate what I'd like to do.

.Table__row {
  background-color: plum;
  
  display: grid;
  grid-template-columns: 0.5fr 0.5fr 1fr;
}

.Table__row:nth-of-type(even) {
  background-color: lime;
}
<div >

  <div >
    <div >Mon</div>
    <div >10am</div>
    <div >Some event</div>
  </div>

  <div >
    <div >Tue</div>
    <div >12:30pm</div>
    <div >Another event</div>
  </div>

  <div >
    <div >Wed</div>
    <div >9:00am</div>
    <div >A different event</div>
  </div>

</div>

Javascript-based solution (determine widest column content, then manually set grid column styles of row element)

function resizeColumns(SELECTOR) {
  const colElements = document.querySelectorAll(SELECTOR);
  //////
  const widths = [...colElements].map(el => el.querySelector('span').offsetWidth);
  const width_max = Math.max(...widths);
  //////
  for(let col of colElements) {
    col.parentNode.style.gridTemplateColumns = `${width_max}px 0.5fr 1fr`;
  }
}

resizeColumns('.Table__col_day');
.Table__row {
  background-color: plum;
  display: grid;
  grid-template-columns: 0.5fr 0.5fr 1fr;
}

.Table__row:nth-of-type(even) {
  background-color: lime;
}
<div >

  <div >
    <div >
      <span>Mon</span>
    </div>
    <div >
      <span>10am</span>
    </div>
    <div >
      <span>Some event</span>
    </div>
  </div>

  <div >
    <div >
      <span>Tue</span>
    </div>
    <div >
      <span>12:30pm</span>
    </div>
    <div >
      <span>Another event</span>
    </div>
  </div>

  <div >
    <div >
      <span>Wed</span>
    </div>
    <div >
      <span>9:00am</span>
    </div>
    <div >
      <span>A different event</span>
    </div>
  </div>

</div>

CodePudding user response:

You said it at the beginning: "table design" so use table

.Table {
  display: table;
  width: 100%;
}

.Table__row {
  background-color: plum;
  display: table-row;
}

.Table__row > * {
  display: table-cell;
  white-space: nowrap;
}

.Table__row > *:not(.Table__day) {
  width: 50%;
}

.Table__row:nth-of-type(even) {
  background-color: lime;
}
<div >

  <div >
    <div >Mon</div>
    <div >10am</div>
    <div >Some event</div>
  </div>

  <div >
    <div >Tue</div>
    <div >12:30pm</div>
    <div >Another event</div>
  </div>

  <div >
    <div >Wed</div>
    <div >9:00am</div>
    <div >A different event</div>
  </div>

</div>

Or consider display:contents if you want to keep display:grid;

.Table {
  display: grid;
  grid-template-columns: auto 1fr 1fr;
}

.Table__row {
  display: contents;
}
.Table__row > * {
  background-color: plum;
}

.Table__row:nth-of-type(even) > * {
  background-color: lime;
}
<div >

  <div >
    <div >Mon</div>
    <div >10am</div>
    <div >Some event</div>
  </div>

  <div >
    <div >Tue</div>
    <div >12:30pm</div>
    <div >Another event</div>
  </div>

  <div >
    <div >Wed</div>
    <div >9:00am</div>
    <div >A different event</div>
  </div>

</div>

  • Related