Table column sizing

CssTwitter BootstrapHtml TableBootstrap 4

Css Problem Overview


In Bootstrap 3, I could apply col-sm-xx to the th tags in the thead and resize table columns at will. However this doesn't work in bootstrap 4. How can I achieve something like this in bootstrap 4?

<thead>
<th class="col-sm-3">3 columns wide</th>
<th class="col-sm-5">5 columns wide</th>
<th class="col-sm-4">4 columns wide</th>
</thead>

Looking at the codeply provided it doesn't size properly, especially if you add some data to the table. See how this runs:

<div class="container" style="border: 1px solid black;">
    <table class="table table-bordered">
    <thead>
        <tr class="row">
            <th class="col-sm-3">3 columns wide</th>
            <th class="col-sm-5">5 columns wide</th>
            <th class="col-sm-4">4 columns wide</th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td>123</td>
            <td>456</td>
            <td>789</td>
        </tr>
    </tbody>
</table>
</div>

Css Solutions


Solution 1 - Css

Updated 2018

Make sure your table includes the table class. This is because Bootstrap 4 tables are "opt-in" so the table class must be intentionally added to the table.

http://codeply.com/go/zJLXypKZxL

Bootstrap 3.x also had some CSS to reset the table cells so that they don't float..

table td[class*=col-], table th[class*=col-] {
    position: static;
    display: table-cell;
    float: none;
}

I don't know why this isn't is Bootstrap 4 alpha, but it may be added back in the final release. Adding this CSS will help all columns to use the widths set in the thead..

Bootstrap 4 Alpha 2 Demo


UPDATE (as of Bootstrap 4.0.0)

Now that Bootstrap 4 is flexbox, the table cells will not assume the correct width when adding col-*. A workaround is to use the d-inline-block class on the table cells to prevent the default display:flex of columns.

Another option in BS4 is to use the sizing utils classes for width...

<thead>
     <tr>
           <th class="w-25">25</th>
           <th class="w-50">50</th>
           <th class="w-25">25</th>
     </tr>
</thead>

Bootstrap 4 Alpha 6 Demo

Lastly, you could use d-flex on the table rows (tr), and the col-* grid classes on the columns (th,td)...

<table class="table table-bordered">
        <thead>
            <tr class="d-flex">
                <th class="col-3">25%</th>
                <th class="col-3">25%</th>
                <th class="col-6">50%</th>
            </tr>
        </thead>
        <tbody>
            <tr class="d-flex">
                <td class="col-sm-3">..</td>
                <td class="col-sm-3">..</td>
                <td class="col-sm-6">..</td>
            </tr>
        </tbody>
    </table>

Bootstrap 4.0.0 (stable) Demo

Note: Changing the TR to display:flex can alter the borders

Solution 2 - Css

Another option is to apply flex styling at the table row, and add the col-classes to the table header / table data elements:

<table>
  <thead>
    <tr class="d-flex">
      <th class="col-3">3 columns wide header</th>
      <th class="col-sm-5">5 columns wide header</th>
      <th class="col-sm-4">4 columns wide header</th>
    </tr>
  </thead>
  <tbody>
    <tr class="d-flex">
      <td class="col-3">3 columns wide content</th>
      <td class="col-sm-5">5 columns wide content</th>
      <td class="col-sm-4">4 columns wide content</th>
    </tr>
  </tbody>
</table>

Solution 3 - Css

Using d-flex class works well but some other attributes don't work anymore like vertical-align: middle property.

The best way I found to size columns very easily is to use the width attribute with percentage only in thead cells.

<table class="table">
    <thead>
        <tr>
            <th width="25%">25%</th>
            <th width="25%">25%</th>
            <th width="50%">50%</th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td>25%</td>
            <td>25%</td>
            <td>50%</td>
        </tr>
    </tbody>
</table>

Solution 4 - Css

I hacked this out for release Bootstrap 4.1.1 per my needs before I saw @florian_korner's post. Looks very similar.

If you use sass you can paste this snippet at the end of your bootstrap includes. It seems to fix the issue for chrome, IE, and edge. Does not seem to break anything in firefox.

@mixin make-td-col($size, $columns: $grid-columns) {
    width: percentage($size / $columns);
}

@each $breakpoint in map-keys($grid-breakpoints) {
    $infix: breakpoint-infix($breakpoint, $grid-breakpoints);

    @for $i from 1 through $grid-columns {
        td.col#{$infix}-#{$i}, th.col#{$infix}-#{$i} {
            @include make-td-col($i, $grid-columns);
        }
    }
}

or if you just want the compiled css utility:

td.col-1, th.col-1 {
  width: 8.33333%; }

td.col-2, th.col-2 {
  width: 16.66667%; }

td.col-3, th.col-3 {
  width: 25%; }

td.col-4, th.col-4 {
  width: 33.33333%; }

td.col-5, th.col-5 {
  width: 41.66667%; }

td.col-6, th.col-6 {
  width: 50%; }

td.col-7, th.col-7 {
  width: 58.33333%; }

td.col-8, th.col-8 {
  width: 66.66667%; }

td.col-9, th.col-9 {
  width: 75%; }

td.col-10, th.col-10 {
  width: 83.33333%; }

td.col-11, th.col-11 {
  width: 91.66667%; }

td.col-12, th.col-12 {
  width: 100%; }

td.col-sm-1, th.col-sm-1 {
  width: 8.33333%; }

td.col-sm-2, th.col-sm-2 {
  width: 16.66667%; }

td.col-sm-3, th.col-sm-3 {
  width: 25%; }

td.col-sm-4, th.col-sm-4 {
  width: 33.33333%; }

td.col-sm-5, th.col-sm-5 {
  width: 41.66667%; }

td.col-sm-6, th.col-sm-6 {
  width: 50%; }

td.col-sm-7, th.col-sm-7 {
  width: 58.33333%; }

td.col-sm-8, th.col-sm-8 {
  width: 66.66667%; }

td.col-sm-9, th.col-sm-9 {
  width: 75%; }

td.col-sm-10, th.col-sm-10 {
  width: 83.33333%; }

td.col-sm-11, th.col-sm-11 {
  width: 91.66667%; }

td.col-sm-12, th.col-sm-12 {
  width: 100%; }

td.col-md-1, th.col-md-1 {
  width: 8.33333%; }

td.col-md-2, th.col-md-2 {
  width: 16.66667%; }

td.col-md-3, th.col-md-3 {
  width: 25%; }

td.col-md-4, th.col-md-4 {
  width: 33.33333%; }

td.col-md-5, th.col-md-5 {
  width: 41.66667%; }

td.col-md-6, th.col-md-6 {
  width: 50%; }

td.col-md-7, th.col-md-7 {
  width: 58.33333%; }

td.col-md-8, th.col-md-8 {
  width: 66.66667%; }

td.col-md-9, th.col-md-9 {
  width: 75%; }

td.col-md-10, th.col-md-10 {
  width: 83.33333%; }

td.col-md-11, th.col-md-11 {
  width: 91.66667%; }

td.col-md-12, th.col-md-12 {
  width: 100%; }

td.col-lg-1, th.col-lg-1 {
  width: 8.33333%; }

td.col-lg-2, th.col-lg-2 {
  width: 16.66667%; }

td.col-lg-3, th.col-lg-3 {
  width: 25%; }

td.col-lg-4, th.col-lg-4 {
  width: 33.33333%; }

td.col-lg-5, th.col-lg-5 {
  width: 41.66667%; }

td.col-lg-6, th.col-lg-6 {
  width: 50%; }

td.col-lg-7, th.col-lg-7 {
  width: 58.33333%; }

td.col-lg-8, th.col-lg-8 {
  width: 66.66667%; }

td.col-lg-9, th.col-lg-9 {
  width: 75%; }

td.col-lg-10, th.col-lg-10 {
  width: 83.33333%; }

td.col-lg-11, th.col-lg-11 {
  width: 91.66667%; }

td.col-lg-12, th.col-lg-12 {
  width: 100%; }

td.col-xl-1, th.col-xl-1 {
  width: 8.33333%; }

td.col-xl-2, th.col-xl-2 {
  width: 16.66667%; }

td.col-xl-3, th.col-xl-3 {
  width: 25%; }

td.col-xl-4, th.col-xl-4 {
  width: 33.33333%; }

td.col-xl-5, th.col-xl-5 {
  width: 41.66667%; }

td.col-xl-6, th.col-xl-6 {
  width: 50%; }

td.col-xl-7, th.col-xl-7 {
  width: 58.33333%; }

td.col-xl-8, th.col-xl-8 {
  width: 66.66667%; }

td.col-xl-9, th.col-xl-9 {
  width: 75%; }

td.col-xl-10, th.col-xl-10 {
  width: 83.33333%; }

td.col-xl-11, th.col-xl-11 {
  width: 91.66667%; }

td.col-xl-12, th.col-xl-12 {
  width: 100%; }

Solution 5 - Css

Disclaimer: This answer may be a bit old. Since the bootstrap 4 beta. Bootstrap has changed since then.

The table column size class has been changed from this

<th class="col-sm-3">3 columns wide</th>

to

<th class="col-3">3 columns wide</th>

Solution 6 - Css

I can resolve this problem using the following code using Bootstrap 4:

<table class="table">
  <tbody>
    <tr class="d-flex">
      <th class="col-3" scope="row">Indicador:</th>
      <td class="col-9">this is my indicator</td>
    </tr>
    
    <tr class="d-flex">
      <th class="col-3" scope="row">DefiniciĆ³n:</th>
      <td class="col-9">This is my definition</td>
    </tr>
    
  </tbody>
</table>

Solution 7 - Css

As of Alpha 6 you can create the following sass file:

@each $breakpoint in map-keys($grid-breakpoints) {
  $infix: breakpoint-infix($breakpoint, $grid-breakpoints);

  col, td, th {
    @for $i from 1 through $grid-columns {
        &.col#{$infix}-#{$i} {
          flex: none;
          position: initial;
        }
    }

    @include media-breakpoint-up($breakpoint, $grid-breakpoints) {
      @for $i from 1 through $grid-columns {
        &.col#{$infix}-#{$i} {
          width: 100% / $grid-columns * $i;
        }
      }
    }
  }
}

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionKillerpixlerView Question on Stackoverflow
Solution 1 - CssZimView Answer on Stackoverflow
Solution 2 - CssJacob van LingenView Answer on Stackoverflow
Solution 3 - CssEveView Answer on Stackoverflow
Solution 4 - CssMichael AdamissionView Answer on Stackoverflow
Solution 5 - CssAbdalla ArbabView Answer on Stackoverflow
Solution 6 - CssJorge SantosView Answer on Stackoverflow
Solution 7 - CssFlorian KörnerView Answer on Stackoverflow