219

Is there a way to add a horizontal scrollbar to an HTML table? I actually need it to be scrollable both vertically and horizontally depending on how the table grows but I cannot get either scrollbar to appear.

Serge Stroobandt
  • 28,495
  • 9
  • 107
  • 102
Tsundoku
  • 9,104
  • 29
  • 93
  • 127

20 Answers20

428

First, make a display: block of your table

then, set overflow-x: to auto.

table {
    display: block;
    overflow-x: auto;
    white-space: nowrap;
}

Nice and clean. No superfluous formatting.

Here are more involved examples with scrolling table captions from a page on my website.

If an issue is taken about cells not filling the entire table, append the following additional CSS code:

table tbody {
    display: table;
    width: 100%;
}
Serge Stroobandt
  • 28,495
  • 9
  • 107
  • 102
  • 4
    This works for me in Chrome, but only after squashing everything together. `white-space: nowrap;` helps immediately see the scrollbar. – Cees Timmerman Feb 17 '16 at 13:13
  • 38
    I actually tried this before. The only issue was that the table cells no longer filled the full width of the table. – Shevy Jun 23 '16 at 14:17
  • 6
    As said by others this doesn't work properly: table rows don't fill the table width. – collimarco Aug 10 '17 at 10:58
  • @collimarco Have you tried by adding `white-space: nowrap; `? – Serge Stroobandt Aug 11 '17 at 06:36
  • 1
    @SergeStroobandt no, in my case `white-space: nowrap;` doesn't solve the problem (tested on Firefox). Rows width is less than the table width when there is not enough content (text) to expand the rows. – collimarco Aug 11 '17 at 10:41
  • @collimarco Adding an equal number of empty cells should help. – Serge Stroobandt Aug 11 '17 at 11:03
  • @collimarco I found two solutions. I did this with display: inline-block instead of block, and the table is only as wide as the rows dictate. Another solution was to make the last td element in each row min-width: 100%, which causes the table to always be full page width. In both cases the text doesn't wrap. They both work on firefox. – dogoncouch Feb 10 '18 at 06:46
  • 4
    @collimarco Note I had to use max-width: 100% for the inline-block option. – dogoncouch Feb 10 '18 at 07:08
  • adding this media query handles "table cells no longer filled the full width" issue like in @media (max-width: 767px) – Muhammad Faisal Iqbal Aug 23 '19 at 14:35
  • 1
    This works perfectly in datatables, I always use white-space:nowrap because I don't like multi row cells. Overflow:auto is better than scroll because it only shows when is needed! – Ares9323 Mar 19 '20 at 15:02
  • I want to add Horizontal Scrollbar to half of the table, basically I want to horizontally scroll only the right columns of my table . How can we implement this? – Kunal Tyagi Oct 01 '20 at 08:02
  • Don't set `display: block` on tables - surprisingly it strips them of their semantics! This harms accessibility and makes life difficult for users of screen readers. See here https://developer.paciellogroup.com/blog/2018/03/short-note-on-what-css-display-properties-do-to-table-semantics/ – WickyNilliams Feb 02 '21 at 13:21
  • 3
    If you use and the rule 'table tbody, table thead' columns and headers doesnt match. I didn't use the 'display:table' declaration and put column sizes in 's (inside ). – jlbofh Apr 26 '21 at 19:08
  • 1
    Cannot use display: table on thead as well. @jlbofh not sure I understood what you did exactly to avoid this? – trainoasis Mar 07 '22 at 15:21
  • what about thead ? – sdzt9 Jun 09 '22 at 15:36
  • Using your code, noticing it doesn't work for tables that aren't "too big", thinking to myself "well, I tried", then noticing the second code block with the exact fix. You are a godsend – zdimension Nov 20 '22 at 22:36
  • I was using display: block solution until i saw that not full width issue . You can add a container element with overflow-x:auto around the table, and it will display a horizontal scroll bar when needed. That solved all problems. – greenridinghood Nov 29 '22 at 18:02
100

Did you try CSS overflow property?

overflow: scroll; /* Scrollbar are always visible */
overflow: auto;   /* Scrollbar is displayed as it's needed */

UPDATE
As other users are pointing out, this is not enough to add the scrollbars.
So please, see and upvote comments and answers below.

pasine
  • 11,311
  • 10
  • 49
  • 81
  • 16
    According to my own attempts and everything else I've read on the internet this simply won't work. You can overflow a wrapper element, sure, but not the table itself. – bloudermilk Dec 22 '14 at 15:03
  • 26
    @bloudermilk You can if you add `display: block`. – Cees Timmerman Feb 17 '16 at 13:29
  • 5
    Don't set `display: block` on tables - surprisingly it strips them of their semantics! This harms accessibility and makes life difficult for users of screen readers. See here https://developer.paciellogroup.com/blog/2018/03/short-note-on-what-css-display-properties-do-to-table-semantics/ – WickyNilliams Feb 02 '21 at 13:22
  • Wow...so I was struggling to display a table in mobile view as it was messing up my whole phone layout. Thank You @CeesTimmerman. It fixed my issue – Shrish Sharma Jun 10 '21 at 12:15
47

Wrap the table in a DIV, set with the following style:

div.wrapper {
  width: 500px;
  height: 500px;
  overflow: auto;
}
Colin M
  • 13,010
  • 3
  • 38
  • 58
  • 11
    It seem that the `overflow:auto` here is unecessary. Do you know of anyway to achieve this without setting the width... that always seems to be the solution in html - hardcode some width or height but that seems to defeat the point of having a layout engine! – JonnyRaa Mar 17 '15 at 15:13
39

This is an improvement of Serge Stroobandt's answer and works perfectly. It solves the issue of the table not filling the whole page width if it has less columns.

<style> 
 .table_wrapper{
    display: block;
    overflow-x: auto;
    white-space: nowrap;
}
</style>

<div class="table_wrapper">
<table>
...
</table>
</div>
ochomoswill
  • 391
  • 3
  • 4
25

Use the CSS attribute "overflow" for this.

Short summary:

overflow: visible|hidden|scroll|auto|initial|inherit;

e.g.

table {
    overflow: scroll;
}
Roger Willcocks
  • 1,649
  • 13
  • 27
  • link provided is broken – justingordon Jul 01 '14 at 21:03
  • To quote @WickyNillams from the comment further above: > Don't set display: block on tables - surprisingly it strips them of their semantics! This harms accessibility and makes life difficult for users of screen readers. See here https://www.tpgi.com/short-note-on-what-css-display-properties-do-to-table-semantics/ – Sascha Jan 31 '22 at 10:54
19

Edit: @WickyNilliams has noted that setting display: block on a table body will strip the table of semantics and thus is not a good solution due to accessibility issues.

I had good success with the solution proposed by @Serge Stroobandt, but I encountered the problem @Shevy had with the cells then not filling the full width of the table. I was able to fix this by adding some styles to the tbody.

table {
  display: block;
  overflow-x: auto;
  white-space: nowrap;
}

table tbody {
  display: table;
  width: 100%;
}

This worked for me in Firefox, Chrome, and Safari on Mac.

Mary7678
  • 413
  • 6
  • 12
  • 5
    Don't set `display: block` on tables - surprisingly it strips them of their semantics! This harms accessibility and makes life difficult for users of screen readers. See here https://developer.paciellogroup.com/blog/2018/03/short-note-on-what-css-display-properties-do-to-table-semantics/ – WickyNilliams Feb 02 '21 at 13:21
  • 1
    Yikes, did NOT know that! Thanks for the info, @WickyNilliams. – Mary7678 Feb 03 '21 at 03:48
  • 1
    It's very surprising behavior! – WickyNilliams Feb 03 '21 at 11:36
  • 1
    table tbody styles you apply will make it so that table thead cols have mismatched widths with tbody cols. – trainoasis Mar 07 '22 at 15:34
  • `table tbody{...}` styles don't get applied to my mat-table... Anyone have similar problems? – Baron May 17 '22 at 21:21
  • @trainoasis I tried with 4 different table styles, that isn't the case for me. – Syed M. Sannan Oct 23 '22 at 16:51
12

I couldn't get any of the above solutions to work. However, I found a hack:

body {
  background-color: #ccc;
}

.container {
  width: 300px;
  background-color: white;
}

table {
  width: 100%;
  border-collapse: collapse;
}

td {
  border: 1px solid black;
}

/* try removing the "hack" below to see how the table overflows the .body */
.hack1 {
  display: table;
  table-layout: fixed;
  width: 100%;
}

.hack2 {
  display: table-cell;
  overflow-x: auto;
  width: 100%;
}
<div class="container">

  <div class="hack1">
    <div class="hack2">

      <table>
        <tr>
          <td>table or other arbitrary content</td>
          <td>that will cause your page to stretch</td>
        </tr>
        <tr>
          <td>uncontrollably</td>
          <td>xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx</td>
        </tr>
      </table>

    </div>
  </div>

</div>
mpen
  • 272,448
  • 266
  • 850
  • 1,236
  • None of the above worked for me either, but this did. Nice one, thanks. – Gábriel Dec 14 '19 at 21:10
  • @Gábriel Glad it worked for you. I tried it again just now in Firefox and it doesn't seem to be rendering correctly :-( https://i.imgur.com/BcjSaCV.png Chrome still looks good. – mpen Dec 15 '19 at 03:25
  • 1
    Strange; I was using it exactly on Firefox and it worked there - although not in this exact setup. I wanted to render a big grid made up of 10 x 10 px divs with collapsed borders and the maxed-out width + the overflow-x: auto seemed to be the key. With those in place, everything looked perfect. Also, I'm not using at all, only divs, with display: table, table-row and table-cell.
    – Gábriel Dec 16 '19 at 07:11
9

I was running into the same issue. I discovered the following solution, which has only been tested in Chrome v31:

table {
    table-layout: fixed;
}

tbody {
    display: block;
    overflow: scroll;
}
Josh
  • 91
  • 1
  • 1
5

Insert the table inside a div, so the table will take full length

HTML

<div class="scroll">
 <table>  </table>
</div>   

CSS

.scroll{
    overflow-x: auto;
    white-space: nowrap;
}
Mark Rotteveel
  • 100,966
  • 191
  • 140
  • 197
  • 2
    That worked for me. I usually avoid changing the HTML but in that case it's much easier – clem Jan 09 '21 at 09:50
3

This is what worked for me

.wrapper {
  overflow-x: auto;
  white-space: nowrap;
}

.wrapper table {
  width: auto;
  min-width: 100%;
}

<div class="wrapper">
   <table>...</table>
</div>
Mugetsu
  • 1,739
  • 2
  • 20
  • 41
3
.wrapper {
  width: 0;
  min-width: 100%; //width 0, but min-width 100?? yes, I know...
  overflow: auto;
}
<div class="wrapper">
  <table></table>
</div>

table can have any width. I usually use 100% or max-content for the table.

2

I figured out this answer based on previous solution and it's comment and added some adjustments of my own. This works for me on the responsive table.

table {
  display: inline-block;
  overflow-x: auto;
  white-space: nowrap;
  // make fixed table width effected by overflow-x
  max-width: 100%;
  // hide all borders that make rows not filled with the table width
  border: 0;
}
// add missing borders
table td {
  border: 1px solid;
}
George
  • 91
  • 6
2

The 'more than 100% width' on the table really made it work for me.

.table-wrap {
    width: 100%;
    overflow: auto;
}

table {
    table-layout: fixed;
    width: 200%;
}
Peps
  • 184
  • 1
  • 14
2

With bootstrap

 <div class="table-responsive">
   <table class="table">
     ...
   </table>
 </div>
Forrest
  • 157
  • 14
2

add tag table to div element with style="overflow-x:auto"

<div style="overflow-x:auto">
<table class="table table-bordered">
    <thead>
        <tr>
            <th><b>Name</b></th>
            <th><b>Username</b></th>
            <th><b>Email</b></th>
            <th><b>Avatar</b></th>
            <th><b>Status</b></th>
            <th><b>Action</b></th>
        </tr>
    </thead>
    <tbody>
    </tbody>
</table>
Riki krismawan
  • 503
  • 1
  • 3
  • 10
1

For what it's worth, the best answer I found was here: https://github.com/filamentgroup/tablesaw/issues/58#issuecomment-63966574

table.tablesaw
{
    table-layout: fixed;
    max-width: none;
    width: auto;
    min-width: 100%;
}
Khaled
  • 907
  • 1
  • 8
  • 18
1

Seems a bit overdone solutions. Cleanest is to just wrap it with a div like so:

<div style="overflow-x:auto;">
  <table>
    ...
  </table>
</div>

https://www.w3schools.com/howto/howto_css_table_responsive.asp

Jelle Hak
  • 409
  • 4
  • 6
0

I tried all the above solutions but had some issues with them.

If we add display: 'block' to the table, the cells do not occupy the full width. If we add it to the table wrapper, your custom table header like search, filter etc will also scroll which will look bad.

I was able to achieve the expected behaviour by adding overflow-x: auto to the body wrapper of the table.

Cells take full width even with less columns and a scroll bar appears automatically as needed.

sarfrazanwar
  • 373
  • 5
  • 16
0

Like already stated, using display:block; on table is bad. I tried most of the answers in this thread, none worked as I wanted. If your HTML is structured like this:

<div>
  <table>
    <tbody>

And you want the parent div to be horizontally scrollable, you can try the following:

.text-left {text-align:left;} /* Ignore */

.x-auto {
  overflow-x: auto;
}

.table {
  text-align: left;
  table-layout: fixed;
  width: 100%;
  white-space: nowrap;
}

.table tbody {
  display: table;
  width: 100%;
}
<div class="x-auto">
  <table class="table text-left">
    <tbody>
      <tr>
        <th>Head1</th>
        <th>Head2</th>
      </tr>
      <tr>
        <td>Some short text!</td>
        <td>Some really long text, like really really really really really really really really really really really really long!</td>
      </tr>
    </tbody>
  </table>
</div>
George Chond
  • 977
  • 1
  • 3
  • 12
-2
//Representation of table
<div class="search-table-outter">
<table class="table table-responsive search-table inner">
</table>
</div>

//Css to make Horizontal Dropdown

<style>

    .search-table{table-layout: auto; margin:40px auto 0px auto; }
    .search-table, td, th {
        border-collapse: collapse;
    }
th{padding:20px 7px; font-size:15px; color:#444;}
td{padding:5px 10px; height:35px;}
    .search-table-outter { overflow-x: scroll; }
th, td { min-width: 200px; }


</style>
  • Indentation and sample data would help if you intend to demo something. Also, did you mean "scrollbar" instead of "Dropdown"? – Cees Timmerman Feb 17 '16 at 13:24