Angular 14嵌套HTML表格表头与数据列对齐问题求助
嵌套分组表格表头与数据列对齐问题(Angular 14)
问题背景
我需要通过嵌套HTML表格按PDO、Program、Location对表格数据进行分组,但当前遇到一个问题:当列未完全展开时,表格的<th>标签与嵌套的<td>标签无法对齐。我使用Angular 14框架开发,已经通过[style.width.px]="columnWidths[i]"确保<th>和<td>设置了相同的宽度,但对齐问题仍然存在。
问题表现
列未完全展开时,表头与数据列错位:
- 表头状态:

- 数据列状态:

代码实现
Component.html
<div class="container-parent overflow-auto"> <table #parentTable class="table-hover table-parent w-100"> <thead> <tr class="th-row"> <ng-container *ngFor="let header of tableHeaders; let i = index"> <th class="table-headers" *ngIf="i < 4" [ngClass]="{ 'sticky-left': i < 2 }" [style.display]="columns[i].visible ? '' : 'none'" [style.width.px]="columnWidths[i]" > <i class="material-icons align-middle" [style.cursor]="'pointer'" *ngIf="!columns[i + 1]?.visible && i < 3" (click)="toggleColumn(i, 'add')" >add_box</i > <i class="material-icons align-middle" [style.cursor]="'pointer'" *ngIf="columns[i + 1]?.visible" (click)="toggleColumn(i, 'remove')" >indeterminate_check_box</i > {{ header }} </th> </ng-container> <th class="table-headers" [style.width.px]="columnWidths[4]"> {{ tableHeaders[4] }} </th> </tr> </thead> <tbody> <ng-container *ngIf="currentIndex == 0"> <!-- PDO ROW --> <tr class="pdo-row" *ngFor="let pdo of tableData"> <!-- PDO NAME --> <td class="td-headers" class="pdo-name-column sticky-left" [style.width.px]="columnWidths[0]" [style.display]="columns[0].visible ? '' : 'none'" > {{ pdo.name ?? '-' }} </td> <td class="td-headers" [colSpan]="tableHeaders.length - 1"> <table class="w-100 h-100"> <!-- UNIT ITEM ROW --> <tr class="unit-item-row"> <!-- UNIT ITEM --> <td class="unit-item-column" [style.width.px]="columnWidths[3]" [style.display]="columns[3].visible ? '' : 'none'" > {{ programLocations?.unit_of_item ?? '-' }} </td> <!-- NO. ITEM --> <td class="num-item-column" [style.width.px]="columnWidths[4]"> {{ pdo.num_of_items_pdo | number : '1.0-0' ?? '-' }} </td> </tr> </table> </td> </tr> </ng-container> <ng-container *ngIf="currentIndex == 1"> <!-- PDO ROW --> <tr class="pdo-row" *ngFor="let pdo of tableData"> <!-- PDO NAME --> <td class="td-headers" class="pdo-name-column sticky-left" [style.width.px]="columnWidths[0]" [style.display]="columns[0].visible ? '' : 'none'" > {{ pdo.name ?? '-' }} </td> <td class="td-headers" [colSpan]="tableHeaders.length - 1"> <table class="w-100 h-100"> <!-- PROGRAM ROW --> <ng-container *ngFor=" let program of pdo.pdo_programs; let programIndex = index " > <tr class="program-row"> <!-- PDO PROGRAM --> <td class="pdo-program-column sticky-left" [style.width.px]="columnWidths[1]" [style.display]="columns[1].visible ? '' : 'none'" > {{ program.program ?? '-' }} </td> <td> <table class="w-100 h-100"> <!-- UNIT ITEM ROW --> <tr class="unit-item-row"> <!-- UNIT ITEM --> <td class="unit-item-column" [style.width.px]="columnWidths[3]" [style.display]="columns[3].visible ? '' : 'none'" > {{ programLocations?.unit_of_item ?? '-' }} </td> <!-- NO. ITEM --> <td class="num-item-column" [style.width.px]="columnWidths[4]" > {{ program.num_of_items_program | number : '1.0-0' ?? '-' }} </td> </tr> </table> </td> </tr> </ng-container> </table> </td> </tr> </ng-container> <ng-container *ngIf="currentIndex > 1"> <!-- PDO ROW --> <tr class="pdo-row" *ngFor="let pdo of tableData"> <!-- PDO NAME --> <td class="td-headers" class="pdo-name-column sticky-left" [style.width.px]="columnWidths[0]" [style.display]="columns[0].visible ? '' : 'none'" > {{ pdo.name ?? '-' }} </td> <td class="td-headers" [colSpan]="tableHeaders.length - 1"> <table class="w-100 h-100"> <!-- PROGRAM ROW --> <ng-container *ngFor=" let program of pdo.pdo_programs; let programIndex = index " > <tr class="program-row"> <!-- PDO PROGRAM --> <td class="pdo-program-column sticky-left" [style.width.px]="columnWidths[1]" [style.display]="columns[1].visible ? '' : 'none'" > {{ program.program ?? '-' }} </td> <td> <table class="w-100 h-100"> <!-- LOCATION ROW --> <tr class="location-row" *ngFor=" let programLocations of program?.pdo_program_locations " > <!-- PROGRAM LOCATION --> <td class="location-column" [style.width.px]="columnWidths[2]" [style.display]="columns[2].visible ? '' : 'none'" > {{ programLocations?.location?.name ?? '-' }} </td> <td> <table class="w-100 h-100"> <!-- UNIT ITEM ROW --> <tr class="unit-item-row"> <!-- UNIT ITEM --> <td class="unit-item-column" [style.width.px]="columnWidths[3]" [style.display]=" columns[3].visible ? '' : 'none' " > {{ programLocations?.unit_of_item ?? '-' }} </td> <!-- NO. ITEM --> <td class="num-item-column" [style.width.px]="columnWidths[4]" > {{ pdo.num_of_items_pdo | number : '1.0-0' ?? '-' }} </td> </tr> </table> </td> </tr> </table> </td> </tr> </ng-container> </table> </td> </tr> </ng-container> <!-- Grand total--> <tr class="grand-total-row font-weight-bold"> <td class="grand-total-column sticky-left" [style.width.px]="columnWidths[0]" [style.display]="columns[0].visible ? '' : 'none'" > Grand total </td> <td class="grand-total-column sticky-left" [style.width.px]="columnWidths[1]" [style.display]="columns[1].visible ? '' : 'none'" ></td> <td class="grand-total-column" [style.width.px]="columnWidths[2]" [style.display]="columns[2].visible ? '' : 'none'" ></td> <td class="grand-total-column" [style.width.px]="columnWidths[3]" [style.display]="columns[3].visible ? '' : 'none'" ></td> <td class="grand-total-column" [style.width.px]="columnWidths[4]"> {{ grandTotal.totalNumItems | number : '1.0-0' }} </td> </tr> </tbody> </table> </div>
Component.css
table, th, td { margin: 0; padding: 0; border-collapse: collapse; font-size: 12px; } th:not(:first-child) { position: sticky; top: 0; background-color: white; } th:first-child { position: sticky; top: 0; left: 0; z-index: 10; background-color: white; } .table-parent { min-width: 1440px; } .container-parent { max-height: 100vh; } .grand-total-column:not(:first-child) { position: sticky; bottom: 0; background-color: white; } .grand-total-column.sticky-left:first-child { position: sticky; bottom: 0; left: 0; z-index: 10; background-color: white; } .pdo-name-column.sticky-left { position: sticky; left: 0; background-color: white; } /* .grand-total-column.sticky-left:nth-child(2), .table-headers.sticky-left:nth-child(2), .pdo-program-column.sticky-left { position: sticky; left: 144px; background-color: white; } */ .th-row { border-bottom: 2px solid #ccc; } .pdo-row, .program-row:not(:last-child), .location-row:not(:last-child), .unit-item-row:not(:last-child) { border-bottom: 1px solid #ccc; } .grand-total-row { border-top: 2px solid #ccc; } .unit-item-column, .grand-total-column:nth-child(4) { border-right: 2px solid #ccc; } .table-headers:nth-child(5), .num-item-column, .grand-total-column:not(:first-child) { text-align: right; } th, .pdo-name-column, .pdo-program-column, .location-column, .beneficiary-column, .currency-column, .num-beneficiaries-column, .funding-needs-column, .grand-total-column { padding: 1px; }
内容的提问来源于stack exchange,提问作者lance2k
相关产品推荐
相关产品推荐

