固定列标题在水平滚动时

8
我试图修复列标题,以便我可以横向滚动并且仍然看到标题。我尝试了以下方法,但似乎不起作用。如果您查看截屏,如果我将屏幕向上或向下移动,则标题似乎无法保持在一个位置,并且存在不正确的重叠。第一个td始终隐藏在th后面。
截图1: enter image description here 截图2: enter image description here
   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>

更新1

在尝试过darthnach的解决方案后,在滚动时出现了一个小问题。我可以在边距中看到内容。

CSS

 th {
        padding: 7px;
        position: sticky;
        left:0;
        min-width: 300px;
        background-color:#f5f7f7;

        }

截图1 在此输入图片描述

截图2 在此输入图片描述

这是 stackblitz

stackblitz.com/edit/angular-d1mzew

更新2

修复了滚动时边框问题,但文本可见性保持不变

在此输入图片描述


你可以简单地删除th中设置位置的CSS语句。如果某物是“fixed”,它将始终保持在原位。您可以在此处阅读更多信息:https://developer.mozilla.org/en-US/docs/Web/CSS/position - adr5240
你反对使用Javascript编写的任何解决方案吗? - Mister Jojo
5个回答

5
建立在@Sethuraman的回答之上,如果您将
padding替换为margin,然后在包含表格的
上添加一个边框,可能会解决您的边框问题(不确定这是否是您想要解决的问题)。
您可以尝试以下更改:
.card-body {
    flex: 1 1 auto;
    padding: 0;
    margin: 10px 0;
    /* border: 1px solid lightgray; */ <-- You can add or remove this based on your need
}

这是修改上述类之前和之后的情况。

enter image description here

enter image description here

此外,您可以删除边框间距,以避免在将内容向左滚动时在 th 元素上出现 2px 的滚动间隙。
.fundClassesTable[_ngcontent-xcq-c0] {
    table-layout: fixed;
    border-spacing: 0;
}

请告诉我这是否有帮助或者您需要其他内容。


间距为10像素零边距;已经添加了边框,但是在滚动时仍然可以看到左边距上的一些文本。已更新帖子。 - Tom
可能是因为您还没有将填充设置为0。我已经通过在“.card-body”类中添加填充CSS来更新了我的答案。请尝试一下。 - Furqan Rahamath
你已经上传了截图吗? - Tom
@Tom,你还没有把赏金分配给任何人。你可以将赏金分成几份,并授予帮助过你的人。 - Furqan Rahamath
我已经接受了你的答案,那么赏金不是应该授予给你吗? - Tom
显示剩余6条评论

2
.card-body中,尝试使用margin而不是padding,这可能会解决您的问题。我在stackblitz上进行了测试--https://stackblitz.com/edit/angular-d1mzew。最初的回答。
.card-body {
    flex: 1 1 auto;
    /* padding: 10px; */
    margin: 10px;
}

你分享的 Stackblitz 没有反映修复。 - Tom
我在我的解决方案中尝试了你的CSS,比以前好多了,但是在滚动时我可以看到表格边框消失了。 - Tom
正如我之前提到的,我已经尝试过了,现在比以前好多了,但是在滚动时表格的边框会消失。 - Tom
left - 10px 在滚动时会使标题稍微向左移动。 - Tom
@Tom,你能解释一下滚动时边框消失的原因吗?在Mac上测试时,我发现将“padding”替换为“margin”后行为相同。 - Furqan Rahamath
显示剩余2条评论

2
尝试将 position:stickyleft:-10px 设为属性。这是相同的 stackbliz。我猜这会满足你的需求。"Original Answer" 翻译成 "最初的回答"。
th{
    position: sticky;
    left: -10px;

}

1
您可以尝试使用此代码处理第一列。

div {
  overflow-x:scroll;  
  margin-left:6em;
  width: 300px;
    }
table th, td{
  border: 1px solid #000;
}
.first-col {
  position:absolute;
 width:6em;
 left:0;
  text-align: center;
  background-color: #ccc;
    }
<div>
  <table>
    <thead>
      <tr>
        <th class="first-col">text</th>
        <th>value</th>
        <th>value2
        </th>
        <th>value2
        </th>
        <th>value3
        </th>
        <th>value4
        </th>
        <th>value5
        </th>
        <th>value6
        </th>
        <th>value7
        </th>
      </tr>
    </thead>
    <tbody>
      <tr>
        <td class="first-col">lorem ipsum</td>
        <td><strong>0</strong>
        </td>
        <td>1</td>
        <td>2</td>
        <td>3</td>
        <td>4</td>
        <td>5</td>
        <td>6</td>
        <td>7</td>
      </tr>
      <tr>
        <td class="first-col">lorem ipsum</td>
        <td><strong>0</strong>
        </td>
        <td>1</td>
        <td>2</td>
        <td>3</td>
        <td>4</td>
        <td>5</td>
        <td>6</td>
        <td>7</td>
      </tr>
      <tr>
        <td class="first-col">lorem ipsum</td>
        <td><strong>0</strong>
        </td>
        <td>1</td>
        <td>2</td>
        <td>3</td>
        <td>4</td>
        <td>5</td>
        <td>6</td>
        <td>7</td>
      </tr>
      <tr>
        <td class="first-col">lorem ipsum</td>
        <td><strong>0</strong>
        </td>
        <td>1</td>
        <td>2</td>
        <td>3</td>
        <td>4</td>
        <td>5</td>
        <td>6</td>
        <td>7</td>
      </tr>
      <tr>
        <td class="first-col">lorem ipsum</td>
        <td><strong>0</strong>
        </td>
        <td>1</td>
        <td>2</td>
        <td>3</td>
        <td>4</td>
        <td>5</td>
        <td>6</td>
        <td>7</td>
      </tr>
      <tr>
        <td class="first-col">lorem ipsum</td>
        <td><strong>0</strong>
        </td>
        <td>1</td>
        <td>2</td>
        <td>3</td>
        <td>4</td>
        <td>5</td>
        <td>6</td>
        <td>7</td>
      </tr>
      <tr>
        <td class="first-col">lorem ipsum</td>
        <td><strong>0</strong>
        </td>
        <td>1</td>
        <td>2</td>
        <td>3</td>
        <td>4</td>
        <td>5</td>
        <td>6</td>
        <td>7</td>
      </tr>
      <tr>
        <td class="first-col">lorem ipsum</td>
        <td><strong>0</strong>
        </td>
        <td>1</td>
        <td>2</td>
        <td>3</td>
        <td>4</td>
        <td>5</td>
        <td>6</td>
        <td>7</td>
      </tr>
    </tbody>

  </table>

</div>


1
在你的回答中,你给出了固定宽度。我不能给我的表格固定宽度,因为它跨越整个屏幕并且会依赖于不同的屏幕尺寸。另外,我该如何将逻辑嵌入到我的HTML代码中,因为我正在动态循环遍历th和td元素。 - Tom
1
你不需要在HTML代码中适配逻辑,你只需要改变CSS代码。这是一个类似的例子,你不需要添加容器表格的固定宽度,它会根据数据自动调整宽度。 - Mak0619
1
你正在将类应用于html中的第一个th和td。在你的代码中,th和td已经被预先定义了。当它是动态的时候,css如何确定我的情况下的第一个th和td? - Tom
1
您在 div 元素中设置了 width: 300px;。这导致我的表格缩短了。 - Tom
2
@Tom,Mayank的回答就是你想要的,你所要做的就是将.first-col {}改为th {}。只需删除div上的宽度,这仅适用于此示例。 - mullac
嗨,Callum,我已经更新了帖子并解释了我的问题。该列现在已经固定,但是我可以通过边框上应用的填充看到数据。 - Tom

0

只需从th中删除position fixed并添加

th {
  position: sticky;
  left:0;
}

这是非常接近的解决方案,但有一个问题。在滚动时,我可以看到第一个标题后面的背景内容。 - Tom
我通过设置background-color:#f5f7f7来解决了那个问题,但还有一个小问题。我已经在我的帖子中更新了截图。 - Tom
我可能需要查看代码内容,但我认为可以通过包含所有内容的带有overflow:hidden;的框来解决问题,因为可能是因为ng-container显示了额外的内容。 - darthnach
抱歉,我不明白我该把overflow:hidden放在哪里。 - Tom
你能否制作一个快速预览或其他类似的东西来预览你的代码? - darthnach
完美,只需将.card-body {padding: 10px} 更改为 .card-body {margin: 10px 0;}。它是在容器的边框内留出空间,而你需要在边框外留出空间,以将其与页面中的其他内容分开。https://stackblitz.com/edit/angular-txjfnn?file=src%2Fapp%2Fapp.component.css - darthnach

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接