CSS to position sticky table header & first 3 columns
Question
Application Type
Reactive

Hi, I am creating a table which has 50 columns. I have enabled scrolling and the requirement is to freeze the table header and first 3 columns, so that the user can navigate to all the columns with a reference to the first 3 columns. I have almost done it (based on this old post - https://www.outsystems.com/forums/discussion/65195/how-can-i-create-a-horizontal-scrollable-table-that-has-a-fixed-coloumn/)

But during the scroll, the header is not fixed for the first 3 columns. As shown below. The columns are fixed, but the header  just scrolls above just like the rows. I need the first 3 column headers also to be fixed. Attached the CSS used below. Can anyone please help in completing the CSS to make the first 3 column headers also static? Thanks in Advance!


.table-scroll-wrapper {

    overflow: auto;

    border: var(--border-size-s) solid var(--color-neutral-4);

}


.table-scroll {

    margin: 0px;

    border: none;

}


.table-scroll thead th {

  position: -webkit-sticky;

  position: sticky;

  top: 0;

}


.table-scroll tr td:first-child,

.table-scroll th:first-child {

  position: -webkit-sticky;

  position: sticky;

  width:120px;

  left: 0;

  z-index: 2;

  border-right: var(--border-size-s) solid var(--color-neutral-4);

}


.table-scroll tr td:nth-child(2),

.table-scroll th:nth-child(2) {

  position: -webkit-sticky;

  position: sticky;

  width: 120px;

  left: 110px;

  z-index: 3;

  border-right: var(--border-size-s) solid var(--color-neutral-4);

}


.table-scroll tr td:nth-child(3),

.table-scroll th:nth-child(3) {

  position: -webkit-sticky;

  position: sticky;

  left: 210px;

  z-index: 4;

  border-right: var(--border-size-s) solid var(--color-neutral-4);

}


.table-scroll tr td:last-child {

  border-right: none;

}


.phone .table-scroll tr td,

.tablet .table-scroll tr td {

  border-right: none;

}


I just made it to freeze both header as well as the first 3 columns. The magic was lying with the z-index. Since both th and tr of first 3 columns share same z-index, both were getting moved same. I created a bigger z-index for th alone and now it is working as expected. Sharing below the CSS. It is based on the solution shared in this post. The below CSS is just an extension of it. Hope this helps developers who wants to fix the table headers and columns with CSS alone. 

.table-scroll-wrapper {
    overflow: auto;
    border: var(--border-size-s) solid var(--color-neutral-4);
}

.table-scroll {
    margin: 0px;
    border: none;
}

.table-scroll thead th {
  position: -webkit-sticky;
  position: sticky;
  top: 0;
}

.table-scroll tr td:first-child,
.table-scroll th:first-child {
  position: -webkit-sticky;
  position: sticky;
  width:120px;
  left: 0;
  z-index: 2;
  border-right: var(--border-size-s) solid var(--color-neutral-4);
}

.table-scroll th:first-child {
    z-index: 4;
}

.table-scroll tr td:nth-child(2),
.table-scroll th:nth-child(2) {
  position: -webkit-sticky;
  position: sticky;
  width: 120px;
  left: 110px;
  z-index: 2;
  border-right: var(--border-size-s) solid var(--color-neutral-4);
}

.table-scroll th:nth-child(2) {
    z-index: 4;
}


.table-scroll tr td:nth-child(3),
.table-scroll th:nth-child(3) {
  position: -webkit-sticky;
  position: sticky;
  left: 210px;
  z-index: 2;
  border-right: var(--border-size-s) solid var(--color-neutral-4);
}

.table-scroll th:nth-child(3) {
    z-index: 4;
}

.table-scroll tr td:last-child {
  border-right: none;
}

.phone .table-scroll tr td,
.tablet .table-scroll tr td {
  border-right: none;
}

Thanks @Komal Kumbhar for your quick responses. It gave another way of implementing the fixed headers.


Hi Somesh,

Can you try the following CSS for fixed header along with your CSS for fixed column,

.FixedHeader 
 {
 overflow: hidden;
  background-color: #fff;
  position: fixed ;
  top: 20;
  width: 100%;
}

.TableRecords_Header{
    height: 40px;
       position: -webkit-sticky;
  position: sticky;
  top: 0;
}

.table-header th.sortable {
    cursor: pointer;
}


.sortable-icon {
    display: inline-block;
    height: 11px;
    margin-left: var(--space-s);
    position: relative;
    width: 10px;
}

.sortable-icon:before,
.sortable-icon:after {
    border-left: 4px solid transparent;
    border-right: 4px solid transparent;
    content: '';
    left: 0;
    position: absolute;
}

.sortable-icon:before {
    border-bottom: 4px solid var(--color-neutral-8);
}

.sortable-icon:after {
    border-top: 4px solid var(--color-neutral-8);
    bottom: 0;
}

.desktop .table-header th.sortable:hover .sortable-icon:before,
.table-header th.sorted .sortable-icon:before {
    border-bottom: 4px solid var(--color-primary);
}

.desktop .table-header th.sortable:hover .sortable-icon:after,
.table-header th.sorted .sortable-icon:after {
    border-top: 4px solid var(--color-primary);
}

Hope this will help,

Regards,

Komal

Hi Komal,

Currently I have used the below styles for table container and the table.


If I add your CSS along with mine, then should there be any changes to above style classes? 

Regards,

Somesh


This class can keep your header sticky but along with this css your table's first 3 columns are not sticky then you can do trial with my css, I did not implement this both sticky changes together, Please try it once , I'll also try and let you know,

Kind regards,

I just made it to freeze both header as well as the first 3 columns. The magic was lying with the z-index. Since both th and tr of first 3 columns share same z-index, both were getting moved same. I created a bigger z-index for th alone and now it is working as expected. Sharing below the CSS. It is based on the solution shared in this post. The below CSS is just an extension of it. Hope this helps developers who wants to fix the table headers and columns with CSS alone. 

.table-scroll-wrapper {
    overflow: auto;
    border: var(--border-size-s) solid var(--color-neutral-4);
}

.table-scroll {
    margin: 0px;
    border: none;
}

.table-scroll thead th {
  position: -webkit-sticky;
  position: sticky;
  top: 0;
}

.table-scroll tr td:first-child,
.table-scroll th:first-child {
  position: -webkit-sticky;
  position: sticky;
  width:120px;
  left: 0;
  z-index: 2;
  border-right: var(--border-size-s) solid var(--color-neutral-4);
}

.table-scroll th:first-child {
    z-index: 4;
}

.table-scroll tr td:nth-child(2),
.table-scroll th:nth-child(2) {
  position: -webkit-sticky;
  position: sticky;
  width: 120px;
  left: 110px;
  z-index: 2;
  border-right: var(--border-size-s) solid var(--color-neutral-4);
}

.table-scroll th:nth-child(2) {
    z-index: 4;
}


.table-scroll tr td:nth-child(3),
.table-scroll th:nth-child(3) {
  position: -webkit-sticky;
  position: sticky;
  left: 210px;
  z-index: 2;
  border-right: var(--border-size-s) solid var(--color-neutral-4);
}

.table-scroll th:nth-child(3) {
    z-index: 4;
}

.table-scroll tr td:last-child {
  border-right: none;
}

.phone .table-scroll tr td,
.tablet .table-scroll tr td {
  border-right: none;
}

Thanks @Komal Kumbhar for your quick responses. It gave another way of implementing the fixed headers.


Community GuidelinesBe kind and respectful, give credit to the original source of content, and search for duplicates before posting.