Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Sticky headers not maintaining width when scrolling

I have some table headers which I planned on making sticky (fixed) as the user scrolls down the page, but they currently shrink when the sticky is activated, I would like them to inherit the widths of the headers, but they shrink to the size of the text at the moment. My JS:

$(document).ready(function() {  
var stickyNavTop = $('.th').offset().top;

SOLUTION:

 $(".th th").each(function(){$(this).width($(this).width());});
 $('.th').width($('.th').width());

var stickyNav = function(){  
var scrollTop = $(window).scrollTop();  

if (scrollTop > stickyNavTop) {   
    $('.th').addClass('sticky');  
} else {  
    $('.th').removeClass('sticky');   
}  
};  

stickyNav();  

$(window).scroll(function() {  
    stickyNav();  
});  
});  

My HTML:

<table class="mGrid" cellspacing="0" rules="all" border="1" id="1"
style="width:98%;border-collapse:collapse;">
  <tr class="th">
    <th scope="col">Membership No.</th>
    <th scope="col">Surname</th>
    <th scope="col">Other Name(s)</th>
  </tr>
  <tr>
    <td>
      <div id="2" class="formInput">
        <label for="2">Membership No.</label>
        <input name="2" type="text" value="AH6973" id="2"
        class="required" style="width:60px;" />
      </div>
    </td>
    <td>
      <div id="3" class="formInput">
        <label for="3">Surname</label>
        <input name="3" type="text" value="CARTER" id="3"
        style="width:100px;" />
      </div>
    </td>
    <td>
      <div id="4" class="formInput">
        <label for="4">Other Name(s)</label>
        <input name="4" type="text" value="RAYMOND" id="4"
        style="width:150px;" />
      </div>
    </td>
  </tr>
</table>

my CSS:

.sticky {
    position: fixed;
    width: 100%;
    top: 0;
    z-index: 100;
    border-top: 0;
    color: #fff !important;
    background: #666;
    border-left: solid 1px #525252;
    font-size: 1.0em;
}

(This is modelled to be the same as the header style, it's just the width shrinks to fit the width of the text at the moment. I tried to edit the header style but it's apparently read-only "'HeaderStyle' property is read-only and cannot be set."

like image 970
ECH Avatar asked Feb 14 '14 14:02

ECH


People also ask

How do I make my table header fixed while scrolling?

By setting postion: sticky and top: 0, we can create a fixed header on a scroll in HTML tables.

How do I make my header follow the scroll?

If your header row locates on the top of the worksheet, please click View > Freeze Panes > Freeze Top Rows directly. See screenshot. Now the header row is frozen. And it will follow the worksheet up and down while scrolling the worksheet.

How do you keep the header static on top when scrolling?

Answer: Use CSS fixed positioning You can easily create sticky or fixed header and footer using the CSS fixed positioning. Simply apply the CSS position property with the value fixed in combination with the top and bottom property to place the element on the top or bottom of the viewport accordingly.


2 Answers

Just add this line before your function definition:

$('th').width($('th').width());

Full JavaScript code:

$(document).ready(function() {  
    var stickyNavTop = $('.th').offset().top;  

    $('th').width($('th').width());

    var stickyNav = function(){  
        var scrollTop = $(window).scrollTop();
        if (scrollTop > stickyNavTop) {   
            $('.th').addClass('sticky');  
        } else {  
            $('.th').removeClass('sticky');   
        }  
    };  

    stickyNav();  

    $(window).scroll(function() {  
        stickyNav();  
    });  
});
like image 158
Matt Avatar answered Oct 25 '22 05:10

Matt


here is a common solution, it auto detects each sub-element's width and height and reflect when scrolling, it is something like following:

var $this = $(this),
      top = $this.offset().top,
      left = $this.offset().left,
      width = $this.width(),
      height = $this.height(),
      widthArr = [],
      heightArr = [];
    $this.find("*").each(function(i, e) {
      widthArr.push($(this).width());
      heightArr.push($(this).height());
    });

$(window).scroll(function() {
  if($(window).scrollTop() >= top) {
    $this.css({
      position: "fixed",
      top: 0,
      left: left,
      "z-index": 100,
      width: width,
      height: height
    });

    $this.find("*").each(function(i, e) {
      $(this).width(widthArr[i]);
      $(this).height(heightArr[i]);
    });
  } else {
      // to be implemented
  }
});
like image 44
coderz Avatar answered Oct 25 '22 07:10

coderz