6

How can I implement a table that is both horizontally and vertically scrollable with fixed header using css?

I found this Scrolling a div from an outer div, but it is implemented by using Javascript/Jquery. Any way to implement it by using only CSS?

The updated code:

#div-table-content {
width: 100%;
overflow-x: auto;
}

table {
font-size: 12px;
white-space:nowrap;
overflow-x: scroll;
}

tbody {
height: 400px;
overflow-y: auto;
width: 100%;
display: block;
}

thead tr {
display: block;
width: 100%;
}
1
  • Something like this? Commented Oct 27, 2014 at 15:19

3 Answers 3

3

For a start divide your <table> semantically to headers inside <thead> and content inside <tbody>.

Then, for vertical scrolling, give a fixed height to your <tbody> and set overflow-y: auto and display: block.

For horizontal scrolling, I belive you have to wrap your entire table with a container (lets say <div> and give it a fixed width and overflow-x: auto.

jsFiddle Demo

Sign up to request clarification or add additional context in comments.

15 Comments

but what about the horizontal scrollable?
How would you like the horizontal scrolling to behave? The headers are scrolling horizontally too? Do you need a fixed first-column or something?
yes, the headers need scrolling horizontally too, I don't need a fixed first-column
@JoshC I updated my css code, and the result is: the div is horizontally scrollable with the header, the tbody is both vertically and horizontally scrollable and the width of the tbody is equal to the size of the first column of the header.
@Cacheing I've added a jsFiddle with the minimum of changes needed for this to work.
|
1

Horizontal and vertical scrolling with sticky column headers using css only can be done with the following.

  1. A container div with overflow: scroll
  2. A thead with position: sticky and inset-block-start: 0;

Full example below:

.container {
  overflow: scroll;
  height: 180px;
  width: 300px;
}

table {
  border-collapse: collapse;
}

table th,
table td {
  max-width: 300px;
  padding: 8px 16px;
  border: 1px solid #ddd;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

table thead {
  position: sticky;
  inset-block-start: 0;
  background-color: #ddd;
}
<div class="container">
  <table>
    <thead>
      <tr>
        <th>Fruits</th>
        <th>Nuts</th>
        <th>Vegetables</th>
        <th>Meats</th>
      </tr>
    </thead>
    <tbody>
      <tr>
        <td>Apple</td>
        <td>Peanut</td>
        <td>Carrot</td>
        <td>Chicken</td>
      </tr>
      <tr>
        <td>Banana</td>
        <td>Pecan</td>
        <td>Potato</td>
        <td>Pork</td>
      </tr>
      <tr>
        <td>Cherry</td>
        <td>Cashew</td>
        <td>Tomato</td>
        <td>Beef</td>
      </tr>
      <tr>
        <td>Grape</td>
        <td>Almond</td>
        <td>Cabbage</td>
        <td>Lamb</td>
      </tr>
      <tr>
        <td>Kiwi</td>
        <td>Brazil Nut</td>
        <td>Onion</td>
        <td>Chicken</td>
      </tr>
      <tr>
        <td>Lemon</td>
        <td>Hazelnut</td>
        <td>Cucumber</td>
        <td>Fish</td>
      </tr>
    </tbody>
  </table>
</div>

Comments

0

You can fake table with css-grid (if you don't mind).

.table {
  display: grid;
  width: 100px;
  height: 70px;
  overflow: auto;

  grid-auto-columns: max-content;
}

.head {
  position: sticky;
  top: 0;
  grid-row: 1;
  
  background-color: #fff;
  font-weight: bold;
}

Than you put all cells into single element

  <div class="table">
    <div class="head">column 1</div>
    <div class="head">column 2</div>
    <div class="head">column 3</div>
    <div>data - column 1 - row 1</div>
    <div>data - column 2 - row 1</div>
    <div>data - column 3 - row 1</div>
    <div>data - column 1 - row 2</div>
    <div>data - column 2 - row 2</div>
    <div>data - column 3 - row 2</div>
    <div>data - column 1 - row 3</div>
    <div>data - column 2 - row 3</div>
    <div>data - column 3 - row 3</div>
  </div>

Now you can see both scrollbars all the time; header scrolls horizontally but not vertically.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.