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.