带有垂直文本的冻结标题的表格
Posted
技术标签:
【中文标题】带有垂直文本的冻结标题的表格【英文标题】:Table with frozen header with vertical text 【发布时间】:2018-11-18 16:43:46 【问题描述】:我希望创建一个表格,其中线程被冻结并且主题中的标签以垂直方式定向。我的尝试如下,但是由于我对 css 非常陌生,因此此实现存在许多问题。
我不喜欢我的解决方案的一件事是,在您开始滚动表格之前,由于滚动条被隐藏,有更多行需要滚动到视图中并不明显。有没有办法让滚动条永久可见?
在上面的广告顶部还有一个大景观,其中显示了派对名称。我可以通过玩弄 th.vertical 中的值来扩大这个差距,但我无法消除它。如何强制标题仅与它包含的文本一样高?
最后,我希望thead 中的垂直文本相对于列值居中,但我还没有弄清楚如何做到这一点。我该怎么做?
我还希望能够对任何列进行排序。
table thead tr
display: block;
table th,
table td
width: 75px; //fixed width
div.vertical
margin-left: -100px;
position: absolute;
width: 210px;
transform: rotate(-90deg);
-webkit-transform: rotate(-90deg);
/* Safari/Chrome */
-moz-transform: rotate(-90deg);
/* Firefox */
-o-transform: rotate(-90deg);
/* Opera */
-ms-transform: rotate(-90deg);
/* IE 9 */
th.vertical
height: 60px;
line-height: 14px;
padding-bottom: 100px;
text-align: left;
table tbody
display: block;
height: 500px;
overflow: auto;
<table class='vrt-header'>
<thead>
<tr>
<th></th>
<th class="vertical">
<div class="vertical">Republican</div>
</th>
<th class="vertical">
<div class="vertical">Democrat</div>
</th>
<th class="vertical">
<div class="vertical">Libertarian</div>
</th>
<th class="vertical">
<div class="vertical">Green</div>
</th>
</tr>
</thead>
<tbody>
<tr>
<td>
Alabama
</td>
<td>
65
</td>
<td>
25
</td>
<td>
10
</td>
<td>
0
</td>
</tr>
<tr>
<td>
Alaska
</td>
<td>
75
</td>
<td>
15
</td>
<td>
10
</td>
<td>
0
</td>
</tr>
<tr>
<td>
Arizona
</td>
<td>
55
</td>
<td>
40
</td>
<td>
5
</td>
<td>
0
</td>
</tr>
<tr>
<td>
Arkansas
</td>
<td>
65
</td>
<td>
25
</td>
<td>
10
</td>
<td>
0
</td>
</tr>
<tr>
<td>
California
</td>
<td>
25
</td>
<td>
65
</td>
<td>
3
</td>
<td>
7
</td>
</tr>
<tr>
<td>
?
</td>
<td>
0
</td>
<td>
0
</td>
<td>
0
</td>
<td>
0
</td>
</tr>
<tr>
<td>
?
</td>
<td>
0
</td>
<td>
0
</td>
<td>
0
</td>
<td>
0
</td>
</tr>
<tr>
<td>
?
</td>
<td>
0
</td>
<td>
0
</td>
<td>
0
</td>
<td>
0
</td>
</tr>
<tr>
<td>
?
</td>
<td>
0
</td>
<td>
0
</td>
<td>
0
</td>
<td>
0
</td>
</tr>
<tr>
<td>
?
</td>
<td>
0
</td>
<td>
0
</td>
<td>
0
</td>
<td>
0
</td>
</tr>
<tr>
<td>
?
</td>
<td>
0
</td>
<td>
0
</td>
<td>
0
</td>
<td>
0
</td>
</tr>
<tr>
<td>
?
</td>
<td>
0
</td>
<td>
0
</td>
<td>
0
</td>
<td>
0
</td>
</tr>
<tr>
<td>
?
</td>
<td>
0
</td>
<td>
0
</td>
<td>
0
</td>
<td>
0
</td>
</tr>
<tr>
<td>
?
</td>
<td>
0
</td>
<td>
0
</td>
<td>
0
</td>
<td>
0
</td>
</tr>
<tr>
<td>
?
</td>
<td>
0
</td>
<td>
0
</td>
<td>
0
</td>
<td>
0
</td>
</tr>
<tr>
<td>
?
</td>
<td>
0
</td>
<td>
0
</td>
<td>
0
</td>
<td>
0
</td>
</tr>
<tr>
<td>
?
</td>
<td>
0
</td>
<td>
0
</td>
<td>
0
</td>
<td>
0
</td>
</tr>
<tr>
<td>
?
</td>
<td>
0
</td>
<td>
0
</td>
<td>
0
</td>
<td>
0
</td>
</tr>
<tr>
<td>
?
</td>
<td>
0
</td>
<td>
0
</td>
<td>
0
</td>
<td>
0
</td>
</tr>
<tr>
<td>
?
</td>
<td>
0
</td>
<td>
0
</td>
<td>
0
</td>
<td>
0
</td>
</tr>
<tr>
<td>
?
</td>
<td>
0
</td>
<td>
0
</td>
<td>
0
</td>
<td>
0
</td>
</tr>
<tr>
<td>
?
</td>
<td>
0
</td>
<td>
0
</td>
<td>
0
</td>
<td>
0
</td>
</tr>
<tr>
<td>
?
</td>
<td>
0
</td>
<td>
0
</td>
<td>
0
</td>
<td>
0
</td>
</tr>
<tr>
<td>
?
</td>
<td>
0
</td>
<td>
0
</td>
<td>
0
</td>
<td>
0
</td>
</tr>
<tr>
<td>
?
</td>
<td>
0
</td>
<td>
0
</td>
<td>
0
</td>
<td>
0
</td>
</tr>
<tr>
<td>
?
</td>
<td>
0
</td>
<td>
0
</td>
<td>
0
</td>
<td>
0
</td>
</tr>
<tr>
<td>
?
</td>
<td>
0
</td>
<td>
0
</td>
<td>
0
</td>
<td>
0
</td>
</tr>
<tr>
<td>
?
</td>
<td>
0
</td>
<td>
0
</td>
<td>
0
</td>
<td>
0
</td>
</tr>
<tr>
<td>
?
</td>
<td>
0
</td>
<td>
0
</td>
<td>
0
</td>
<td>
0
</td>
</tr>
<tr>
<td>
?
</td>
<td>
0
</td>
<td>
0
</td>
<td>
0
</td>
<td>
0
</td>
</tr>
</tbody>
</table>
【问题讨论】:
您一共问了 4 个问题。尝试将它们分解为多个问题。它使回答更容易,并且其他人更有可能遇到相关问题。 不确定我是否完全理解了这个问题。 A)固定列的宽度使这更容易处理,这是你一直想要的吗? B)您是否考虑过写作模式而不是 position+transform ? C) 滚动条的宽度通常在 1.2rem 左右,填充在这里有帮助吗? D) 如果 div 是 inline-block,那么 text-align 就可以了。这里有一个代码笔来测试这条评论:codepen.io/gc-nomade/pen/YvrMeN(灵感来自codepen.io/gc-nomade/pen/EKQKBe &)否则通过垂直边距/填充的特殊性在通量中旋转codepen.io/gc-nomade/pen/Cqkig 还有 position:sticky 看不看codepen.io/gc-nomade/pen/Lrzvox 【参考方案1】:你想做的不是一件容易的事。我会用 div 替换你的表格。
我写了一个例子,让你知道它的外观:
<div class='table'>
<div class='header'>
<div ><p class="vertical first"> </p></div>
<div ><p class="vertical">Republican</p></div>
<div ><p class="vertical">Democrat</p></div>
<div ><p class="vertical">Libertarian</p></div>
<div ><p class="vertical">Green</p></div>
</div>
<div class='scroller'>
<div class='content'>
<div>
<div>Alabama</div>
<div>65</div>
<div>25</div>
<div>10</div>
<div>0</div>
</div>
<div>
<div>Alaska</div>
<div>65</div>
<div>25</div>
<div>10</div>
<div>0</div>
</div>
<div>
<div>Arizona</div>
<div>65</div>
<div>25</div>
<div>10</div>
<div>0</div>
</div>
<div>
<div>Arzkansas</div>
<div>65</div>
<div>25</div>
<div>10</div>
<div>0</div>
</div>
<div>
<div>Arzkansas</div>
<div>65</div>
<div>25</div>
<div>10</div>
<div>0</div>
</div>
<div>
<div>Arzkansas</div>
<div>65</div>
<div>25</div>
<div>10</div>
<div>0</div>
</div>
<div>
<div>Arzkansas</div>
<div>65</div>
<div>25</div>
<div>10</div>
<div>0</div>
</div>
<div>
<div>Arzkansas</div>
<div>65</div>
<div>25</div>
<div>10</div>
<div>0</div>
</div>
<div>
<div>Arzkansas</div>
<div>65</div>
<div>25</div>
<div>10</div>
<div>0</div>
</div>
<div>
<div>Arzkansas</div>
<div>65</div>
<div>25</div>
<div>10</div>
<div>0</div>
</div>
<div>
<div>Arzkansas</div>
<div>65</div>
<div>25</div>
<div>10</div>
<div>0</div>
</div>
<div>
<div>Arzkansas</div>
<div>65</div>
<div>25</div>
<div>10</div>
<div>0</div>
</div>
<div>
<div>Arzkansas</div>
<div>65</div>
<div>25</div>
<div>10</div>
<div>0</div>
</div>
<div>
<div>Arzkansas</div>
<div>65</div>
<div>25</div>
<div>10</div>
<div>0</div>
</div>
<div>
<div>Arzkansas</div>
<div>65</div>
<div>25</div>
<div>10</div>
<div>0</div>
</div>
</div>
</div>
</div>
.table
height:300px;
width:500px;
.vertical
transform: rotate(-90deg);
width:56px;
margin:0px;
.first
padding-right: 268px;
.header
height:150px;
width:500px;
display:flex;
.header>div
display:flex;
.scroller
height:calc(100% - 50px);
overflow-y:scroll;
.content
width:100%;
display:table;
.content>div
display:table-row;
width:500px;
.content>div>div
display:table-cell;
http://jsfiddle.net/xjhun7zf/6/`
(它并不完美,因为我在 20 分钟内就写好了)
如果您有 2 个容器,一个用于头部,一个用于身体,那么您可以将头部设置为具有固定高度的静态位置,将您的身体设置为静止高度;
【讨论】:
【参考方案2】:1) 这可能是在默认情况下使用覆盖滚动条的 Mac 上。 Chrome 和 Safari 支持 webkit-scroll 属性,可让您使其始终可见,但不确定是否可以在 Firefox 中覆盖它。
2) 您可能遇到了UA style sheet 的th
条目:td, th padding: 1px;
您可以使用th padding: 0px;
覆盖它
3) 你想要的实际上是表的默认行为。但它不起作用有两个原因。如果不使用现成的组件,这可能是您自己解决的最困难的问题。因此,除非您将此作为练习,否则我建议不要尝试重新发明***。相反,找到一个 jquery 插件或角度组件或提供此功能的东西。我认为在不编写一堆 javascript 的情况下以跨浏览器兼容的方式完成所有这些(包括旋转标题)是不可能的。
第一个原因是设置div.vertical position:absolute
会使它们脱离正常流程; th
将其正常流子定位为与整个列对齐,但不是 position:absolute
的东西。
其次,您巧妙地创建了 3 个表格,因为 tr display:block
和允许滚动的 tbody display:block
。布局代码(大约)将它们视为常规的<div>
s,因此会看到<table><thead><div>...</div></thead><div>....</div></table>
,并创建一个表格单元格、行和部分(又名tbody)来保存每个<div>
。然后在 div
里面看到 tr
所以创建一个 table
来保存它们。
因此,thead > tr
下的表中的列与保存数据的列不同。因此,即使您解决了第一个原因,您仍然会为此抗争。
这是 chrome 的布局树(忽略十六进制):
LayoutBlockFlow 0x23e069224010 html
LayoutBlockFlow 0x23e069224138 BODY
LayoutTable 0x23e069230010 TABLE class="vrt-header"
LayoutTableSection 0x23e069240010 THEAD
LayoutTableRow (anonymous) 0x23e06924c010
LayoutTableCell (anonymous) 0x23e069254010
LayoutBlockFlow 0x23e069224260 TR
LayoutTable (anonymous) 0x23e0692301b0
LayoutTableSection (anonymous) 0x23e069240188
LayoutTableRow (anonymous) 0x23e06924c128
LayoutTableCell 0x23e069254150 TH
LayoutTableCell 0x23e069254290 TH class="vertical"
LayoutBlockFlow (positioned) 0x23e069224388 DIV class="vertical"
LayoutText 0x23e069264010 #text "Republican"
LayoutTableCell 0x23e0692543d0 TH class="vertical"
LayoutBlockFlow (positioned) 0x23e0692244b0 DIV class="vertical"
LayoutText 0x23e0692640e0 #text "Democrat"
LayoutTableCell 0x23e069254510 TH class="vertical"
LayoutBlockFlow (positioned) 0x23e0692245d8 DIV class="vertical"
LayoutText 0x23e0692641b0 #text "Libertarian"
LayoutTableCell 0x23e069254650 TH class="vertical"
LayoutBlockFlow (positioned) 0x23e069224700 DIV class="vertical"
LayoutText 0x23e069264280 #text "Green"
LayoutTableSection (anonymous) 0x23e069240300
LayoutTableRow (anonymous) 0x23e06924c240
LayoutTableCell (anonymous) 0x23e069254790
LayoutBlockFlow 0x23e069224828 TBODY
LayoutTable (anonymous) 0x23e069230350
LayoutTableSection (anonymous) 0x23e069240478
LayoutTableRow 0x23e06924c358 TR
LayoutTableCell 0x23e0692548d0 TD
LayoutText 0x23e069264350 #text "\nAlabama\n"
LayoutTableCell 0x23e069254a10 TD
LayoutText 0x23e069264420 #text "\n65\n"
LayoutTableCell 0x23e069254b50 TD
LayoutText 0x23e0692644f0 #text "\n25\n"
LayoutTableCell 0x23e069254c90 TD
LayoutText 0x23e0692645c0 #text "\n10\n"
LayoutTableCell 0x23e069254dd0 TD
LayoutText 0x23e069264690 #text "\n0\n"
LayoutTableRow 0x23e06924c470 TR
LayoutTableCell 0x23e069254f10 TD
LayoutText 0x23e069264760 #text "\nAlaska\n"
【讨论】:
【参考方案3】:我玩过你的代码……
-
我不知道除了
overflow-y: scroll;
之外的另一种始终显示滚动条的方式。
我修改了所有标题的样式,但我找不到一种简单的方法来自动调整transform
之后的高度。我使用了一个固定值。
新样式正在纠正这一点。
我建议您尝试阅读有关 jQuery 的 Stupid-Table-Plugin 以轻松对表格进行排序。
…另外,我补充说:
:hover
上的一些样式以突出 th
s 上的操作。
使用:nth-of-type()
选择器为行替换颜色。
……我最终得到了这个 sn-p:
// Doc here: https://joequery.github.io/Stupid-Table-Plugin/
$("#simpleTable").stupidtable();
table thead,
table tbody
display: block;
table tbody
height: 500px;
overflow-y: scroll; /* To make the scroll bar always visible */
thead th
position: relative;
cursor: pointer; /* change cursor to show we can do an action */
height: 90px;
background: #ccc;
border-bottom: 2px solid black;
thead th:hover
background: #ccf; /* Styling on hover */
thead th p
position: absolute;
bottom: 20px;
transform: rotate(-90deg);
text-align: left;
table th,
table th p,
table td
width: 75px;
table td
text-align: center;
table tr td:first-of-type
text-align: left;
table tr:nth-of-type(odd) td
background: #eee;
table tr:nth-of-type(even) td
background: #ddd;
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/stupidtable/1.1.3/stupidtable.min.js"></script>
<table id="simpleTable" class='vrt-header'>
<thead>
<tr>
<th data-sort="string"></th>
<th data-sort="int">
<p>Republican</p>
</th>
<th data-sort="int">
<p>Democrat</p>
</th>
<th data-sort="int">
<p>Libertarian</p>
</th>
<th data-sort="int">
<p>Green</p>
</th>
</tr>
</thead>
<tbody>
<tr>
<td>
Alabama
</td>
<td>
65
</td>
<td>
25
</td>
<td>
10
</td>
<td>
0
</td>
</tr>
<tr>
<td>
Alaska
</td>
<td>
75
</td>
<td>
15
</td>
<td>
10
</td>
<td>
0
</td>
</tr>
<tr>
<td>
Arizona
</td>
<td>
55
</td>
<td>
40
</td>
<td>
5
</td>
<td>
0
</td>
</tr>
<tr>
<td>
Arkansas
</td>
<td>
65
</td>
<td>
25
</td>
<td>
10
</td>
<td>
0
</td>
</tr>
<tr>
<td>
California
</td>
<td>
25
</td>
<td>
65
</td>
<td>
3
</td>
<td>
7
</td>
</tr>
<tr>
<td>
?
</td>
<td>
0
</td>
<td>
0
</td>
<td>
0
</td>
<td>
0
</td>
</tr>
<tr>
<td>
?
</td>
<td>
0
</td>
<td>
0
</td>
<td>
0
</td>
<td>
0
</td>
</tr>
<tr>
<td>
?
</td>
<td>
0
</td>
<td>
0
</td>
<td>
0
</td>
<td>
0
</td>
</tr>
<tr>
<td>
?
</td>
<td>
0
</td>
<td>
0
</td>
<td>
0
</td>
<td>
0
</td>
</tr>
<tr>
<td>
?
</td>
<td>
0
</td>
<td>
0
</td>
<td>
0
</td>
<td>
0
</td>
</tr>
<tr>
<td>
?
</td>
<td>
0
</td>
<td>
0
</td>
<td>
0
</td>
<td>
0
</td>
</tr>
<tr>
<td>
?
</td>
<td>
0
</td>
<td>
0
</td>
<td>
0
</td>
<td>
0
</td>
</tr>
<tr>
<td>
?
</td>
<td>
0
</td>
<td>
0
</td>
<td>
0
</td>
<td>
0
</td>
</tr>
<tr>
<td>
?
</td>
<td>
0
</td>
<td>
0
</td>
<td>
0
</td>
<td>
0
</td>
</tr>
<tr>
<td>
?
</td>
<td>
0
</td>
<td>
0
</td>
<td>
0
</td>
<td>
0
</td>
</tr>
<tr>
<td>
?
</td>
<td>
0
</td>
<td>
0
</td>
<td>
0
</td>
<td>
0
</td>
</tr>
<tr>
<td>
?
</td>
<td>
0
</td>
<td>
0
</td>
<td>
0
</td>
<td>
0
</td>
</tr>
<tr>
<td>
?
</td>
<td>
0
</td>
<td>
0
</td>
<td>
0
</td>
<td>
0
</td>
</tr>
<tr>
<td>
?
</td>
<td>
0
</td>
<td>
0
</td>
<td>
0
</td>
<td>
0
</td>
</tr>
<tr>
<td>
?
</td>
<td>
0
</td>
<td>
0
</td>
<td>
0
</td>
<td>
0
</td>
</tr>
<tr>
<td>
?
</td>
<td>
0
</td>
<td>
0
</td>
<td>
0
</td>
<td>
0
</td>
</tr>
<tr>
<td>
?
</td>
<td>
0
</td>
<td>
0
</td>
<td>
0
</td>
<td>
0
</td>
</tr>
<tr>
<td>
?
</td>
<td>
0
</td>
<td>
0
</td>
<td>
0
</td>
<td>
0
</td>
</tr>
<tr>
<td>
?
</td>
<td>
0
</td>
<td>
0
</td>
<td>
0
</td>
<td>
0
</td>
</tr>
<tr>
<td>
?
</td>
<td>
0
</td>
<td>
0
</td>
<td>
0
</td>
<td>
0
</td>
</tr>
<tr>
<td>
?
</td>
<td>
0
</td>
<td>
0
</td>
<td>
0
</td>
<td>
0
</td>
</tr>
<tr>
<td>
?
</td>
<td>
0
</td>
<td>
0
</td>
<td>
0
</td>
<td>
0
</td>
</tr>
<tr>
<td>
?
</td>
<td>
0
</td>
<td>
0
</td>
<td>
0
</td>
<td>
0
</td>
</tr>
<tr>
<td>
?
</td>
<td>
0
</td>
<td>
0
</td>
<td>
0
</td>
<td>
0
</td>
</tr>
<tr>
<td>
?
</td>
<td>
0
</td>
<td>
0
</td>
<td>
0
</td>
<td>
0
</td>
</tr>
</tbody>
</table>
希望对你有帮助。
【讨论】:
感谢您的回答。假设我将加利福尼亚重命名为 SouthernCalifornia(一个单词),那么第一列的宽度不会反映在表头中,如以下小提琴所示:jsfiddle.net/61avLpzr/3。你会如何纠正这个问题? @Baz 我认为更简单的方法是给第一列一个固定的width
(参见这个sn-p中CSS的开头:jsfiddle.net/awc80hkg/1)【参考方案4】:
我做了你所要求的一切,全部 4 个,几乎只使用 css。
测试它:https://jsfiddle.net/xpvt214o/246746/show 或 见代码小提琴:https://jsfiddle.net/xpvt214o/246746/我也可以只用 CSS 编写第三个问题!我使用填充和 div 包装器设置高度。像这样:
th.vertical
height: 0;
vertical-align: bottom;
text-align: left;
cursor: pointer;
div.verticalWrapper
height: 0;
padding-top: 100%;
position: relative;
注意padding-top: 100%
1) 我为此创建了一个表格容器 div。
.tableContainer
height: 400px;
width: 500px;
overflow: scroll;
对于 ios,这只是一个偏好问题:https://heresthethingblog.com/2015/03/10/mac-tip-macs-scroll-bars/
2) 由于我们正在旋转元素,我们需要一个等于宽度的高度。我使用 css 来做到这一点,您可以阅读相关答案here
3) 我使用了 css 转换。
4) 使用与@takit-isy相同的方法
【讨论】:
标头未冻结。以上是关于带有垂直文本的冻结标题的表格的主要内容,如果未能解决你的问题,请参考以下文章