39

Does anyone know a vanilla way of making the body of a table scrollable using only html and css?

The obvious solution

tbody {
    height: 200px;
    overflow-y: scroll;
}

does not work.

Wouldnt this be the obvious use of tables?

am I doing something wrong?

Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129
Martin Kristiansen
  • 9,875
  • 10
  • 51
  • 83

4 Answers4

64

You need to declare a height first, else your table will expand to the according width of its content.

table{
   overflow-y:scroll;
   height:100px;
   display:block;
}

EDIT: after clarifying your problem I edited the fiddle: check out this Example or that way. It's rather hacky and not guaranteed to work crossbrowser but might work for your case.

Jessica Tiberio
  • 137
  • 1
  • 9
Christoph
  • 50,121
  • 21
  • 99
  • 128
  • what happens to the `thead` part of the table? – Martin Kristiansen Sep 26 '12 at 08:53
  • 3
    Using `display:block` would work, but generally wouldn't be recommended as the browser would no longer consider it to be a table. – scottlimmer Sep 26 '12 at 08:55
  • The examble should solve this [link](http://jsfiddle.net/nDmgy/) --and I want the header to stay in place – Martin Kristiansen Sep 26 '12 at 08:59
  • 1
    @MartinKristiansen you mean, you want to scroll the body while the head stays fixed? You can't achieve with pure css. – Christoph Sep 26 '12 at 09:00
  • @Christoph: Thats what I wanna do -- and it would seem like that was exactly what tables were made for -- but from the looks of it, I think your right. – Martin Kristiansen Sep 26 '12 at 09:01
  • I like the fix, except from the static td width, is there a way to make that dynamic? – Martin Kristiansen Sep 26 '12 at 09:21
  • @MartinKristiansen since the table-properties are destroyed with declaring `display:block` the th and td lose their coupling and thus need fixed widths, unfortunately. Just try to remove them and you will see what I mean. – Christoph Sep 26 '12 at 09:46
  • You need javascript to achieve the effect you want. I guess there are quite some plugins out there which get you the desired result. – Christoph Sep 26 '12 at 11:51
17

You can't do that with a table. Wrap the table with a div a give it something like:

div.wrapper {
    overflow:hidden;
    overflow-y: scroll;
    height: 100px; // change this to desired height
}
scottlimmer
  • 2,230
  • 1
  • 22
  • 29
14

You can wrap the table with a parent div and make him scrollable as scoota269 advised:

.div_before_table {
    overflow:hidden;
    overflow-y: scroll;
    height: 500px;
}

And to keep the table header sticky you can add a fixed class:

.th.fixed {
    top: 0;
    z-index: 2;
    position: sticky;
    background-color: white;
 }

table {
  font-family: arial, sans-serif;
  border-collapse: collapse;
  width: 100%;
}

td,
th {
  text-align: left;
  padding: 8px;
}

tr:nth-child(even) {
  background-color: #ddd;
}


/* The scrollable part */

.scrollable {
  height: 150px;
  overflow-y: scroll;
  border-bottom: 1px solid #ddd;
}

th {
  position: sticky;
  background-color: white;
  z-index: 2;
  top: 0;
}
<div class="scrollable">
  <table>
    <tr>
      <th>Company</th>
      <th>Contact</th>
      <th>Country</th>
    </tr>
    <tr>
      <td>Alfreds Futterkiste</td>
      <td>Maria Anders</td>
      <td>Germany</td>
    </tr>
    <tr>
      <td>Centro comercial Moctezuma</td>
      <td>Francisco Chang</td>
      <td>Mexico</td>
    </tr>
    <tr>
      <td>Centro comercial Moctezuma</td>
      <td>Francisco Chang</td>
      <td>Mexico</td>
    </tr>
    <tr>
      <td>Centro comercial Moctezuma</td>
      <td>Francisco Chang</td>
      <td>Mexico</td>
    </tr>
    <tr>
      <td>Ernst Handel</td>
      <td>Roland Mendel</td>
      <td>Austria</td>
    </tr>
    <tr>
      <td>Island Trading</td>
      <td>Helen Bennett</td>
      <td>UK</td>
    </tr>
    <tr>
      <td>Laughing Bacchus Winecellars</td>
      <td>Yoshi Tannamuri</td>
      <td>Canada</td>
    </tr>
    <tr>
      <td>Magazzini Alimentari Riuniti</td>
      <td>Giovanni Rovelli</td>
      <td>Italy</td>
    </tr>
  </table>
</div>
David Bendahan
  • 4,104
  • 1
  • 24
  • 21
  • This is not accurate enough. I am using a gradient for the background-color of the table head. Using th makes it to repeat the color from left to right for each column of the table head. – Package.JSON Feb 24 '21 at 10:27
-1

Do you want somthing like this ?

Pure CSS Scrollable Table with Fixed Header (1)

http://anaturb.net/csstips/sheader.htm

http://www.scientificpsychic.com/blogentries/html-and-css-scrolling-table-with-fixed-heading.html

RMN
  • 754
  • 9
  • 25
  • 45
  • Yep except that I still have to make the width of the cols in the table static. I really really dont wanna have to decide the width before runtime. – Martin Kristiansen Sep 26 '12 at 11:04
  • and the second solution is a hack if I ever saw one. without the width tag set, there is absolutely no garantie that the coloms will align with the headers – Martin Kristiansen Sep 26 '12 at 11:07
  • A similar question has been asked here: http://stackoverflow.com/questions/10838700/large-dynamically-sized-html-table-with-a-fixed-scroll-row-and-fixed-scroll-colu – RMN Sep 26 '12 at 12:36
  • And this code guy suggests to set the width at server side in case you need to set it dynamically. http://www.cssbakery.com/2010/12/css-scrolling-tables-with-fixed.html?showComment=1337211950779#c1687226751870967064 – RMN Sep 26 '12 at 12:41