TABLE with sticky header row and scrollable body rows

Discussion in 'HTML' started by JJ, Oct 31, 2013.

  1. JJ

    JJ Guest

    I have a vertically long TABLE that I need to be scrollable. For this,
    currently I put it in a DIV and use that DIV as the scroller. i.e.:

    <div style="height:500px;overflow-y:auto">
    <table>
    <thead>
    <tr><th>header1</th><th>header2</th><th>header3</th></tr>
    </thead>
    <tbody>
    <tr><td>data1 col1</td><td>data1 col2</td><td>data1 col3</td></tr>
    <tr><td>data2 col1</td><td>data2 col2</td><td>data2 col3</td></tr>
    <tr>
    <td>this column can be multiple lines. also variable width</td>
    <td>this one always in one line. fixed width</td>
    <td>this one always in one line. fixed width</td>
    </tr>
    <!-- etc. -->
    </tbody>
    </table>
    </div>

    This works, but the disadvantage is that, the header row can get out of view
    when the table is scrolled. So I want to make the header row sticky like
    Windows Explorer's Detail view.

    I thought of assigning "overfow-y:auto" style to TBODY, but it's not
    applicable since that style is for block/inline-block elements only. But if
    I use "display:block" on the TBODY, the table layout is messed up.

    So how can I make the header row sticky?
    If possible, without using JavaScript at all.
     
    JJ, Oct 31, 2013
    #1
    1. Advertising

  2. JJ

    Tim Streater Guest

    In article <>, JJ <>
    wrote:

    > I have a vertically long TABLE that I need to be scrollable. For this,
    > currently I put it in a DIV and use that DIV as the scroller. i.e.:


    [snip]

    > So how can I make the header row sticky?
    > If possible, without using JavaScript at all.


    The only way I found to do it is to have two tables. With suitable CSS
    it looks like one table. The upper one has just the one row, obviously.

    --
    Tim

    "That excessive bail ought not to be required, nor excessive fines imposed,
    nor cruel and unusual punishments inflicted" -- Bill of Rights 1689
     
    Tim Streater, Oct 31, 2013
    #2
    1. Advertising

  3. JJ

    dorayme Guest

    In article <>,
    JJ <> wrote:

    > I have a vertically long TABLE that I need to be scrollable. For this,
    > currently I put it in a DIV and use that DIV as the scroller. i.e.:
    >
    > <div style="height:500px;overflow-y:auto">
    > <table>
    > <thead>
    > <tr><th>header1</th><th>header2</th><th>header3</th></tr>
    > </thead>
    > <tbody>
    > <tr><td>data1 col1</td><td>data1 col2</td><td>data1 col3</td></tr>
    > <tr><td>data2 col1</td><td>data2 col2</td><td>data2 col3</td></tr>
    > <tr>
    > <td>this column can be multiple lines. also variable width</td>
    > <td>this one always in one line. fixed width</td>
    > <td>this one always in one line. fixed width</td>
    > </tr>
    > <!-- etc. -->
    > </tbody>
    > </table>
    > </div>
    >
    > This works, but the disadvantage is that, the header row can get out of view
    > when the table is scrolled. So I want to make the header row sticky like
    > Windows Explorer's Detail view.
    >
    > I thought of assigning "overfow-y:auto" style to TBODY, but it's not
    > applicable since that style is for block/inline-block elements only. But if
    > I use "display:block" on the TBODY, the table layout is messed up.
    >
    > So how can I make the header row sticky?
    > If possible, without using JavaScript at all.


    Take a look at

    <http://pics.cssbakery.com/treats/scrollingtable/tableTest6.php>

    If it is sort of thing you want, look at the source, or see through

    <http://www.cssbakery.com/2010/12/css-scrolling-tables-with-fixed.html>

    --
    dorayme
     
    dorayme, Oct 31, 2013
    #3
  4. JJ

    JJ Guest

    On Thu, 31 Oct 2013 17:47:52 +0000, Tim Streater wrote:
    > The only way I found to do it is to have two tables. With suitable CSS
    > it looks like one table. The upper one has just the one row, obviously.


    I tried that once, but the header table column widths won't match/align with
    the data table.

    Even though my table width is fixed, there are at least two columns whose
    width must be variable depending on their cells' contents.
     
    JJ, Nov 1, 2013
    #4
  5. JJ

    JJ Guest

    On Fri, 01 Nov 2013 10:19:39 +1100, dorayme wrote:
    > Take a look at
    >
    > <http://pics.cssbakery.com/treats/scrollingtable/tableTest6.php>
    >
    > If it is sort of thing you want, look at the source, or see through
    >
    > <http://www.cssbakery.com/2010/12/css-scrolling-tables-with-fixed.html>


    Sorry I forgot to mention that, my table has at least two columns whose
    width must be variable depending on their cells' contents. The table width
    is fixed.

    The examples in that pages use fixed width for all columns. But maybe I
    could use them later. Thanks.
     
    JJ, Nov 1, 2013
    #5
  6. 2013-11-01 7:17, JJ wrote:

    > On Thu, 31 Oct 2013 17:47:52 +0000, Tim Streater wrote:
    >> The only way I found to do it is to have two tables. With suitable CSS
    >> it looks like one table. The upper one has just the one row, obviously.

    >
    > I tried that once, but the header table column widths won't match/align with
    > the data table.
    >
    > Even though my table width is fixed, there are at least two columns whose
    > width must be variable depending on their cells' contents.


    Yes, that's the nasty part. Tim's method works if you can use explicit
    width settings and table-layout: fixed. But that means the layout is
    rigid. And fixed layout implies that cell content may get truncated.

    I suppose we could have two tables so that initially they default
    table-layout to auto, and then you use JavaScript to get the allocated
    widths of columns, set the same widths to the columns of the first
    table, and set table-layout: fixed on both tables. Wait... some header
    cells might have more content than data cells in the same column, so I
    guess you would need to have a copy of the header row(s) in the second
    table initially but delete it after you have fixed the column widths.

    This sounds so simple that I wonder whether there's some trap here.
    Beoynd the problem that the columns would not match when JavaScript is
    disabled, of course. (Perhaps you should have just a single table
    initially, so the fallback would be a simple table with no scrollable
    body. Then you would split it into two tables in JavaScript.)

    --
    Yucca, http://www.cs.tut.fi/~jkorpela/
     
    Jukka K. Korpela, Nov 1, 2013
    #6
  7. JJ

    Tim Streater Guest

    In article <152i6qdaqzb1q$.ancm9i16ww61$>, JJ
    <> wrote:

    > On Thu, 31 Oct 2013 17:47:52 +0000, Tim Streater wrote:
    > > The only way I found to do it is to have two tables. With suitable CSS
    > > it looks like one table. The upper one has just the one row, obviously.

    >
    > I tried that once, but the header table column widths won't match/align with
    > the data table.
    >
    > Even though my table width is fixed, there are at least two columns whose
    > width must be variable depending on their cells' contents.


    Yes. In my case I use javascript to set the column widths in both
    tables, and I use overflow: hidden and text-overflow: ellipsis to deal
    with the content.

    --
    Tim

    "That excessive bail ought not to be required, nor excessive fines imposed,
    nor cruel and unusual punishments inflicted" -- Bill of Rights 1689
     
    Tim Streater, Nov 1, 2013
    #7
  8. JJ

    dorayme Guest

    In article <1ldcuun67k9wb$>,
    JJ <> wrote:

    > On Fri, 01 Nov 2013 10:19:39 +1100, dorayme wrote:
    > > Take a look at
    > >
    > > <http://pics.cssbakery.com/treats/scrollingtable/tableTest6.php>
    > >
    > > If it is sort of thing you want, look at the source, or see through
    > >
    > > <http://www.cssbakery.com/2010/12/css-scrolling-tables-with-fixed.html>

    >
    > Sorry I forgot to mention that, my table has at least two columns whose
    > width must be variable depending on their cells' contents. The table width
    > is fixed.
    >


    Perhaps you can supply - apart from a non-scrolling header - an
    example that demonstrates the criteria you have mentioned. Your
    example in your opening post didn't seem to fit what you wanted (apart
    from the problem you posted about).

    * A fixed width table (like presumably styled to be table {width:
    600px;})

    * Your "data1 col2" and "this one always in one line. fixed width" and
    the cell that has "this column can be multiple lines. also variable
    width" actually varying.

    I mention because if you supply something that works exactly how you
    want it except for the header scrolling away, maybe someone can
    suggest an actual solution for you (rather that a bit of vague hand
    waving in some direction which might fall foul of some other
    requirement you have.

    > The examples in that pages use fixed width for all columns. But maybe I
    > could use them later. Thanks.


    --
    dorayme
     
    dorayme, Nov 1, 2013
    #8
  9. JJ

    Ben C Guest

    On 2013-11-01, Jukka K. Korpela <> wrote:
    > 2013-11-01 7:17, JJ wrote:
    >
    >> On Thu, 31 Oct 2013 17:47:52 +0000, Tim Streater wrote:
    >>> The only way I found to do it is to have two tables. With suitable CSS
    >>> it looks like one table. The upper one has just the one row, obviously.

    >>
    >> I tried that once, but the header table column widths won't match/align with
    >> the data table.
    >>
    >> Even though my table width is fixed, there are at least two columns whose
    >> width must be variable depending on their cells' contents.

    >
    > Yes, that's the nasty part. Tim's method works if you can use explicit
    > width settings and table-layout: fixed. But that means the layout is
    > rigid. And fixed layout implies that cell content may get truncated.
    >
    > I suppose we could have two tables so that initially they default
    > table-layout to auto, and then you use JavaScript to get the allocated
    > widths of columns, set the same widths to the columns of the first
    > table, and set table-layout: fixed on both tables.


    You could use visibility: hidden and position: relative to hide the
    headings row on the second table, while leaving the headings in there so
    that the column widths are not affected (borrowing an idea from the CSS
    "solution" below).

    > Wait... some header cells might have more content than data cells in
    > the same column, so I guess you would need to have a copy of the
    > header row(s) in the second table initially but delete it after you
    > have fixed the column widths.


    Yes. You would put the whole table in the markup as normal. Then the
    JavaScript would come along, read the column widths of the headings row,
    and use them to make the "headings" table, and fix everything up.

    This would work quite well because if JavaScript was turned off or
    didn't work you'd just have the normal table.

    It is possible to avoid JavaScript if you don't mind just repeating the
    whole table twice and relying on CSS.

    The strategy is to put the first table in an overflow:hidden div so you
    can only see the top row, and the rest of it in a scrollable one (see
    below).

    <style type="text/css">
    div.show_head
    {
    height: 40px;
    overflow: hidden;
    }
    thead { height: 40px; }

    div.show_head table tbody { visibility: hidden; }
    div.show_body table thead { visibility: hidden; }

    div.show_body
    {
    height: 500px;
    overflow: scroll;
    }

    div.show_body table
    {
    position: relative;
    top: -40px;
    }
    </style>

    ...

    <div class="show_head">
    <table>
    <thead>

    ...

    </thead>
    <tbody>

    ...

    </tbody>
    </table>
    </div>
    <div class="show_body">
    <table>
    <thead>

    ...

    </thead>
    <tbody>

    ...

    </tbody>
    </table>
    </div>
     
    Ben C, Nov 5, 2013
    #9
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. VijayRama
    Replies:
    2
    Views:
    2,408
    Gregory A. Beamer
    Oct 12, 2009
  2. Leo J. Hart IV
    Replies:
    5
    Views:
    157
    Brett Merkey
    Feb 10, 2004
  3. Mel
    Replies:
    2
    Views:
    212
    Thomas 'PointedEars' Lahn
    Jul 10, 2004
  4. Matt Kruse
    Replies:
    10
    Views:
    384
    Richard Cornford
    Sep 16, 2005
  5. Cruelemort

    Sticky table columns

    Cruelemort, May 2, 2007, in forum: Javascript
    Replies:
    3
    Views:
    160
    Cruelemort
    May 3, 2007
Loading...

Share This Page