I have implemented a table with horizontal scrolling in angular and have requirement to fix the first two columns while scrolling vertically. I have created a stackblitz to show two tables. What I looking for is that as and when the user scrolls the second table, the first two rows that is Legal Class Name and Fund Name should be fixed.
I tried to apply the following class to the respective tds and it didnt work
.stickyRows {
position: sticky;
}
Here is the stackblitz
https://stackblitz.com/edit/angular-o2ukfs
th {
padding: 7px;
position: sticky;
left: 0px;
min-width: 250px;
width: 250px;
background-color: #f5f7f7;
}
td {
padding: 7px;
min-width: 250px;
/* max-width: 300px; */
}
.fundClassesTable {
table-layout: fixed;
}
.cellbgcolor {
color: transparent;
}
.btn {}
.tableItem {
text-align: left;
border-left: solid 1px lightgrey;
border-top: solid 1px lightgrey;
border-right: solid 1px lightgrey;
border-bottom: solid 1px lightgrey;
}
.rowItem:hover {
background-color: #f5f7f7;
}
label {
margin-left: 0.5rem;
vertical-align: middle
}
.panel-heading {
color: black;
border-color: #ddd;
overflow: hidden;
padding-top: 5px !important;
padding-bottom: 5px !important;
}
.panel-heading .left-label {
display: inline-block;
padding-top: 5px !important;
}
.scrollClass {
overflow-x: scroll;
display: grid;
overflow-y:hidden;
height: 100%;
}
.panel-heading label {
margin-bottom: 0px !important;
}
#FundClass tr:hover {
background-color: #ECF0F1;
}
.headcol {
position: absolute;
min-width: 300px;
max-width: 300px;
width: 5em;
left: 0;
top: auto;
border-top-width: 1px;
/*only relevant for first row*/
margin-top: -1px;
/*compensate for top border*/
}
.headcol:before {
content: 'Row ';
}
.collapsed {
color: #d6630a;
font-size: 22px;
text-decoration: none;
font-weight: bold;
}
.expanded {
color: #d6630a;
font-size: 22px;
text-decoration: none;
font-weight: bold;
}
.fixed-side {
border: 1px solid #000;
background: #eee;
visibility: visible;
}
.card-body {
flex: 1 1 auto;
padding: 0px;
margin: 10px 0;
background-color: white;
}
<div class="card">
<div class="card-header panel-heading">
<span class="left-label" style="font-size: 18px; font-weight: bold; ">Accounting Fund Classes</span>
</div>
<div [ngClass]="{'show': isExpanded}" id="fundClass" class="collapse" role="tabpanel" aria-labelledby="fundClass_heading"
data-parent="#fundClass" [attr.aria-expanded]="isExpanded">
<div class="card-body scrollClass" *ngIf="data">
<table id="FundClass" class="fundClassesTable table-striped">
<tr *ngFor="let c of ColumnNames">
<th Fund Name scope="col" [ngClass]="c != 'Buttons1'? 'tableItem bold' : 'tableItem cellbgcolor'"> {{ c }}</th>
<ng-container *ngFor="let f of data let i=index">
<td class="tableItem" style="font-weight: bold" *ngIf="c == 'Fund Name'">
{{ f.FundName}}
</td>
<td [attr.id]="'f.Id'" *ngIf="c == 'Accounting Class Name'"
class="tableItem">
{{ f.FundName}}
</td>
<td class="tableItem" *ngIf="c == 'Class ID'">{{f.Id}}</td>
<td [attr.id]="'f.Id'" *ngIf="c == 'Legal Fund Class'"
class="tableItem">
{{ f.LegalFundClassName}}
</td>
<td [attr.id]="'f.Id'" *ngIf="c == 'Invested Amount'"
class="tableItem">
{{ f.InvestedAmount | number : '.2-2'}}
</td>
<td [attr.id]="'f.Id'" *ngIf="c == 'Vehicle Type'"
class="tableItem">
{{ f.VehicleTypeName}}
</td>
<td [attr.id]="'f.Id'" *ngIf="c == 'Closure Status'"
class="tableItem">
{{ f.ClosureStatusName}}
</td>
<td class="tableItem" *ngIf="c == 'Buttons1'">
<button *ngIf="!EditMode[f.Id]" type="button"
class="btn btn-primary btn mr-1 "
(click)="buttonClicked(f.Id)">Edit</button>
<button *ngIf="EditMode[f.Id]" type="button"
class="btn btn-primary btn mr-1"
(click)="buttonClicked(f.Id)">Cancel</button>
</td>
</ng-container>
</tr>
</table>
</div>
</div>
</div>
How to freeze multiple rows in Excel. In case you want to lock several rows (starting with row 1), carry out these steps: Select the row (or the first cell in the row) right below the last row you want to freeze. On the View tab, click Freeze Panes > Freeze Panes.
To freeze the top row or first column:From the View tab, Windows Group, click the Freeze Panes drop down arrow. Select either Freeze Top Row or Freeze First Column. Excel inserts a thin line to show you where the frozen pane begins.
Freeze columns and rows to keep them in view while you scroll through your data. Select the cell below the rows, and to the right of the columns you want to freeze. Click View > Freeze Panes > Freeze Panes.
I hope this is what you were looking for:
app.component.css
/* Container should define how tall the scrollable content is */
.scrollClass{
height: 500px;
}
/* tagetting the first <th>; to ensure <th> are scrolled along with <td> */
.fundClassesTable tr:nth-child(1) th{
z-index: 3;
position: sticky;
position: -webkit-sticky;
top: 2px;
}
/* target all <td> in the first row to be sticky */
.fundClassesTable tr:nth-child(1) td{
color: red;
position: sticky;
position: -webkit-sticky;
top: 2px;
z-index: 2;
background-color: white;
font-weight: bold;
}
/* Same as above but with top property as 36px
because the 2nd "row" is 36px from the top of <table> */
.fundClassesTable tr:nth-child(2) th{
z-index: 3;
position: sticky;
position: -webkit-sticky;
top: 38px;
}
.fundClassesTable tr:nth-child(2) td{
color: red;
position: sticky;
position: -webkit-sticky;
top: 38px;
z-index: 2;
background-color: white;
font-weight: bold;
}
Forked Stackblitz
Riv's solution has worked for me but i am left with one nagging problem. As I scroll through the fixed rows , I can see the data of the rows visible between gaps of the fixed rows and border of the fixed rows arent visible
Probably not the best solution out there but I would use ::after pseudo selector to create a background for your stickied table cells to hide the background cells when scrolling down.
.fundClassesTable tr:nth-child(1)::after{
content: '';
position: absolute;
height: 71px;
width: 96.7%;
top: 55px;
left: 19px;
z-index: 1;
background-color: white; //create a white background to cover your other cells when scrolled down
border: solid 1px deeppink;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With