I'm trying to adjust the column headers so that I can scroll horizontally while keeping the headers visible. I've attempted the following changes but haven't been successful. In the screenshots provided, you can see that when I scroll up or down, the headers don't stay in place and there is some improper overlapping. The first td always ends up hidden behind the th.
Screenshot 1https://i.sstatic.net/3VblS.png
Screenshot 2 https://i.sstatic.net/D2upr.png
th:first-child {
position: fixed;
}
th {
position: fixed;
}
.fixed-side {
border:1px solid #000;
background:#eee;
visibility:visible;
}
CSS
<style>
th,
td {
padding: 7px;
min-width: 300px;
max-width: 300px;
}
/* th:first-child {
position: fixed;
} */
th {
position: fixed;
}
.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;
}
.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;
}
</style>
HTML
<div class="card">
<div class="card-header panel-heading">
<span class="left-label" style="font-size: 18px; font-weight: bold; ">Fund Classes</span>
<a class="pull-right" [ngClass]="{'collapsed': !isExpanded, 'expanded': isExpanded }" data-toggle="collapse"
href="javascript:void(0);" (click)="expand()" role="button" [attr.aria-expanded]="isExpanded"
aria-controls="fundClass"> {{ isExpanded ? '-' : '+' }}
</a>
<div *ngIf="CanEdit" class="pull-right"
style="padding-right:10px; display: inline-block; vertical-align:middle">
<button style="text-align: center; vertical-align:middle" class="btn btn-default pull-right"
(click)="openFundClassModal()"> <i data-bind="visible: true" class="fa fa-plus-square"></i> Add
Class</button>
</div>
<div class="pull-right" style="padding-right:10px; display: inline-block; vertical-align:middle">
<label style="text-align: center; vertical-align:middle" class="btn btn-primary"
[ngClass]="{'btn-primary': InvestedOnly, 'btn-default': !InvestedOnly }"><input type="checkbox"
(click)="isInvestedSelected($event)" checked="checked" [(ngModel)]="InvestedOnly" class="hidden"
for="chkInvested" />Invested Only</label>
</div>
</div>
<div *ngIf="!FundClasses || !FundClasses.FundDetailsViewModel" style="padding-top:10px">
<div class="alert alert-warning" style="text-align:center" role="alert">
Loading... Please Wait
</div>
</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="FundClasses && FundClasses.FundDetailsViewModel">
<table id="FundClass" class="fundClassesTable table-striped">
<!-- *ngIf="c != 'Buttons1' && !CanEdit" -->
<tr *ngFor="let c of FundClasses.FundClassColumnNames">
<th class="fixed-side" scope="col" [ngClass]="c != 'Buttons1'? 'tableItem bold' : 'tableItem cellbgcolor'"> {{ c }}</th>
<ng-container *ngFor="let fundClass of FundClasses.FundDetailsViewModel let i=index">
<ng-container *ngFor="let f of fundClass['FundClassDetailsViewModel'] | keyvalue">
<td class="tableItem" style="font-weight: bold" *ngIf="c == 'Fund Name'">
{{ f.value.FundName}}
</td>
<td [attr.id]="'f.value.Id'" class="tableItem"
*ngIf="!EditMode[f.value.Id] && c == 'Accounting Class Name'">{{ f.value.Description}}
</td>
<td [attr.id]="'f.value.Id'" *ngIf="EditMode[f.value.Id] && c == 'Accounting Class Name'"
class="tableItem">
<input kendoTextBox [(ngModel)]="f.value.Description"
style="width: 284px; height: 29.5px;" />
</td>
<td class="tableItem" *ngIf="c == 'Class ID'">{{f.value.Id}}</td>
<td *ngIf="EditMode[f.value.Id] && c == 'Legal Fund Class'" class="tableItem">
<kendo-dropdownlist [(ngModel)]="f.value.LegalFundClassId"
class="form-control form-control-sm " [data]="fundClass.PrimaryLegalFundClasses"
[filterable]="false" textField="Description" [valuePrimitive]="true"
valueField="Id">
</kendo-dropdownlist>
</td>
<td [attr.id]="'f.value.Id'" *ngIf="!EditMode[f.value.Id] && c == 'Legal Fund Class'"
class="tableItem">
{{ f.value.LegalFundClassName}}
</td>
<td [attr.id]="'f.value.Id'" *ngIf="EditMode[f.value.Id] && c == 'Inception Date'"
class="tableItem">
<kendo-datepicker [format]="'MMM dd, yyyy'" [(ngModel)]="f.value.InceptionDate"
class="form-control form-control-sm">
</kendo-datepicker>
</td>
<td [attr.id]="'f.value.Id'" *ngIf="!EditMode[f.value.Id] && c == 'Inception Date'"
class="tableItem">
{{ f.value.InceptionDate | date:"'MMM dd, yyyy"}}
</td>
<td [attr.id]="'f.value.Id'" *ngIf="EditMode[f.value.Id] && c == 'Invested Amount'"
class="tableItem">
<input kendoTextBox [(ngModel)]="f.value.InvestedAmount"
style="width: 284px; height: 29.5px;" />
</td>
<td [attr.id]="'f.value.Id'" *ngIf="!EditMode[f.value.Id] && c == 'Invested Amount'"
class="tableItem">
{{ f.value.InvestedAmount | number : '.2-2'}}
</td>
<td [attr.id]="'f.value.Id'" *ngIf="EditMode[f.value.Id] && c == 'Vehicle Type'"
class="tableItem">
<kendo-dropdownlist [(ngModel)]="f.value.VehicleTypeId"
class="form-control form-control-sm " [data]="FundClasses.VehicleTypes"
[filterable]="false" textField="Name" [valuePrimitive]="true" valueField="Id">
</kendo-dropdownlist>
</td>
<td [attr.id]="'f.value.Id'" *ngIf="!EditMode[f.value.Id] && c == 'Vehicle Type'"
class="tableItem">
{{ f.value.VehicleTypeName}}
</td>
<td [attr.id]="'f.value.Id'" *ngIf="EditMode[f.value.Id] && c == 'Closure Status'"
class="tableItem">
<kendo-dropdownlist [(ngModel)]="f.value.ClosureStatusId"
class="form-control form-control-sm" [data]="FundClasses.ClosureStatuses"
[filterable]="false" textField="Name" [valuePrimitive]="true" valueField="Id">
</kendo-dropdownlist>
</td>
<td [attr.id]="'f.value.Id'" *ngIf="!EditMode[f.value.Id] && c == 'Closure Status'"
class="tableItem">
{{ f.value.ClosureStatusName}}
</td>
<td [attr.id]="'f.value.Id'" *ngIf="EditMode[f.value.Id] && c == 'Is Side Pocket?'"
class="tableItem">
<input type="checkbox" value="{{f.value.IsSidePocket}}" id="chkSidePocket"
[(ngModel)]="f.value.IsSidePocket" style="width: 13px; height: 13px;" />
<label for="chk">Yes</label>
</td>
<td [attr.id]="'f.value.Id'" *ngIf="!EditMode[f.value.Id] && c == 'Is Side Pocket?'"
class="tableItem">
{{ f.value.IsSidePocket == true ? 'Yes' : 'No'}}
</td>
<td [attr.id]="'f.value.Id'" *ngIf="EditMode[f.value.Id] && c == 'Is Thematic?'"
class="tableItem">
<input type="checkbox" value="{{f.value.IsThematic}}" style="width: 13px; height: 13px;"
[(ngModel)]="f.value.IsThematic" />
<label for="chkThematic">Yes</label>
</td>
<td [attr.id]="'f.value.Id'" *ngIf="!EditMode[f.value.Id] && c == 'Is Thematic?'"
class="tableItem">
{{ f.value.IsThematic == true ? 'Yes' : 'No'}}
</td>
<td class="tableItem" *ngIf="c == 'Buttons1' && CanEdit">
<button *ngIf="!EditMode[f.value.Id]" type="button"
class="btn btn-primary btn mr-1 "
(click)="buttonClicked(f.value.Id)">Edit</button>
<button *ngIf="EditMode[f.value.Id]" type="button"
class="btn btn-primary btn mr-1"
(click)="Update(f.value.Id)">Save</button>
<button *ngIf="EditMode[f.value.Id]" type="button"
class="btn btn-primary btn mr-1"
(click)="Delete(f.value.Id)">Delete</button>
<button *ngIf="EditMode[f.value.Id]" type="button"
class="btn btn-primary btn mr-1"
(click)="buttonClicked(f.value.Id)">Cancel</button>
</td>
</ng-container>
</ng-container>
</tr>
</table>
</div>
</div>
</div>
Update 1
After applying darthnach's solution, I encountered a minor issue with scrolling where the contents were visible in the margin
css
th {
padding: 7px;
position: sticky;
left:0;
min-width: 300px;
background-color:#f5f7f7;
}
Screenshot 1 https://i.sstatic.net/H2QXG.png
Screenshot 2 https://i.sstatic.net/m7pJH.png
Here is the stackblitz
stackblitz.com/edit/angular-d1mzew
Update 2
A fix has been implemented to address the border issue during scrolling, however, the text visibility problem persists while scrolling