简体   繁体   中英

Is there a css3 way to fix a <thead> on the y-axis, let it scroll on the x-axis?

This has been asked a zillion times: , , and just on SO. 只是在SO上。 Yet there's no real good answer that I can find.

<recap> Often I have tables that are vertically much deeper than the viewport. I'd like to be able to scroll the table's <tbody> while its <thead> remains fixed and visible. Some of these tables are also much wider than the viewport. Here I want the table's <thead> to scroll horizontally.

To get the effect, I have dozens of lines of JS, including setInterval( ) calls to check scrollLeft and scrollTop , so that I can reposition a copy of <thead> 1 . It works but it's a huge, ungainly, frail and unmaintainable pain in the ass.</recap>

Question: Is there some straightforward css3 way, existent or emerging or proposed, that I can use to get aa table's <thead> and <tbody> to scroll horizontally and vertically, yet independently of each other? Thanks!


1 Why setInterval( ) ? Because IE doesn't uniformly deliver onScroll events, you silly; everybody knows that!

I ended up modeling the "solution" on the suggestion of @Naveed Ahmad. I put the data part of the table in a <tbody>; and made a fake <thead> that I filled in at onLoad time by referring to the widths and offsets of the <td>s in the first table row, like this:

function position_col_heads ( ) {
  // get all the TD child elements from the first row
  var tds = main_tbody.children[0].getElementsByTagName('TD'); 
  for ( var i = 0; i < tds.length; ++i ) {
    thead.children[i].style.left =
      parseFloat( tds[i].offsetLeft ) + 'px';
    thead.children[i].style.width = 
      parseFloat( tds[i].scrollWidth ) + 'px';
  }
}

This works more or less OK . 或多或少都可以。

a dirty way would be to put the header table in a separate div like:

<div class="header">
<table>
    <thead><tr><td>#</td><td>v</td></tr></thead>
</table>
</div>

Then body in the another div like:

<div class="body">
    <table>
        <tbody>
            <tr><td>1</td><td>a</td></tr>
            <tr><td>1</td><td>a</td></tr>
            <tr><td>1</td><td>a</td></tr>
            <tr><td>1</td><td>a</td></tr>
            <tr><td>1</td><td>a</td></tr>         
    </tbody>
</table> 
</div>

Now you can give a fixed height to body div and set oveflow to auto . like:

table{border:0px solid #ccc;height:30px;}
table tr td{border:1px solid #ccc;padding:5px;}
div.body{height:70px;overflow:auto;border-bottom:1px solid #ccc;}

here is a working example I did in jsfiddle

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM