Creating a Sticky Header for Tables with CSS and JavaScript (JQuery)

While there are many examples of sticky headers available, my experience using a JavaScript approach has been successful for smaller tables with 100-150 rows. However, when dealing with larger tables containing 600-700+ rows, the script tends to slow down significantly and may take 10-15 seconds to load the results.

This delay in loading is not ideal from a user-friendly perspective, especially considering how impatient customers can be.

I suspect the reason for the slower performance is due to the sheer amount of data being handled. The script essentially clones the table, removes the header on one clone and the body on the other, allowing for a scrolling feature with a sticky header.

In light of this, my question is: what is the most efficient way, in terms of speed, to create a table with a sticky header? Is it possible to achieve this effect using CSS alone, eliminating the need for JavaScript?

Thank you.

Answer №1

The key lies in the arrangement of div elements inside the th tags, along with the wrapper div.container

Essentially, the sticky header effect is achieved by positioning the divs inside the th tags absolutely, while the scrolling functionality is assigned to the wrapper.

Although not a universal solution, this method can work well for simpler cases.

var rows = $('tbody tr');
for (var i = 0; i < 300; i++) {
rows.clone().appendTo($('tbody'));
}
html, body{
  margin:0;
  padding:0;
  height:100%;
}
section {
  position: relative;
  border: 1px solid #000;
  padding-top: 37px;
  background: #500;
}
section.positioned {
  position: absolute;
  top:100px;
  left:100px;
  width:800px;
  box-shadow: 0 0 15px #333;
}
.container {
  overflow-y: auto;
  height: 200px;
}
table {
  border-spacing: 0;
  width:100%;
}
td + td {
  border-left:1px solid #eee;
}
td, th {
  border-bottom:1px solid #eee;
  background: #ddd;
  color: #000;
  padding: 10px 25px;
}
th {
  height: 0;
  line-height: 0;
  padding-top: 0;
  padding-bottom: 0;
  color: transparent;
  border: none;
  white-space: nowrap;
}
th div{
  position: absolute;
  background: transparent;
  color: #fff;
  padding: 9px 25px;
  top: 0;
  margin-left: -25px;
  line-height: normal;
  border-left: 1px solid #800;
}
th:first-child div{
  border: none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<section class="">
  <div class="container">
    <table>
      <thead>
        <tr class="header">
          <th>
            Table attribute name
            <div>Table attribute name</div>
          </th>
          <th>
            Value
            <div>Value</div>
          </th>
          <th>
            Description
            <div>Description</div>
          </th>
        </tr>
      </thead>
      <tbody>
        <tr>
          <td>align</td>
          <td>left, center, right</td>
          <td>Not supported in HTML5. Deprecated in HTML 4.01. Specifies the alignment of a table according to surrounding text</td>
        </tr>
        <tr>
          <td>bgcolor</td>
          <td>rgb(x,x,x), #xxxxxx, colorname</td>
          <td>Not supported in HTML5. Deprecated in HTML 4.01. Specifies the background color for a table</td>
        </tr>
        <tr>
          <td>border</td>
          <td>1,""</td>
          <td>Specifies whether the table cells should have borders or not</td>
        </tr>
        <tr>
          <td>cellpadding</td>
          <td>pixels</td>
          <td>Not supported in HTML5. Specifies the space between the cell wall and the cell content</td>
        </tr>
        <tr>
          <td>cellspacing</td>
          <td>pixels</td>
          <td>Not supported in HTML5. Specifies the space between cells</td>
        </tr>
        <tr>
          <td>frame</td>
          <td>void, above, below, hsides, lhs, rhs, vsides, box, border</td>
          <td>Not supported in HTML5. Specifies which parts of the outside borders that should be visible</td>
        </tr>
        <tr>
          <td>rules</td>
          <td>none, groups, rows, cols, all</td>
          <td>Not supported in HTML5. Specifies which parts of the inside borders that should be visible</td>
        </tr>
        <tr>
          <td>summary</td>
          <td>text</td>
          <td>Not supported in HTML5. Specifies a summary of the content of a table</td>
        </tr>
        <tr>
          <td>width</td>
          <td>pixels, %</td>
          <td>Not supported in HTML5. Specifies the width of a table</td>
        </tr>
      </tbody>
    </table>
  </div>
</section>

I came across this fiddle from an unknown creator, here is the source link I found: (I added the repetition part)

https://jsfiddle.net/dPixie/byB9d/3/light/

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Navigation drop-down extending beyond the boundaries of the screen

On the right side of react-bootstrap's Navbar, there is a Dropdown menu: <Nav className="container-fluid justify-content-end"> <NavDropdown alignRight title="Dropdown" flip> <NavDropdown.Item href="#action ...

Running queries in a loop is not functional within node-firebird

When running multiple select queries in a loop, I encountered an issue that puzzled me. For simplicity, let's take a look at the code snippet below: var Firebird = require('node-firebird'); Firebird.attach({database: 'TEST'}, (e ...

Ways to rerun a Vuex Getter

Perhaps there's a misunderstanding on my part regarding the concept of a getter in Vuex. Let's consider a scenario where I have a getter that fetches the size of a DOM element, such as a div. The code would look something like this: const gette ...

Monitor changes in the clientWidth property of this.$el in Vue

Can we monitor changes in the clientWidth of a component's element (this.$el.clientWidth)? Here's an example: this.$watch( () => { return this.$el.clientWidth; }, (newWidth, oldWidth) => { c ...

Having an alignment problem with my logo and inline block navigation due to CSS coding

Embracing the world of CSS as a newbie has been an exciting journey. However, I've encountered a hurdle in my coding process and could use some expert guidance. In my website layout, I'm aiming to position my logo on the left side of the navigat ...

Angular and the dynamic transformation of the DOM tree through an array

I am using an HTML component within Angular. The template code looks like this: <tr ng-repeat="item in documentList track by $index"> <td>{{item.TYPE}}</td> <td>{{item.DATE_CRE ...

Strategies for transferring a dynamic variable to a parent window's form in JavaScript?

What is the best way to use a changing parameter name when accessing a variable? For instance: opener.document.form.namerow_3.value = this.cells[0].innerHTML; opener.window.form.{varaible}.value=this.cells[0].innerHTML; In this scenario, the parameter ...

Angular having issues with Bootstrap navbar dropdown functionality

I've encountered an issue with the bootstrap navbar in Angular where I can't get the dropdown menu to load. The bootstrap scripts are properly linked in the angular.json file, and I'm struggling to identify the root cause of the problem. Int ...

Can an HTML file be transformed into a QR code format?

I have a unique challenge where I need to turn an HTML file into a QR code that, when scanned by a user, will load up a website (note: the website does not have a domain and is just an HTML file). The goal is for the QR code scanner to interpret it as a we ...

Input field in a tableview

I have a ListView that features a dropdown, 4 textboxes and buttons. My goal is to only show the fourth textbox (enclosed in a span) when the dropdown value in each row of the ListView is set to 2. For instance, if there are 5 records being displayed in t ...

Performing numerous asynchronous MongoDB queries in Node.js

Is there a better way to write multiple queries in succession? For example: Space.findOne({ _id: id }, function(err, space) { User.findOne({ user_id: userid }, function(err, user) { res.json({ space: space, user: user}); }); }); It can g ...

Using Vue/Nuxt.js to compute the cumulative sum of hierarchically structured JSON data

When using Nuxt async data, I am retrieving a JSON object that includes a nested array in the following structure: "topic_list": { "topics": [ { "id": 9148, "title": "A", "views": 12 }, { "id": 3228, ...

The JavaScript copy function is no longer functioning properly following the update to the href link

I have implemented a function for copying to clipboard as shown below: function CopyToClipboard(containerid) { if (document.selection) { var range = document.body.createTextRange(); range.moveToElementText(document.getElementById(containerid)); ...

Unacceptable response from AJAX function

My goal is to extract specific information from this ajax function, such as the thumbnail image and the owner of the image. It seems like the function is not recognizing data.images[i].imgurl and data.images[i].username. AJAX call in ajax.php require_o ...

The column with a class of col-md-3 is not rendering properly

The design shown below was created in photoshop utilizing a 12 grid system: https://i.sstatic.net/MSGHc.jpg I am attempting to replicate this layout using bootstrap with class='col-md-3' for each input. However, when I do this, they appear next ...

Guide to setting up the redux-form with initial values pulled from the store

I am looking to preload a Redux Form with values obtained from the store. Currently, I can populate the redux form with data directly from the reducer. However, when submitting the form, it only accepts data for clickable elements to generate the payload. ...

Locating a specific element within an array using AngularJS / Conditional statement within ng-class

I am working on a feature where I need to identify the current user in a list of all users. Below is an example of what my code currently looks like. <div class='user' ng-repeat='user in users'> <span class='name'& ...

Performing synchronized execution in a node.js application by utilizing the 'readline' package

Struggling with the asynchronous nature of node.js, despite hours spent on callbacks and researching. I have a program that reads lines from a file using the readline module in node, passing data to async functions within the program. The goal is to proces ...

What is the correct way to employ async/await in combination with Array.filter within a React application?

I'm currently in the process of developing a basic currency converter using React and Typescript. Below is a snippet of my component code: const App = () => { const [countries, setCountries] = useState<Array<CountriesProps>>([]) co ...

Resizing the carousel container dimensions in Angular-UI-Bootstrap

For my project, I have implemented Angular-UI-Bootstrap in the carousel feature. The challenge I am facing is that I need to display images of varying dimensions, some larger and some smaller than the container itself. How can I adjust the size of the caro ...