[css] Bootstrap 4 responsive tables won't take up 100% width

I am building a web app using Bootstrap 4 and running into some weird issues. I want to utilize Bootstrap's table-responsive class to allow horizontal scrolling of the tables on mobile devices. On desktop devices the table should take up 100% of the containing DIV's width.

As soon as I apply the .table-responsive class to my table, the table shrinks horizontally and no longer takes up 100% of the width. Any ideas?

Here is my markup:

<!DOCTYPE html>
<html lang="en" class="mdl-js">
<head>
    <title></title>
    <meta charset="utf-8">
    <meta name="apple-mobile-web-app-capable" content="yes">
    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
    <meta name="application-name" content="">
    <meta name="theme-color" content="#000000">
    <link rel="stylesheet" href="/css/bundle.min.css">
</head>
<body>
    <div class="container-fluid no-padding"> 
        <div class="row">
            <div class="col-md-12">
                <table class="table table-responsive" id="Queue">
                    <thead>
                        <tr>
                            <th><span span="sr-only">Priority</span></th>
                            <th>Origin</th>
                            <th>Destination</th>
                            <th>Mode</th>
                            <th>Date</th>
                            <th><span span="sr-only">Action</span></th>
                         </tr>
                      </thead>
                      <tbody>
                          <tr class="trip-container" id="row-6681470c-91ce-eb96-c9be-8e89ca941e9d" data-id="6681470c-91ce-eb96-c9be-8e89ca941e9d">
                              <td>0</td>
                              <td>PHOENIX, AZ</td>
                              <td>SAN DIEGO, CA</td>
                              <td>DRIVING</td>
                              <td><time datetime="2017-01-15T13:59">2017-01-15 13:59:00</time></td>
                              <td><span class="trip-status-toggle fa fa-stop" data-id="6681470c-91ce-eb96-c9be-8e89ca941e9d" data-trip-status="1"></span></td>
                          </tr>
                          <tr class="steps-container" data-steps-for="6681470c-91ce-eb96-c9be-8e89ca941e9d" style="display: none;">
                              <td colspan="6" class="no-padding"></td>
                          </tr>
                      </tbody>
                  </table>
              </div>
           </div>
           <br>
        </div>
        <script type="text/javascript" src="//ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
        <script type="text/javascript" src="/js/bundle.min.js"></script>
     </body>
</html>

If I apply a 100% width to the .table-responsive class, it makes the table itself a 100% wide but the child elements (TBODY, TR, etc.) are still narrow.

This question is related to css bootstrap-4

The answer is


The solution compliant with the v4 of the framework is to set the proper breakpoint. Rather than using .table-responsive, you should be able to use .table-responsive-sm (to be just responsive on small devices)

You can use any of the available endpoints: table-responsive{-sm|-md|-lg|-xl}


I found that using the recommended table-responsive class in a wrapper still causes responsive tables to (surprisingly) shrink horizontally:

<div class="table-responsive-lg">
    <table class="table">
        ...
    </table>
</div>

The solution for me was to create the following media breakpoints and classes to prevent it:

.table-xs {
    width:544px;
}

.table-sm {
    width: 576px;
}

.table-md {
    width: 768px;
}

.table-lg {
    width: 992px;
}

.table-xl {
    width: 1200px;
}

/* Small devices (landscape phones, 544px and up) */
@media (min-width: 576px) {  
    .table-sm {
        width: 100%;
    }
}

/* Medium devices (tablets, 768px and up) The navbar toggle appears at this breakpoint */
@media (min-width: 768px) {
    .table-sm {
        width: 100%;
    }

    .table-md {
        width: 100%;
    }
}

/* Large devices (desktops, 992px and up) */
@media (min-width: 992px) {
    .table-sm {
        width: 100%;
    }

    .table-md {
        width: 100%;
    }

    .table-lg {
        width: 100%;
    }
}

/* Extra large devices (large desktops, 1200px and up) */
@media (min-width: 1200px) {
    .table-sm {
        width: 100%;
    }

    .table-md {
        width: 100%;
    }

    .table-lg {
        width: 100%;
    }

    .table-xl {
        width: 100%;
    }
}

Then I can add the appropriate class to my table element. For example:

<div class="table-responsive-lg">
    <table class="table table-lg">
        ...
    </table>
</div>

Here the wrapper sets the width to 100% for large and greater per Bootstrap. With the table-lg class applied to the table element, the table width is set also set to 100% for large and greater, but set to 992px for medium and smaller. The classes table-xs, table-sm, table-md, and table-xl work the same way.


This solution worked for me:

just add another class into your table element: w-100 d-block d-md-table

so it would be : <table class="table table-responsive w-100 d-block d-md-table">

for bootstrap 4 w-100 set the width to 100% d-block (display: block) and d-md-table (display: table on min-width: 576px)

Bootstrap 4 display docs


If you're using V4.1, and according to their docs, don't assign .table-responsive directly to the table. The table should be .table and if you want it to be horizontally scrollable (responsive) add it inside a .table-responsive container (a <div>, for instance).

Responsive tables allow tables to be scrolled horizontally with ease. Make any table responsive across all viewports by wrapping a .table with .table-responsive.

<div class="table-responsive">
  <table class="table">
  ...
  </table>
</div>

doing that, no extra css is needed.

In the OP's code, .table-responsive can be used alongside with the .col-md-12 on the outside .


Taking in consideration the other answers I would do something like this, thanks!

.table-responsive {
    @include media-breakpoint-up(md) {
        display: table;
    }
}

It seems as though the "sr-only" element and its styles inside of the table are what's causing this bug. At least I had the same issue and after months of banging our head against the wall that's what we determined the cause was, though I still don't understand why. Adding left:0 to the "sr-only" styles fixed it.


None of these answers are working (date today 9th Dec 2018). The correct resolution here is to add .table-responsive-sm to your table:

<table class='table table-responsive-sm'>
[Your table]
</table>

This applies the responsiveness aspect only to the SM view (mobile). So in mobile view you get the scrolling as desired and in larger views the table is not responsive and thus displayed full width, as desired.

Docs: https://getbootstrap.com/docs/4.0/content/tables/#breakpoint-specific


For some reason the responsive table in particular doesn't behave as it should. You can patch it by getting rid of display:block;

.table-responsive {
    display: table;
}

I may file a bug report.

Edit:

It is an existing bug.


Create responsive tables by wrapping any .table with .table-responsive{-sm|-md|-lg|-xl}, making the table scroll horizontally at each max-width breakpoint of up to (but not including) 576px, 768px, 992px, and 1120px, respectively.

just wrap table with .table-responsive{-sm|-md|-lg|-xl}

for example

<div class="table-responsive-md">
    <table class="table">
    </table>
</div>

bootstrap 4 tables


It's caused by the table-responsive class giving the table a property of display:block, which is strange because this overwrites the table classes original display:table and is why the table shrinks when you add table-responsive.

Most likely its down to bootstrap 4 still being in dev. You are safe to overwrite this property with your own class that sets display:table and it won't effect the responsiveness of the table.

e.g.

.table-responsive-fix{
   display:table;
}

That's because the .table-responsive class adds the property display: block to your element which changes it from the previous display: table.

Override this property back to display: table in your own stylesheet

.table-responsive {
    display: table;
}

Note: make sure this style executes after your bootstrap code for it to override.


For Bootstrap 4.x use display utilities:

w-100 d-print-block d-print-table

Usage:

<table class="table w-100 d-print-block d-print-table">