代码之家  ›  专栏  ›  技术社区  ›  Gonzalo.-

构建固定列的可滚动表

  •  0
  • Gonzalo.-  · 技术社区  · 7 年前

    我需要实现这样的目标

    enter image description here

    我的第一个想法是像这样使用flexbox(这是一个模拟的示例,我将使用angular和ng repeat动态生成结构)

    .reporting-table-container {
        display: flex;
        padding-left: 25px;
        padding-right: 10px;
        margin-bottom: 15px;
    }
    
    .reporting-table-container .columns-container {
        display: flex;
        overflow-x: scroll;
        margin-right: 15px;
    }
    
    .reporting-table-container .columns-container .single-column-container {
        display: flex;
        flex-direction: column;
        justify-content: space-evenly;
    }
    
    .reporting-table-container .columns-container .single-column-container:nth-child(even), .reporting-table-container .labels-container {
        background-color: #e9e9e9;
    }
    
    .reporting-table-container .labels-container {
        display: flex;
        flex-direction: column;
        justify-content: space-evenly;
    }
    
    .reporting-table-container .labels-container > div {
        width: 100px;
        font-weight: 800px;
    }
    <div class="reporting-table-container">
        <div class="labels-container">
            <div>ID</div>
            <div>Product Title</div>
            <div>Strategy Name</div>
            <div>Score</div>
            <div>Message</div>
            <div>Feedback</div>
            <div>Clicks</div>
            <div>Conversion Rate</div>
            <div>Revenue</div>
        </div>
        <div class="columns-container">
            <div class="single-column-container">
                <div>2249</div>
                <div>25.5 cu. ft. French Door Refrigerator in Stainless Steel</div>
                <div>Online co-purchase 2wks</div>
                <div>230</div>
                <div>Customer also bough this other item</div>
                <div>43</div>
                <div>0.50%</div>
                <div>$282.830</div>
            </div>
             <div class="single-column-container">
                <div>2249</div>
                <div>25.5 cu. ft. French Door Refrigerator in Stainless Steel</div>
                <div>Online co-purchase 2wks</div>
                <div>230</div>
                <div>Customer also bough this other item</div>
                <div>43</div>
                <div>0.50%</div>
                <div>$282.830</div>
            </div>
             <div class="single-column-container">
                <div>2249</div>
                <div>25.5 cu. ft. French Door Refrigerator in Stainless Steel</div>
                <div>Online co-purchase 2wks</div>
                <div>230</div>
                <div>Customer also bough this other item</div>
                <div>43</div>
                <div>0.50%</div>
                <div>$282.830</div>
            </div>
    <div class="single-column-container">
                <div>2249</div>
                <div>25.5 cu. ft. French Door Refrigerator in Stainless Steel</div>
                <div>Online co-purchase 2wks</div>
                <div>230</div>
                <div>Customer also bough this other item</div>
                <div>43</div>
                <div>0.50%</div>
                <div>$282.830</div>
            </div>
    <div class="single-column-container">
                <div>2249</div>
                <div>25.5 cu. ft. French Door Refrigerator in Stainless Steel</div>
                <div>Online co-purchase 2wks</div>
                <div>230</div>
                <div>Customer also bough this other item</div>
                <div>43</div>
                <div>0.50%</div>
                <div>$282.830</div>
            </div>
    <div class="single-column-container">
                <div>2249</div>
                <div>25.5 cu. ft. French Door Refrigerator in Stainless Steel</div>
                <div>Online co-purchase 2wks</div>
                <div>230</div>
                <div>Customer also bough this other item</div>
                <div>43</div>
                <div>0.50%</div>
                <div>$282.830</div>
            </div>
    <div class="single-column-container">
                <div>2249</div>
                <div>25.5 cu. ft. French Door Refrigerator in Stainless Steel</div>
                <div>Online co-purchase 2wks</div>
                <div>230</div>
                <div>Customer also bough this other item</div>
                <div>43</div>
                <div>0.50%</div>
                <div>$282.830</div>
            </div>
    <div class="single-column-container">
                <div>2249</div>
                <div>25.5 cu. ft. French Door Refrigerator in Stainless Steel</div>
                <div>Online co-purchase 2wks</div>
                <div>230</div>
                <div>Customer also bough this other item</div>
                <div>43</div>
                <div>0.50%</div>
                <div>$282.830</div>
            </div>
    <div class="single-column-container">
                <div>2249</div>
                <div>25.5 cu. ft. French Door Refrigerator in Stainless Steel</div>
                <div>Online co-purchase 2wks</div>
                <div>230</div>
                <div>Customer also bough this other item</div>
                <div>43</div>
                <div>0.50%</div>
                <div>$282.830</div>
            </div>
    <div class="single-column-container">
                <div>2249</div>
                <div>25.5 cu. ft. French Door Refrigerator in Stainless Steel</div>
                <div>Online co-purchase 2wks</div>
                <div>230</div>
                <div>Customer also bough this other item</div>
                <div>43</div>
                <div>0.50%</div>
                <div>$282.830</div>
            </div>
    <div class="single-column-container">
                <div>2249</div>
                <div>25.5 cu. ft. French Door Refrigerator in Stainless Steel</div>
                <div>Online co-purchase 2wks</div>
                <div>230</div>
                <div>Customer also bough this other item</div>
                <div>43</div>
                <div>0.50%</div>
                <div>$282.830</div>
            </div>
        </div>
    </div>

    然后,我进入CSS网格布局,但我不太确定它应该看起来如何-与我当前的示例不同,所有“单元格”将在同一个单元中,因此我不确定如何修复第一列,也不确定如何设置CSS动态,这取决于要渲染的项目数。

    通知 :虽然我的代码将使用angularjs动态生成结构,但我相信问题是纯CSS/HTML(我希望避免使用javascript生成此结构)。

    1 回复  |  直到 6 年前
        1
  •  0
  •   Gonzalo.-    7 年前

    我最终通过使用css网格解决了这个问题。

    下面是一个带有essential的mock,但我当然会使用真实数据(以及正确加载的图像)。

    关键在于使用 grid-template-columns ng-style 动态指定列数

    我仍然错过了图片旁边的自定义滚动条,但我相信这是另一个故事

    (function(){
    
        function reportingTableController() {
          this.recommendations = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
        }
    
        angular
            .module('app', [])
            .component('reportingTable', {
                template: `<div class="reporting-table-container" ng-style="{'grid-template-columns': '90px repeat({{$ctrl.recommendations.length + 1}}, 130px)'}">
        <div style="grid-row:1;" class="row-label-title"></div>
        <div style="grid-row:2;" class="row-label-title">ID</div>
        <div style="grid-row:3;" class="row-label-title">Product Title</div>
        <div style="grid-row:4;" ng-style="{'grid-column-end': $ctrl.recommendations.length + 2}" class="orange-delimiter"></div>
        <div style="grid-row:5;" class="row-label-title">Strategy Name</div>
        <div style="grid-row:6;" class="row-label-title">Score</div>
        <div style="grid-row:7;" class="row-label-title">Message</div>
        <div style="grid-row:8" ng-style="{'grid-column-end': $ctrl.recommendations.length + 2}" class="orange-delimiter">></div>
        <div style="grid-row:9;" class="row-label-title">Feedback</div>
        <div style="grid-row:10;" class="row-label-title">Clicks</div>
        <div style="grid-row:11;" class="row-label-title">Conversion Rate</div>
        <div style="grid-row:12;" class="row-label-title">Revenue</div>
    
        <div ng-class-even="'even-cell'" class="reporting-table-cell" ng-style="{'grid-row': 1, 'grid-column': $index + 2 }" ng-repeat="recommendation in $ctrl.recommendations">
            <img src="Angular/app/RecommendationsTab/mock.png" alt="recommendation image" />
        </div>
    
        <div ng-class-even="'even-cell'" class="reporting-table-cell" ng-style="{'grid-row': 2, 'grid-column': $index + 2 }" ng-repeat="recommendation in $ctrl.recommendations">
            2249
        </div>
        
        <div ng-class-even="'even-cell'" class="reporting-table-cell" ng-style="{'grid-row': 3, 'grid-column': $index + 2 }" ng-repeat="recommendation in $ctrl.recommendations">
            25.5 cu. ft. French Door Refrigerator in Stainless Steel
        </div>
        
        <div ng-class-even="'even-cell'" class="reporting-table-cell" ng-style="{'grid-row': 5, 'grid-column': $index + 2 }" ng-repeat="recommendation in $ctrl.recommendations">
            Online co-purchase 2wks
        </div>
        
        <div ng-class-even="'even-cell'" class="reporting-table-cell" ng-style="{'grid-row': 6, 'grid-column': $index + 2 }" ng-repeat="recommendation in $ctrl.recommendations">
            230
        </div>
        
        <div ng-class-even="'even-cell'" class="reporting-table-cell" ng-style="{'grid-row': 7, 'grid-column': $index + 2 }" ng-repeat="recommendation in $ctrl.recommendations">
            Customer also bough this other item
        </div>
        
        <div ng-class-even="'even-cell'" class="reporting-table-cell" ng-style="{'grid-row': 9, 'grid-column': $index + 2 }" ng-repeat="recommendation in $ctrl.recommendations">
            Mailbox
        </div>
        
        <div ng-class-even="'even-cell'" class="reporting-table-cell" ng-style="{'grid-row': 10, 'grid-column': $index + 2 }" ng-repeat="recommendation in $ctrl.recommendations">
            43
        </div>
        
        <div ng-class-even="'even-cell'" class="reporting-table-cell" ng-style="{'grid-row': 11, 'grid-column': $index + 2 }" ng-repeat="recommendation in $ctrl.recommendations">
            0.50%
        </div>
        
        <div ng-class-even="'even-cell'" class="reporting-table-cell" ng-style="{'grid-row': 12, 'grid-column': $index + 2 }" ng-repeat="recommendation in $ctrl.recommendations">
            $282.830
        </div>
    </div>`,
                controller: reportingTableController,
            });
    })();
    .reporting-table-container {
        display:grid;
        padding-right: 10px;
        margin-bottom: 15px;
        margin-left: 25px;
        background-color: white;
        overflow-x: scroll;
    }
    
    .reporting-table-container .row-label-title {
        font-weight: 800;
        left: 0;
        position: sticky;
        grid-column: 1;
    }
    
    /* grid cells*/
    .reporting-table-container > div {
        padding-left: 6px;
        padding-right: 6px;
        padding-top: 8px;
        padding-bottom: 10px;
    }
    
    .reporting-table-container .row-label-title, 
    .reporting-table-container .reporting-table-cell.even-cell {
        background-color: #e9e9e9;
    }
    
    .reporting-table-container .reporting-table-cell, 
    .reporting-table-container .row-label-title {
        border-bottom: #d1d1d1 1px solid;
    }
    
    .reporting-table-container .row-label-title:first-of-type {
        background-color: white;
        border-bottom: none;
    }
    
    .reporting-table-container .orange-delimiter {
        border: 1px solid #f96302;
        background-color: white;
        grid-column-start: 1;
        height: 1px;
        margin-bottom: 3px;
        margin-top: 3px;
        padding: 0;
    }
    
    .reporting-table-container .reporting-table-cell > img {
        max-width: calc(100% - 12px);/* 12 px of padding*/
    }
    <script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.7.2/angular.min.js"></script>
    <body>
      <div ng-app="app">
       <reporting-table></reporting-table>
      </div>
    </body>