Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Freeze the first two rows on vertical scrolling of the page

Tags:

html

css

angular

I have implemented a table with horizontal scrolling in angular and have requirement to fix the first two columns while scrolling vertically. I have created a stackblitz to show two tables. What I looking for is that as and when the user scrolls the second table, the first two rows that is Legal Class Name and Fund Name should be fixed.

I tried to apply the following class to the respective tds and it didnt work

.stickyRows {
    position: sticky;
}

Here is the stackblitz

https://stackblitz.com/edit/angular-o2ukfs

        th {
            padding: 7px;
            position: sticky;
            left: 0px;
            min-width: 250px;
            width: 250px;
            background-color: #f5f7f7;
        }
    
    
        td {
            padding: 7px;
            min-width: 250px;
            /* max-width: 300px; */
        }
    
        .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;
            overflow-y:hidden;
            height: 100%;
        }
    
        .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;
        }
    
    
        .card-body {
            flex: 1 1 auto;
            padding: 0px;
            margin: 10px 0;
            background-color: white;
    
        
        }
    
       
    <div class="card">
    	<div class="card-header panel-heading">
    		<span class="left-label" style="font-size: 18px; font-weight: bold; ">Accounting Fund Classes</span>
          
        </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="data">
    
                <table id="FundClass" class="fundClassesTable table-striped">
                    <tr *ngFor="let c of ColumnNames">
                        <th Fund Name scope="col" [ngClass]="c != 'Buttons1'? 'tableItem bold' : 'tableItem cellbgcolor'"> {{ c }}</th>
                        <ng-container *ngFor="let f of data let i=index">
                           
                                <td class="tableItem" style="font-weight: bold"  *ngIf="c == 'Fund Name'">
                                    {{ f.FundName}}
                                </td>
                                 <td [attr.id]="'f.Id'" *ngIf="c == 'Accounting Class Name'"
                                    class="tableItem">
                                    {{ f.FundName}}
                                </td>
                                <td class="tableItem" *ngIf="c == 'Class ID'">{{f.Id}}</td>
                               
                                <td [attr.id]="'f.Id'" *ngIf="c == 'Legal Fund Class'"
                                    class="tableItem">
                                    {{ f.LegalFundClassName}}
                                </td>
                               
                                <td [attr.id]="'f.Id'" *ngIf="c == 'Invested Amount'"
                                    class="tableItem">
                                    {{ f.InvestedAmount | number : '.2-2'}}
                                </td>
                               
                                <td [attr.id]="'f.Id'" *ngIf="c == 'Vehicle Type'"
                                    class="tableItem">
                                    {{ f.VehicleTypeName}}
                                </td>
                               
                                <td [attr.id]="'f.Id'" *ngIf="c == 'Closure Status'"
                                    class="tableItem">
                                    {{ f.ClosureStatusName}}
                                </td>
                               
                              
    
                                <td class="tableItem" *ngIf="c == 'Buttons1'">
    
                                    <button *ngIf="!EditMode[f.Id]" type="button"
                                        class="btn btn-primary btn mr-1 "
                                        (click)="buttonClicked(f.Id)">Edit</button>
                                    
                                    <button *ngIf="EditMode[f.Id]" type="button"
                                        class="btn btn-primary btn mr-1"
                                        (click)="buttonClicked(f.Id)">Cancel</button>
    
                                </td>
    
                          
                        </ng-container>
    
                    </tr>
                </table>
            </div>
        </div>
    </div>



    
like image 411
Tom Avatar asked Jul 25 '19 11:07

Tom


People also ask

Can you freeze two different rows in Excel?

How to freeze multiple rows in Excel. In case you want to lock several rows (starting with row 1), carry out these steps: Select the row (or the first cell in the row) right below the last row you want to freeze. On the View tab, click Freeze Panes > Freeze Panes.

How do you freeze the first row of a worksheet?

To freeze the top row or first column:From the View tab, Windows Group, click the Freeze Panes drop down arrow. Select either Freeze Top Row or Freeze First Column. Excel inserts a thin line to show you where the frozen pane begins.

How do I freeze the first two columns in Excel 365?

Freeze columns and rows to keep them in view while you scroll through your data. Select the cell below the rows, and to the right of the columns you want to freeze. Click View > Freeze Panes > Freeze Panes.


1 Answers

I hope this is what you were looking for:

example GIF

app.component.css

/* Container should define how tall the scrollable content is */
.scrollClass{
  height: 500px;
}

/* tagetting the first <th>; to ensure <th> are scrolled along with <td> */
.fundClassesTable tr:nth-child(1) th{
  z-index: 3;
  position: sticky;
  position: -webkit-sticky;
  top: 2px;
}

/* target all <td> in the first row to be sticky */
.fundClassesTable tr:nth-child(1) td{
  color: red;
  position: sticky;
  position: -webkit-sticky;
  top: 2px;
  z-index: 2;
  background-color: white;
  font-weight: bold;
}

/* Same as above but with top property as 36px 
because the 2nd "row" is 36px from the top of <table> */
.fundClassesTable tr:nth-child(2) th{
  z-index: 3;
  position: sticky;
  position: -webkit-sticky;
  top: 38px;
}

.fundClassesTable tr:nth-child(2) td{
  color: red;
  position: sticky;
  position: -webkit-sticky;
  top: 38px;
  z-index: 2;
  background-color: white;
  font-weight: bold;
}

Forked Stackblitz

EDIT:

Riv's solution has worked for me but i am left with one nagging problem. As I scroll through the fixed rows , I can see the data of the rows visible between gaps of the fixed rows and border of the fixed rows arent visible

Probably not the best solution out there but I would use ::after pseudo selector to create a background for your stickied table cells to hide the background cells when scrolling down.

.fundClassesTable tr:nth-child(1)::after{
  content: '';
  position: absolute;
  height: 71px;
  width: 96.7%;
  top: 55px;
  left: 19px;
  z-index: 1;
  background-color: white; //create a white background to cover your other cells when scrolled down
  border: solid 1px deeppink;
}
like image 153
terahertz Avatar answered Oct 22 '22 18:10

terahertz