如何正确设置 sticky table header 的样式?
How to correctly style sticky table header?
我的数据 table 中的样式粘性 header 有点问题。我写了简单的 Angular 组件和特定指令:
sticky.directive.ts
@Directive({
selector: '[sticky]'
})
export class StickyDirective {
constructor(private _element: ElementRef, private _window: WindowRef) {
console.log('debug')
}
@HostListener('window:scroll', ['$event'])
handleScrollEvent(e) {
if (this._window.nativeWindow.pageYOffset > 100) {
this._element.nativeElement.classList.add('stick');
} else {
this._element.nativeElement.classList.remove('stick');
}
}
}
该指令的目的是添加 class stick 如果用户滚动到下方 header。因此,table header 应该对用户可见,即使他滚动很长时间 table。 stick class 看起来像:
.stick {
position: fixed;
top: 55px;
}
和我的 some.component.html 的一部分(并在 thead 元素上使用指令)看起来像:
<table class=" table table-bordered ">
<thead sticky>
<tr>
<th width="40%">Name
</th>
<th width="10%">Priority
</th>
<th width="25%">Date created
</th>
<th width="25%">Date modified
</th> </tr> </thead> <tbody> <tr *ngFor="let r of entitiesFiltered">
<td>
<div class="table-cell-flex">
<div class="cell-content">
{{r.name}}
</div>
</div>
</td>
<td>
<div class="table-cell-flex">
<div class="cell-content">
{{r.priority}}
</div>
</div>
</td>
...
我的代码满足基本功能。这意味着 header 在滚动页面期间保持在同一位置,但 header 宽度和列宽度发生变化。它看起来像:
问题:
任何人都可以告诉我如何设计我的 table,固定的 header 不会改变 form/shape table?是否可以?
我认为您不需要 angular 指令,它会在添加 class "stick" 时覆盖指定宽度的样式。
您可以固定 table 头部的位置并在其上设置更高的 z-index,这样当它滚动时,body 不会显示出来。
参见 codepen 示例:
thead{
position:fixed;
z-index:2;
...
}
tbody{
position:absolute;
z-index:1;
...
}
你用 javaScript 得到任何列的宽度,然后设置为 header 并且 px 的位置是固定的或绝对的,
或者使用 html 和代码:
<div class="table-wrapper content">
<!-- overall wrapper -->
<table>
<!-- header -->
<thead>
<tr>
<th>Header 1</th>
<th>Header 2</th>
<th>Header 3</th>
</tr>
</thead>
</table>
</div>
<div class="table-body-wrapper" style="position: relative; overflow: visible;">
<!-- the element with the custom scrollbar -->
<table>
<!-- body -->
<tbody>
<!-- auto-generated data (see js function below) -->
<tr>
<td>Row 1, Column 1</td>
<td>Row 1, Column 2</td>
<td>Row 1, Column 3</td>
</tr>
<tr>
<td>Row 2, Column 1</td>
<td>Row 2, Column 2</td>
<td>Row 2, Column 3</td>
</tr>
<tr>
<td>Row 3, Column 1</td>
<td>Row 3, Column 2</td>
<td>Row 3, Column 3</td>
</tr>
<tr>
<td>Row 4, Column 1</td>
<td>Row 4, Column 2</td>
<td>Row 4, Column 3</td>
</tr>
<tr>
<td>Row 5, Column 1</td>
<td>Row 5, Column 2</td>
<td>Row 5, Column 3</td>
</tr>
</tbody>
</table>
</div>
我刚刚发现:
position: sticky
https://developer.mozilla.org/fr/docs/Web/CSS/position#Positionnement_adh%C3%A9rent_(sticky)
我遇到了同样的问题。
为了解决这个问题,我创建了一个简单的 hack,我在 sticky header 中设置了列的固定宽度,并在 table 下复制了 sticky header (为了保持宽度列名称的内容。
我的解决方案基于Bootstrap 4 和Angular 6。
example.component.html:
<table class="table">
<thead>
<tr>
<th #tableColumn1>Column 1</th>
<th #tableColumn2>Column 2</th>
<th #tableColumn3>Column 3</th>
</tr>
</thead>
<tbody>
<tr *ngFor="let message of messages">
<td>{{ message.title }}</td>
<td>{{ message.author }}</td>
<td>{{ message.created_at }}</td>
</tr>
</tbody>
</table>
<table class="table" [class.d-none]="!showFixedTableHeader">
<thead>
<tr [class.sticky]="showFixedTableHeader">
<th [width]="tableColumn1.offsetWidth">Column 1</th>
<th [width]="tableColumn2.offsetWidth">Column 2</th>
<th [width]="tableColumn3.offsetWidth">Column 3</th>
</tr>
</thead>
</table>
example.component.ts
import {Component, HostListener} from '@angular/core';
@Component({
templateUrl: './example.component.html',
styleUrls: ['./example.component.css']
})
export class ExampleComponent {
showFixedTableHeader: boolean = false;
@HostListener('window:scroll')
onScroll() {
const pageTopOffset = window.pageYOffset;
if (pageTopOffset > 285) {
this.showFixedTableHeader = true;
} else {
this.showFixedTableHeader = false;
}
}
@HostListener('window:resize')
onResize() {
// Do nothing.
// It will automatically trigger to update the bound properties in template.
}
}
example.component.css
tr.sticky {
top: 60px;
position: fixed;
z-index: 99;
}
我的数据 table 中的样式粘性 header 有点问题。我写了简单的 Angular 组件和特定指令:
sticky.directive.ts
@Directive({
selector: '[sticky]'
})
export class StickyDirective {
constructor(private _element: ElementRef, private _window: WindowRef) {
console.log('debug')
}
@HostListener('window:scroll', ['$event'])
handleScrollEvent(e) {
if (this._window.nativeWindow.pageYOffset > 100) {
this._element.nativeElement.classList.add('stick');
} else {
this._element.nativeElement.classList.remove('stick');
}
}
}
该指令的目的是添加 class stick 如果用户滚动到下方 header。因此,table header 应该对用户可见,即使他滚动很长时间 table。 stick class 看起来像:
.stick {
position: fixed;
top: 55px;
}
和我的 some.component.html 的一部分(并在 thead 元素上使用指令)看起来像:
<table class=" table table-bordered ">
<thead sticky>
<tr>
<th width="40%">Name
</th>
<th width="10%">Priority
</th>
<th width="25%">Date created
</th>
<th width="25%">Date modified
</th> </tr> </thead> <tbody> <tr *ngFor="let r of entitiesFiltered">
<td>
<div class="table-cell-flex">
<div class="cell-content">
{{r.name}}
</div>
</div>
</td>
<td>
<div class="table-cell-flex">
<div class="cell-content">
{{r.priority}}
</div>
</div>
</td>
...
我的代码满足基本功能。这意味着 header 在滚动页面期间保持在同一位置,但 header 宽度和列宽度发生变化。它看起来像:
问题:
任何人都可以告诉我如何设计我的 table,固定的 header 不会改变 form/shape table?是否可以?
我认为您不需要 angular 指令,它会在添加 class "stick" 时覆盖指定宽度的样式。
您可以固定 table 头部的位置并在其上设置更高的 z-index,这样当它滚动时,body 不会显示出来。
参见 codepen 示例:
thead{
position:fixed;
z-index:2;
...
}
tbody{
position:absolute;
z-index:1;
...
}
你用 javaScript 得到任何列的宽度,然后设置为 header 并且 px 的位置是固定的或绝对的, 或者使用 html 和代码:
<div class="table-wrapper content">
<!-- overall wrapper -->
<table>
<!-- header -->
<thead>
<tr>
<th>Header 1</th>
<th>Header 2</th>
<th>Header 3</th>
</tr>
</thead>
</table>
</div>
<div class="table-body-wrapper" style="position: relative; overflow: visible;">
<!-- the element with the custom scrollbar -->
<table>
<!-- body -->
<tbody>
<!-- auto-generated data (see js function below) -->
<tr>
<td>Row 1, Column 1</td>
<td>Row 1, Column 2</td>
<td>Row 1, Column 3</td>
</tr>
<tr>
<td>Row 2, Column 1</td>
<td>Row 2, Column 2</td>
<td>Row 2, Column 3</td>
</tr>
<tr>
<td>Row 3, Column 1</td>
<td>Row 3, Column 2</td>
<td>Row 3, Column 3</td>
</tr>
<tr>
<td>Row 4, Column 1</td>
<td>Row 4, Column 2</td>
<td>Row 4, Column 3</td>
</tr>
<tr>
<td>Row 5, Column 1</td>
<td>Row 5, Column 2</td>
<td>Row 5, Column 3</td>
</tr>
</tbody>
</table>
</div>
我刚刚发现:
position: sticky
https://developer.mozilla.org/fr/docs/Web/CSS/position#Positionnement_adh%C3%A9rent_(sticky)
我遇到了同样的问题。
为了解决这个问题,我创建了一个简单的 hack,我在 sticky header 中设置了列的固定宽度,并在 table 下复制了 sticky header (为了保持宽度列名称的内容。
我的解决方案基于Bootstrap 4 和Angular 6。
example.component.html:
<table class="table">
<thead>
<tr>
<th #tableColumn1>Column 1</th>
<th #tableColumn2>Column 2</th>
<th #tableColumn3>Column 3</th>
</tr>
</thead>
<tbody>
<tr *ngFor="let message of messages">
<td>{{ message.title }}</td>
<td>{{ message.author }}</td>
<td>{{ message.created_at }}</td>
</tr>
</tbody>
</table>
<table class="table" [class.d-none]="!showFixedTableHeader">
<thead>
<tr [class.sticky]="showFixedTableHeader">
<th [width]="tableColumn1.offsetWidth">Column 1</th>
<th [width]="tableColumn2.offsetWidth">Column 2</th>
<th [width]="tableColumn3.offsetWidth">Column 3</th>
</tr>
</thead>
</table>
example.component.ts
import {Component, HostListener} from '@angular/core';
@Component({
templateUrl: './example.component.html',
styleUrls: ['./example.component.css']
})
export class ExampleComponent {
showFixedTableHeader: boolean = false;
@HostListener('window:scroll')
onScroll() {
const pageTopOffset = window.pageYOffset;
if (pageTopOffset > 285) {
this.showFixedTableHeader = true;
} else {
this.showFixedTableHeader = false;
}
}
@HostListener('window:resize')
onResize() {
// Do nothing.
// It will automatically trigger to update the bound properties in template.
}
}
example.component.css
tr.sticky {
top: 60px;
position: fixed;
z-index: 99;
}