Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.


stickyHeader.js is a script I wrote to make table headers stick to the top of the viewport of a browser when scrolling down them. This makes it easier to understand the data. This presentation walks you through how I built it.

The code is available at

  • Be the first to comment


  1. 1. stickyHeader.js
  2. 2. About Russell Heimlich ★ Sole developer at the Pew Research Center ★ Creator of ★ Frontend and Backend Developer ★ @kingkool68
  3. 3. What Does stickyHeader.js Do?
  4. 4. What Does stickyHeader.js Do?★ Table headers stick to the top of the viewport when you scroll down data tables★ Long data tables become easier to read★ Has nothing to do with the Sticky Footer CSS technique
  5. 5. Inspired By Spreadsheets
  6. 6.’s Comparator
  7. 7.’s Comparator
  8. 8. stickyHeader.js★ Written by me sometime in 2008 while at★ Just include the script and 2 CSS rules★ Works on any table with class=”stickyHeader”★ 46 lines (uncompressed)
  9. 9. I Thought I Could Just Use CSS...thead { position:fixed;}
  10. 10. NOPE!(but this CSS works better on today’s browsers)
  11. 11. Plan B★ Create a DIV after the table★ Clone the table header and insert it into the DIV★ Position the DIV using CSS★ Show/hide the DIV as needed using JavaScript
  12. 12. Code Time!
  13. 13. Wait For The Document To Load$(document).ready(function () { ... the rest of the code goes here ...}
  14. 14. Find All stickyHeader Tablesvar tables = $(table.stickyHeader);tables.each(function(i){ ... the rest of the code goes here ...});
  15. 15. Clone The <thead>var table = tables[i];var theadClone = $(table).find(thead).clone(true);var stickyHeader =$(<div></div>).addClass(stickyHeader hide);
  16. 16. .clone( [withDataAndEvents] )A Boolean indicating whether event handlersshould be copied along with the elements.As of jQuery 1.4, element data will be copied aswell.
  17. 17. Append the Cloned <thead>stickyHeader.append( $(<table></table) ) .find(table).append(theadClone);$(table).after(stickyHeader);
  18. 18. The HTML So Far<table class=”stickyHeader”> <thead>....</thead> ...</table><div class=”stickyHeader hide”> <table> <thead>...</thead> </table></div>
  19. 19. Back to the JavaScriptvar tableHeight = $(table).height();
  20. 20. Finding The Width Is Trickiervar tableWidth = $(table).width() +Number( $(table).css( padding-left ).replace(/px/ig,"") )+ Number( $(table).css( padding-right ).replace(/px/ig,"") )+ Number( $(table).css( border-left-width ).replace(/px/ig,"") )+ Number( $(table).css( border-right-width ).replace(/px/ig,"") );
  21. 21. Why So Complicated?★ width() doesn’t account for padding and border widths.★ Should have used outerWidth() instead.
  22. 22. Why Do We Need Table Dimensions?
  23. 23. Table Cell Shiftiness★ Table cell widths adjust based on the contents★ When we take the <thead> away from the <table> widths can change, and the illusion of the stickyHeader effect will be broken.★ We need to loop through the cells and set the width manually to fix this.
  24. 24. Now To Determine <th> Heightvar headerCells = $(table).find(thead th);var headerCellHeight =$(headerCells[0]).height();
  25. 25. Match Header Cell Widthsfor (i=0; i<headerCells.length; i++) { var headerCell = $(headerCells[i]); var cellWidth = headerCell.width(); cellWidth = cellWidth + "px"; $(stickyHeaderCells[i]).css(width, cellWidth);}
  26. 26. Does The Browser Support postion:fixed?var no_fixed_support = false;if (stickyHeader.css(position) == "absolute") { no_fixed_support = true;}
  27. 27. stickyHeader.css.hide { display:none;}div.stickyHeader { position:fixed; _position:absolute; top:0;}
  28. 28. IE6 Doesn’t Support position:fixed★ We can use CSS to determine if we’re dealing with IE6★ IE6 will be positioned using JavaScript instead
  29. 29. The Underscore “Hack”★ .property: value; - Targets IE7 and below★ _property: value; - Targets IE6 and below★ Think of it like an unofficial browser prefix
  30. 30. Determining The Cutoff Pointsvar cutoffTop = $(table).offset().top;var cutoffBottom =cutoffTop + tableHeight - headerCellHeight;
  31. 31. Show/Hide The stickyHeader On Scroll$(window).scroll(function() { var currentPosition = $(window).scrollTop(); //More Code Will Go Here!});
  32. 32. Top of the Table (446px) Top of the Viewport (627px)Bottom of the Table (6000+px)
  33. 33. If The Viewport Is Within The Cutoff Points if (currentPosition > cutoffTop && currentPosition < cutoffBottom) { stickyHeader.removeClass(hide); if (no_fixed_support) { stickyHeader.css(top, currentPosition + px); } }
  34. 34. Otherwise Hide The stickyHeaderelse { stickyHeader.addClass(hide);}
  35. 35. Notes About Styling
  36. 36. .stickyHeader Needs A Background Color★ It is an overlay after all...
  37. 37. If You Need To Get Specific/*Global table header styles */th { ... }/*Original stickyHeader table header styles */table.stickyHeader th { ... }/*Cloned stickyHeader table header styles */div.stickyHeader th { ... }
  38. 38. Other Versions★ Ported over to the 4 most popular libraries★ Prototype★ jQuery 1.3.2★ MooTools 1.2.2★ Dojo Toolkit 1.3.1
  39. 39. Thoughts On Different Libraries★ Prototype: Extends JavaScript Language★ jQuery: Makes JavaScript Easier★ MooTools: Hybrid Prototype/jQuery★ Dojo Toolkit: WTF?!?!
  40. 40. Other Things I Learned★ jQuery handles dimensions the best, other libraries made me have to write my own.★ For logging event data, use document.title instead of console.log
  41. 41. The Code Is Available★★ stickyHeader/★ Demos: stickyHeader/