Search code examples
htmlcssalignmentcenter

Center CSS 2nd row of lis that is spread evenly under a div using display:table


I want to spread out my lis evenly under a list so I'm using the display:table trick, but this is only good if you have just one row of items that is spread out. As you can see from the picture below, if you have 2 rows, the 2nd row's items will maintain the same width as the first row's, which is fine, but it is no longer centered. How do I get it to center? The number of lis will change dynamically, so ideally it would create a new row if there are more than 3 li's and center the 2nd row's li(s) if necessary too.

enter image description here

HTML

<ul class="table">
  <div class="table-row">
    <li class="cell type type-water">water</li>
    <li class="cell type type-ghost">ghost</li>
    <li class="cell type type-ground">ground</li>
  </div>
  <div class="table-row">
    <li class="cell type type-ice">ice</li>
  </div>
</ul>

CSS

.table {
  display: table;
  width: 100%;
  list-style: none;
    table-layout: fixed;
}

.table-row {
  display: table-row;
  width: 100%;
  list-style: none;
    table-layout: fixed;
}

.cell {
  display: table-cell;
  text-align: center;
}

Solution

  • In general, you can't center properly. A table is displayed, well, in a tabular way. It has columns and rows, which must remain aligned.

    For example, if your first row has three cells and the second one has 2 cells, you can either align the last 2 to the left or to the right, but not center.

    Therefore, I recommend letting the cells grow instead of centering

    .table-row {
      display: table;
      width: 100%;
      list-style: none;
      table-layout: fixed;
    }
    .cell {
      display: table-cell;
      text-align: center;
    }
    .table, .cell {
      border: 1px solid;
    }
    <div class="table">
      <div class="table-row">
        <div class="cell type type-water">water</div>
        <div class="cell type type-ghost">ghost</div>
        <div class="cell type type-ground">ground</div>
      </div>
      <div class="table-row">
        <div class="cell type type-ice">ice</div>
      </div>
    </div>

    You can do that because, since the widths of the cells are now independent in each row, we can in fact wrap each row in a different table.

    Alternatively, you can manually insert elements or pseudo-elements to place your cells at the desired position:

    .table {
      display: table;
      width: 100%;
      table-layout: fixed;
      border-collapse: collapse;
    }
    .table-row {
      display: table-row;
    }
    .cell {
      display: table-cell;
      text-align: center;
      border: 2px solid;
    }
    .insert-before::before, .insert-after::after {
      content: '';
      display: table-cell;
    }
    <div class="table">
      <div class="table-row">
        <div class="cell type type-water">water</div>
        <div class="cell type type-ghost">ghost</div>
        <div class="cell type type-ground">ground</div>
      </div>
      <div class="table-row insert-before insert-after">
        <div class="cell type type-ice">ice</div>
      </div>
    </div>

    But you won't achieve centering if the numbers of cells of different rows have different parity.