我需要实现这样的目标
向右滚动是动态的(列数是可变的),而在左侧的第一列是固定的。滚动应该使用图像顶部的箭头,但是我可以协商放弃它。
我的第一个想法是像这样使用flexbox(这是一个模拟示例,我将使用ng-repeat和angular来动态生成结构)
.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>
但是很快就发现标签列和数据列之间不会出现边界。此外,我无法(至少没有javascript)匹配同一行的高度(鉴于该行的最大数据,我应该扩展该行的高度)
然后我进入CSS网格布局,但是我不太确定它的外观-与当前示例不同,所有“单元格”都位于同一单元内,因此我不确定如何修复第一列如何设置CSS动态,具体取决于要渲染的项目数。
我该如何实现?
通知:尽管我的代码将使用angularjs动态生成结构,但我相信问题出在纯CSS / HTML上(我想避免使用JavaScript来生成该结构)。>
预先感谢
答案 0 :(得分:0)
我终于设法通过使用CSS网格来解决此问题。
以下是模拟的基本内容,但是我当然会使用真实数据(以及正确加载的图像)。
关键在于使用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>