How to make the Header of Data Table component fixed to the top, and the Paginator fixed to the bottom?
This is my HTML:
<div> <table mat-table #itemsTable [dataSource]="dataSource"> <ng-container matColumnDef="position"> <th mat-header-cell *matHeaderCellDef> No. </th> <td mat-cell *matCellDef="let element"> {{element.position}} </td> </ng-container> <ng-container matColumnDef="name"> <th mat-header-cell *matHeaderCellDef> Name </th> <td mat-cell *matCellDef="let element"> {{element.name}} </td> </ng-container> <ng-container matColumnDef="weight"> <th mat-header-cell *matHeaderCellDef> Weight </th> <td mat-cell *matCellDef="let element"> {{element.weight}} </td> </ng-container> <ng-container matColumnDef="symbol"> <th mat-header-cell *matHeaderCellDef> Symbol </th> <td mat-cell *matCellDef="let element"> {{element.symbol}} </td> </ng-container> <tr mat-header-row *matHeaderRowDef="this.componentsDataService.displayedColumns"></tr> <tr mat-row *matRowDef="let row; columns: this.componentsDataService.displayedColumns;" (click)="onRowClicked(row)"></tr> </table> <mat-paginator [pageSizeOptions]="[50, 100, 250]" showFirstLastButtons></mat-paginator>
</div>I tried adding sticky to the <tr mat-header-row> from the docs, but it doesn't work.
My imports in .ts file:
import { Component, OnInit, OnChanges, Input, ViewChild } from '@angular/core'; import { TabsDataService } from 'src/app/services/tabs-data.service'; import { ComponentsDataService } from 'src/app/services/components-data.service'; import { MatPaginator, MatTableDataSource, MatTable, MatTableModule } from '@angular/material';
96 Answers
I found in the examples on the material site that the header can be fixed by adding sticky to the matHeaderRowDef:
<tr mat-header-row *matHeaderRowDef="displayedColumns; sticky: true">For the paginator i added a class to mat-paginator:
<mat-paginator ...> with a class based on the answer in the link @frederik provided in the comments
.mat-paginator-sticky { bottom: 0px; position: sticky; z-index: 10;
} 2 As per Material 8.1
For the sticky header we need to give a sticky values as shown in many answers here
For the sticky paginator or bottom fixed paginator.
We can wrap the table inside a div with max-height or height CSS Property and put the paninator outside that div.
Html Code sample.
<div> <div> <!--- List of column definitions here ---> <table mat-table [dataSource]="dataSource" matSort> <tr mat-header-row *matHeaderRowDef="displayedColumns; sticky: true"></tr> <tr mat-row *matRowDef="let row; columns: displayedColumns;"></tr> </table> </div> <mat-paginator [pageSize]="25" [pageSizeOptions]="[10, 15, 25, 100]"></mat-paginator> </div>CSS
table { width: 100%; } .table-container { max-height: calc(100vh - 155px); // or height: calc(100vh - 155px); depending on your need change overflow: auto; } 2 Try to update angular material in your project because the sticky attribute was added in 6.2.3.
2The below css worked for me:
<mat-header-row *matHeaderRowDef="displayedColumns"></mat-header-row>
.mat-header-row{ position: sticky; top: 0; z-index: 100; background: white; } 2 You can use a normal sticky mat-footer-row with colspan and put the paginator inside:
<table mat-table> ... <ng-container matColumnDef="paginator"> <td mat-footer-cell *matFooterCellDef [colSpan]="displayedColumns.length"> <mat-paginator ...></mat-paginator> </td> </ng-container> <tr mat-footer-row *matFooterRowDef="['paginator']; sticky: true"></tr>
</table>And use some style like this, to make it more appealing to eye:
.mat-row:last-child td { border-bottom: none;
}
.mat-footer-row:first-child td { border-top: 1px solid rgba(0, 0, 0, 0.12);
}
.mat-footer-cell .mat-paginator { margin-left: -24px; margin-right: -24px;
} 2 I too had this problem. I created a div of fixed size and then kept the table inside div. This should solve your issue.
<div> <table mat-table [dataSource]=dataSource> <!--Your table entries here --> . . . . <tr mat-header-row *matHeaderRowDef="displayedColumns; sticky: true"></tr> <tr mat-row *matRowDef="let row; columns: displayedColumns;"></tr> </table>
</div> 1