2

I have seen countless solutions for a table with frozen columns that is scroll-able for example:

how do I create an HTML table with fixed/frozen left column and scrollable body?

but what I am after is for the scroll to be on the page (body) rather than the table or a container surrounding the table.

Edit- its just a basic HTML table that is to large to display altogether so has a horizontal scroll. The reason for having the horizontal scroll on the body of the page is so that users do not have to scroll to the bottom of the the page before being able to horizontally scroll.

        .stickyCol2 tr th:nth-child(1),
        .stickyCol2 tr td:nth-child(1){    
          position: absolute;
          width: 50px;
          left: 15px;
          top: auto;  
          background-color: #fff;
        }

        .stickyCol2 tr th:nth-child(2),
        .stickyCol2 tr td:nth-child(2){    
          position: absolute;
          width: 60px;
          left: 86px;
          top: auto;  
          background-color: #fff;
        }
 <div class="stickyCol2">
            <table>
               <thead>
                  <tr>
                     <th>item 1</th>
                     <th>item 2</th>
                     <th>item 3</th>
                 </tr>
              </thead>
              <tbody>        
                 <tr>
                   <td>item 1</td>
                   <td>item 2</td>
                   <td>item 3</td>
                </tr>
             </tbody>
         </table>
         </div>

js fiddle https://jsfiddle.net/uthz6c24/1/

NPE
  • 429
  • 2
  • 16
  • 1
    Please include your html and css code so we could assist u better – Amiratak88 Mar 19 '19 at 15:57
  • Just don't limit the table to 100% width and then your body will scroll (it will also mean your body will be a lot wider but it's not very clear what you are wanting). Please take a [tour](https://stackoverflow.com/tour) of the [help centre](http://stackoverflow.com/help) to see [how to ask a good question](http://stackoverflow.com/help/how-to-ask). – Pete Mar 19 '19 at 16:06
  • But it sounds like what you're after is not doable - if you want a scrollbar on your body, your table needs to be wider than your body. Perhaps you could use js to clone the first columns and put it in a position fixed div on the left but then you have the problem of needing to loop all the cells and make sure they are the correct height to match up with the main table and also match the vertical scroll of the cloned column with the main table. One question I would ask is why move the scroll to the body - it's really bad UX – Pete Mar 19 '19 at 16:12
  • #Amiratak88 I've added the code there are a lot more columns that in my example. – Paula lyon-lee Mar 19 '19 at 16:27
  • #pete I have not limited the table to 100%, I can surround it in a container and have the scroll bar there and the first two columns are frozen nicely but this then means the user has to scroll to the bottom of the page before being able to scroll across to see the information. thats what im trying to avoid. my table is a lot wider than the body it has over 30 columns in it, my example only shows the code im using. I think you might be right about it not being possible with CSS and having to use JavaScript instead – Paula lyon-lee Mar 19 '19 at 16:28
  • #pete only reason to move the scroll to the body is so that the user does not have to scroll down to the bottom of a very long table before being able to access the horizontal scroll. If it where up to me I would not be doing it like this. – Paula lyon-lee Mar 19 '19 at 17:02
  • Does it need to be a table? You could perfectly manage this in css grid. Simple create a parent container with fixed header and first column and set `html {overflow: hidden}`. Next create a div to contain all your cells and make it a css grid. It will automaticly create an inside scrollbar when needed. – TVBZ Mar 19 '19 at 17:34
  • #TVBZ unfortunately yes it does need to be a table which is why its such a headache. – Paula lyon-lee Mar 20 '19 at 10:11

1 Answers1

0

Below is some working code along with explanations you can use to fine-tune towards your solution.

The main idea is that you wrap the contents of the columns you want fixed inside span elements, which you make fixed on the left side of the screen (using CSS) and give them width equal to their content (I used just one column in my code).

var cellWidth=$('th:first-child').width();
$('th:first-child, td:first-child').each(function() {
  $(this).wrapInner('<span></span>');
  $(this).find('span').attr('style', 'width:'+cellWidth+'px;');
})

You add a margin-left to the table equal to the total width of the fixed columns (which you will have to calculate using Javascript if you must), so that the fixed columns don't overlap the scrollable cell content.

$('table').attr('style', 'margin-left:'+cellWidth+'px;');

After that, using jQuery, you can detect the scroll of the body (or for an overflowing container, works the same) and apply a negative transform:translateY property on the spans.

$(window).on('scroll', function() {
  var scr = -$(this).scrollTop();
  console.log(scr);
  $('th:first-child span, td:first-child span').css('transform', 'translateY(' + scr + 'px)');
})

Here is a working fiddle, hope it gives you the initial boost. https://jsfiddle.net/scooterlord/ndxjg1b0/21/

scooterlord
  • 15,124
  • 11
  • 49
  • 68