Таблица у которой ячейки с одинаковой шириной и высотой

Можно ли сделать таблицу без js, у которой ячейки одинаковой ширины и высоты?
при этом таблица динамическая, изначально не известно сколько будет ячеек

.container{
  width: 500px;
  margin: 0 auto;
}
table{
  width: 100%;
  border-collapse: collapse;
  border: 1px solid #dee2e6;
  text-align:center;
}
td{
  border: 1px solid #E7ECF2;
}
<div class="container">
  <table class="table table-bordered">
    <tbody>
        <tr>
           <td>1</td>
           <td>2</td>
           <td>3</td>
           <td>4</td>
        </tr>
        <tr>
           <td>5</td>
           <td>6</td>
           <td>7</td>
           <td>8</td>
        </tr>
    </tbody>
  </table>
</div>
https://jsfiddle.net/jouhntv3/
или это нужно делать с js и вычислять ширину?


Ответы (2 шт):

Автор решения: DiD

Вы имеете в виду так?

JS тут только для добавления ячеек. Если таблица генерируется на сервере, содержимое тега <style> должно генерироваться вместе с таблицей.

const table = document.querySelector('table');
const style = document.querySelector('body style');

function addCol() {
  table.querySelectorAll('tr')
    .forEach(tr => tr.appendChild(document.createElement('td')));
  setStyle();
}

function addRow() {
  let tr = document.createElement('tr');
  table.querySelectorAll('table tr:nth-child(1) td')
    .forEach(() => tr.appendChild(document.createElement('td')));
  table.appendChild(tr);
  setStyle();
}

function setStyle() {
  style.innerHTML =
    `td { width: min( calc(100vh / ${table.querySelectorAll('tr').length} - 1px), calc(100vw / ${table.querySelectorAll('table tr:nth-child(1) td').length} - 1px) );
        height: min( calc(100vh / ${table.querySelectorAll('tr').length} - 1px), calc(100vw / ${table.querySelectorAll('table tr:nth-child(1) td').length} - 1px) ); }`;
}

function showCSS(){
  alert(style.innerHTML);
  }
button {
  position: absolute;
}

button:nth-child(2) {
  top: 1.5rem;
}

button:nth-child(3) {
  top: 3rem;
}

* {
  box-sizing: border-box;
}

body {
  margin: 0;
}

table {
  top: 0;
  max-width: 100vw;
  margin: 0 auto;
  max-height: 100vh;
  border-collapse: collapse;

}
<button onclick="addCol()">Add col</button>
<button onclick="addRow()">Add row</button>
<button onclick="showCSS()">Show CSS</button>
<style>
  td {
    width: calc( 100vh / 3 - 1px);
    height: calc( 100vh / 3 - 1px);
  }
  table {
    height: 100vh;
  }
</style>
<table border="1">
  <tr>
    <td></td>
    <td></td>
    <td></td>
    <td></td>
  </tr>
  <tr>
    <td></td>
    <td></td>
    <td></td>
    <td></td>
  </tr>
  <tr>
    <td></td>
    <td></td>
    <td></td>
    <td></td>
  </tr>
</table>

→ Ссылка
Автор решения: zhurof

Есть старый, но немного костыльный способ делать квадратные блоки на одном лишь css, используя особенность вертикального паддинга в процентах (берётся от ширины родителя). Правда в таком случае контент ячейки придётся абсолютить.

*,*before,*after{
  box-sizing: border-box;
}
.container{
  width: 500px;
  margin: 0 auto;
}
table{
  width: 100%;
  border-collapse: collapse;
  border: 1px solid #dee2e6;
  text-align:center;
}
td{
  border: 1px solid #E7ECF2;
  position: relative;
}
td:before{
  content: '';
  display: block;
  padding-top: 100%;
}
td span{
  display: block;
  position: absolute;
  width: 100%;
  left: 0;
  top: 50%;
  transform: translateY(-50%);
}
<div class="container">
  <table class="table table-bordered">
    <tbody>
        <tr>
           <td><span>1</span></td>
           <td><span>2</span></td>
           <td><span>3</span></td>
           <td><span>4</span></td>
        </tr>
        <tr>
           <td><span>5</span></td>
           <td><span>6</span></td>
           <td><span>7</span></td>
           <td><span>8</span></td>
        </tr>
    </tbody>
  </table>
</div>

→ Ссылка