Header remains fixed when scrolling

Is there a way to make the header of a Bootstrap table fixed when scrolling, while also adjusting the width of each column based on the content within it? I want the column headers to match the width of the row with the most text. Setting the position of the header to fixed currently prevents the width from changing based on content.

I am looking for a solution that allows the column widths to be dynamically adjusted according to the longest value in that specific column, whether it's a header title or cell content. Ideally, this calculation would be applied to the header column width automatically without manually setting fixed values per column.

Here is my attempt using Angular and a jsfiddle link to demonstrate the issue: JsFiddle. The columns are not aligned properly due to fixed positioning of the header rows.

HTML code:

<div class="col-md-12 tableDiv"  >
 <table class="table table-striped" >
  <thead class="table-bordered">
    <tr>
      <th>Column1</th>
      <th>Column2</th>
      <th>Column3</th>
      <th>Column4</th>
      <th>Column5</th>
      <th>Column6</th>

    </tr>
  </thead>
  <tbody >
    <tr>
      <td > FIRST</td>
      <td >asdasdfasf</td>
      <td >fsdf</td>
      <td>sdfsfd</td>
      <td>sdfs</td>
      <td>fsdfsdf</td>
    </tr>
        <tr>
      <td > asdf</td>
      <td >asdfa</td>
      <td >fsdf</td>
      <td>sdfsfd</td>
      <td>sdfs</td>
      <td>fsdfsdf</td>
    </tr>
        <tr>
      <td > asdf</td>
      <td >asdfa</td>
      <td >fsdf</td>
      <td>sdfsfd</td>
      <td>sdfs</td>
      <td>fsdfsdf</td>
    </tr>
  </tbody>
</table>
  </div>
<div>
</div>

CSS:

.table-bordered tr {
  position: fixed;
   z-index:1;
  top: 50px;
  background: #fff;
 }

Answer №1

If performance is not a concern and you're okay with forgoing borders in the header (as borders will not be affected by CSS transforms), there's a solution using CSS3 transforms. The idea is to sync the window scroll position with a transform applied to the header, keeping it unfixed while maintaining its original widths:

let header = document.querySelector(".table-bordered");
let body = document.body;

function setTranslate(element, value) {
    let style = `translateY(${value}px)`;
    element.style.oTransform = style;
    element.style.MozTransform = style;
    element.style.WebkitTransform = style;
    element.style.transform = style;
}

window.onscroll = () => {
    setTranslate(header, window.scrollY);
};

Check out this working example on jsFiddle

The drawback of this approach is that you'll need to update the header styles on every scroll event, impacting performance. Another solution involves creating two separate tables—one for the header and one for the body—and implementing a function that sets the header widths based on the body widths. This way, you can set the table's position property to fixed and call this function whenever you need to resize the table or refresh its sizes. Here's how you can achieve this:

let header = document.querySelector(".table-header");
let body = document.querySelector(".table-body");
let htds = header.querySelectorAll("th");
let btds = body.querySelectorAll("tbody tr:first-child td");

function fixHeaderWidths() {
  header.style.width = `${body.offsetWidth}px`;
  Array.prototype.forEach.call(htds, (td, index) => {
    td.style.width = `${btds[index].offsetWidth}px`;
  });
  body.style.top = "";
  let top = (header.getBoundingClientRect()).bottom - (btds[0].getBoundingClientRect()).top;
  body.style.top = `${top}px`;
}

fixHeaderWidths();

window.onresize = fixHeaderWidths;
.table-header {
  background: white;
  position: fixed;
  table-layout: fixed;
  z-index: 1;
}

.table-body {
  position: relative;
}

.table-body thead {
  visibility: hidden;
}

.tableDiv {
  margin-top: 40px
}
<link href="https://maxcdn.bootstrapcdn.com/bootswatch/3.3.7/flatly/bootstrap.min.css" rel="stylesheet" />
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-alpha.2/css/bootstrap.min.css" rel="stylesheet" />
<div class="col-md-12 tableDiv">
  <table class="table-header table table-stripedcf table-bordered">
    <thead>
      <tr>
        <th>Column1</th>
        <th>Column2</th>
        <th>Column3</th>
        <th>Column4</th>
        <th>Column5</th>
        <th>Column6</th>
      </tr>
    </thead>
  </table>
  <table class="table-body table table-stripedcf table-bordered">
    <thead>
      <tr>
        <th>Column1</th>
        <th>Column2</th>
        <th>Column3</th>
        <th>Column4</th>
        <th>Column5</th>
        <th>Column6</th>
      </tr>
    </thead>
    <tbody>
     <!-- Table body content here -->
    </tbody>
  </table>
</div>

If you prefer not to use jQuery, avoid including the Bootstrap script file (which requires jQuery) in your project. You can consider using a library like bootstrap.native instead.

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

Adding multiple styles using ngStyle is currently not possible

When using ngStyle to add height and width styles to an img element, I encountered a strange issue: <img class="image-full-view" [ngStyle]="{'height': selectedImage.heightSize, 'width': selectedImage.widthSize}" [src]="selectedImage ...

Utilizing REST-API with Angular 2 and Electron

I am encountering an issue with my Electron App that utilizes Angular 2. I had to make a modification from <base href="/"> to <base href="./">, which is a relative path within the file system, in order to make it function properly. However, thi ...

Error occurs when Protractor end-to-end tests encounter a problem with browser.executeAsyncScript

I encountered an error while attempting to implement e2e testing for our application. My initial test case failed with the following error message: Failed: Error while running testForAngular: javascript error: Unexpected identifier JavaScript stack: ...

"Exploring the insertion of a line break within the modal body of an Angular application

Is it possible to create a modal for error messages with multilined body messages without altering the modal template? Any assistance would be greatly appreciated. <div class="modal-body" > <p *ngIf="!_isTranslatable">{{_modalBody}}</p&g ...

Executing a function in Angular depending on the values emitted by two distinct observables

As someone who is relatively new to Angular (6 months), I am facing a challenge with my code. Currently, I have two observables that are working independently of each other: this.siteService.siteChanged$ .pipe(takeUntil(this.disconnect$)) .subscribe(_ ...

Encountering issues accessing / Error within MEAN stack application

I recently completed the Heroku tutorial, which you can find here. I followed all the steps but did not deploy to the Heroku server and instead worked on my localhost. However, when I tried to access my application using localhost port 8080, I encountered ...

The amazing magnific popup boasts a pair of close buttons

I recently started working on integrating a front-end HTML theme with a back-end Laravel app. Oddly enough, I noticed that the popup modal is displaying two close x buttons instead of just one. Despite my efforts, I have been unable to pinpoint what exactl ...

Display a fresh <p> tag when the condition in the if-statement is met

If you are looking for a questionnaire, check out this one. Now, I am interested in creating if-statements using HTML/CSS/jQuery to achieve the following scenario: Initially, only Question 1 will be visible. When the input matches a certain value like X, ...

Is there a way to access the value of a public variable within the @input decorator of a function type?

I am working on a dropdown component that utilizes the @Input decorator to define a function with arguments, returning a boolean value. dropdown-abstract.component.ts @Input() public itemDisabled: (itemArgs: { dataItem: any; index: number }) => boo ...

Error Panel Style Message Format:

Currently, I am utilizing PrimeFaces, which utilizes JQuery UI not just for its functionality but also for its CSS styling framework. The issue I am facing stems from my lack of understanding about the CSS framework, as I have been unable to locate any exa ...

Conceal API request details on the network tab

I am currently working on an application built with Angular 10. I was wondering if there is a way to encrypt the request parameters or hide sensitive data. The issue is that anyone who can view the URL has access to both the Bearer token and the request pa ...

Pressing the button will allow you to select and copy the text within the

I am looking to incorporate a mock-chat feature into my website. The concept is to type something on the website, then click a button next to it which will move the text to a frame above. I attempted this using a textarea and even found a code for selectin ...

What is the best way to add two hyperlinks within a single tab of a Bootstrap navigation menu?

I attempted to place two links in one tab, but I was unsuccessful. Here is my navbar code: <!DOCTYPE html> <html lang="eng"> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scal ...

Utilizing Typescript to implement an interface's properties

After declaring an interface as shown below interface Base { required: string; } I proceeded to implement the interface in a class like this class MyClass implements Base{ method(): void { console.log(this.required); } } However, I ...

Why isn't Google Map showing up in my HTML <div> section?

I am currently working on a web page that consists of two containers. The mainmapdiv container covers the entire page, while the mainhomediv container is positioned on top of the mainmapdiv. My goal is to hide the mainhomediv container and show a Google Ma ...

What are some ways I can adjust line-height without changing the height of the cursor?

When working in a contenteditable div, I am utilizing line-height to create some spacing between lines. The following example illustrates the issue: <div style="padding: 50px; width: 90px; line-height: 2em;" contenteditable="true"> line height lin ...

What could be causing the appearance of two vertical scrollbars after transitioning from ReactJS to NextJS?

During the development of a project in plain ReactJS, I added these two lines to my index.css: overflow-y: scroll; overflow-x: hidden; The purpose was to ensure a vertical scrollbar always appeared without causing a horizontal scrollbar even when there wa ...

Tips for getting Angular Ivy and Angular Universal up and running together

I'm encountering a problem while attempting to incorporate Ivy + Angular Universal into my project. This issue only arises when I enable Ivy mode in Angular (disabling it allows me to successfully build my application). Below are the steps to replic ...

Styles applied in the child component will have a cascading effect on the entire webpage

My webpage is divided into two parts: child1 and child2. Page Hierarchy: Parent Child1 Child2 Here are the CSS styles included in the page: Child1 -> z-index: 1 Child2 -> z-index: 2 What I want to achieve is to add a backdrop to the entire ...

Assistance needed: How to add extra information when registering a user on JHipster?

After diligently following this tutorial to add more information about the user, I encountered an issue while trying to include an input field in the register.component.html. As soon as I added the ngModel directive, the page stopped functioning properly. ...