边框样式不适用于粘贴位置元素

我不知道为什么我的边框样式不与 position: sticky;属性工作。我想设置我的粘贴表头边框样式。但是我不想使用透明的背景颜色。我怎样才能做到呢?这里是我的问题和 JSFiddle Link的样本代码

#wrapper {
width: 400px;
height: 200px;
overflow: auto;
}


table {
width: 100%;
text-align: center;
border-collapse: collapse;
}


table tr th,
table tr td {
border: 2px solid;
}


table thead th {
position: -webkit-sticky;
position: sticky;
top: 0;
background-color: #edecec;
}
<div id="wrapper">
<table>
<thead>
<tr>
<th>A</th>
<th>B</th>
<th>C</th>
<th>D</th>
<th>E</th>
</tr>
</thead>
<tr>
<td>1</td>
<td>1</td>
<td>1</td>
<td>1</td>
<td>1</td>
</tr>
<tr>
<td>2</td>
<td>2</td>
<td>2</td>
<td>2</td>
<td>2</td>
</tr>
<tr>
<td>3</td>
<td>3</td>
<td>3</td>
<td>3</td>
<td>3</td>
</tr>
<tr>
<td>4</td>
<td>4</td>
<td>4</td>
<td>4</td>
<td>4</td>
</tr>
<tr>
<td>5</td>
<td>5</td>
<td>5</td>
<td>5</td>
<td>5</td>
</tr>
<tr>
<td>6</td>
<td>6</td>
<td>6</td>
<td>6</td>
<td>6</td>
</tr>
<tr>
<td>7</td>
<td>7</td>
<td>7</td>
<td>7</td>
<td>7</td>
</tr>
<tr>
<td>8</td>
<td>8</td>
<td>8</td>
<td>8</td>
<td>8</td>
</tr>
<tr>
<td>9</td>
<td>9</td>
<td>9</td>
<td>9</td>
<td>9</td>
</tr>
<tbody>
</tbody>
</table>
</div>

下面是我想要什么和谁没有足够清楚我的问题的截图。

enter image description here

可以看到 th的内联边框样式不起作用(删除 CSS 的 position属性,你会看到附近的粗体。)。

enter image description here

向下滚动一下,你会看到所有的边框样式都不见了。

91371 次浏览

使用 table thead th代替 table thead。 这是演示。 < a href = “ https://jsfiddle.net/nhatphhamcdn/9dhqchtu/”rel = “ nofollow norefrer”> https://jsfiddle.net/nhatphamcdn/9dhqchtu/

因为粘性定位在相对和固定之间波动,我能想到的规避这种开箱即用的唯一方法就是利用 psuedo 类。

我相信有一个更优雅的方式来实现这一点,但我只是改变了 :after:before的 suedo 类,以提供绝对定位的边界。

#wrapper {
width: 400px;
height: 200px;
overflow: auto;
}


table {
width: 100%;
text-align: center;
border-collapse: collapse;
}


table tr th,
table tr td {
border: 2px solid;
}


table thead th {
position: -webkit-sticky;
position: sticky;
top: -1px;
background-color: #edecec;
}
th:after,
th:before {
content: '';
position: absolute;
left: 0;
width: 100%;
}
th:before {
top: 0;
border-top: 3px solid blue;
}
th:after {
bottom: 0;
border-bottom: 3px solid blue;
}
<div id="wrapper">
<table>
<thead>
<tr>
<th>A</th>
<th>B</th>
<th>C</th>
<th>D</th>
<th>E</th>
</tr>
</thead>
<tr>
<td>1</td>
<td>1</td>
<td>1</td>
<td>1</td>
<td>1</td>
</tr>
<tr>
<td>2</td>
<td>2</td>
<td>2</td>
<td>2</td>
<td>2</td>
</tr>
<tr>
<td>3</td>
<td>3</td>
<td>3</td>
<td>3</td>
<td>3</td>
</tr>
<tr>
<td>4</td>
<td>4</td>
<td>4</td>
<td>4</td>
<td>4</td>
</tr>
<tr>
<td>5</td>
<td>5</td>
<td>5</td>
<td>5</td>
<td>5</td>
</tr>
<tr>
<td>6</td>
<td>6</td>
<td>6</td>
<td>6</td>
<td>6</td>
</tr>
<tr>
<td>7</td>
<td>7</td>
<td>7</td>
<td>7</td>
<td>7</td>
</tr>
<tr>
<td>8</td>
<td>8</td>
<td>8</td>
<td>8</td>
<td>8</td>
</tr>
<tr>
<td>9</td>
<td>9</td>
<td>9</td>
<td>9</td>
<td>9</td>
</tr>
<tr>
<td>9</td>
<td>9</td>
<td>9</td>
<td>9</td>
<td>9</td>
</tr>
<tr>
<td>9</td>
<td>9</td>
<td>9</td>
<td>9</td>
<td>9</td>
</tr>
<tr>
<td>9</td>
<td>9</td>
<td>9</td>
<td>9</td>
<td>9</td>
</tr>
<tr>
<td>9</td>
<td>9</td>
<td>9</td>
<td>9</td>
<td>9</td>
</tr>
<tr>
<td>9</td>
<td>9</td>
<td>9</td>
<td>9</td>
<td>9</td>
</tr>
<tr>
<td>9</td>
<td>9</td>
<td>9</td>
<td>9</td>
<td>9</td>
</tr>
<tr>
<td>9</td>
<td>9</td>
<td>9</td>
<td>9</td>
<td>9</td>
</tr>
<tr>
<td>9</td>
<td>9</td>
<td>9</td>
<td>9</td>
<td>9</td>
</tr>
<tr>
<td>9</td>
<td>9</td>
<td>9</td>
<td>9</td>
<td>9</td>
</tr>
<tr>
<td>9</td>
<td>9</td>
<td>9</td>
<td>9</td>
<td>9</td>
</tr>
<tr>
<td>9</td>
<td>9</td>
<td>9</td>
<td>9</td>
<td>9</td>
</tr>
<tr>
<td>9</td>
<td>9</td>
<td>9</td>
<td>9</td>
<td>9</td>
</tr>
<tr>
<td>9</td>
<td>9</td>
<td>9</td>
<td>9</td>
<td>9</td>
</tr>
<tr>
<td>9</td>
<td>9</td>
<td>9</td>
<td>9</td>
<td>9</td>
</tr>
<tr>
<td>9</td>
<td>9</td>
<td>9</td>
<td>9</td>
<td>9</td>
</tr>
<tr>
<td>9</td>
<td>9</td>
<td>9</td>
<td>9</td>
<td>9</td>
</tr>
<tr>
<td>9</td>
<td>9</td>
<td>9</td>
<td>9</td>
<td>9</td>
</tr>
<tr>
<td>9</td>
<td>9</td>
<td>9</td>
<td>9</td>
<td>9</td>
</tr>
<tr>
<td>9</td>
<td>9</td>
<td>9</td>
<td>9</td>
<td>9</td>
</tr>
<tr>
<td>9</td>
<td>9</td>
<td>9</td>
<td>9</td>
<td>9</td>
</tr>
<tbody>
</tbody>
</table>
</div>

现在我可以使用用户@soulshined 建议的 psuedo classes设置边框样式。下面是 css 的工作变化,这里是 JSFiddle Link。已经在铬和火狐上测试过了。

#wrapper {
width: 400px;
height: 200px;
overflow: auto;
padding: 1px;
}


table {
width: 100%;
text-align: center;
border-collapse: collapse;
}
table tr th {
border: 1px solid green;
}
table tr th:first-child {
border-left: 1px solid green;
}
table tr td {
border: 1px solid green;
}


table thead th {
position: -webkit-sticky;
position: sticky;
top: 0;
background-color: #edecec;
}


th::before {
content: '';
position: absolute;
left: 0;
width: 100%;
height: 100%;
border-right: 1px solid green;
display: block;
top : 1px;
}


th::after {
content: '';
position: absolute;
left: 0;
width: 100%;
height: 100%;
border-bottom: 1px solid green;
border-top: 1px solid green;
display: block;
top : -1px;
}

您需要使用 box-shadow属性而不是 border-top/border-bottom。此外,还需要删除表格头部和第一行的顶部/底部边框。

#wrapper {
width: 400px;
height: 200px;
overflow: auto;
}


table {
width: 100%;
text-align: center;
border-collapse: collapse;
}


table tr th,
table tr td {
border: 2px solid;
}


table thead th {
position: -webkit-sticky;
position: sticky;
top: 0;
background-color: #edecec;
}




/* here is the trick */


table tbody:nth-of-type(1) tr:nth-of-type(1) td {
border-top: none !important;
}


table thead th {
border-top: none !important;
border-bottom: none !important;
box-shadow: inset 0 2px 0 #000000, inset 0 -2px 0 #000000;
padding: 2px 0;
}




/* and one small fix for weird FF behavior, described in https://stackoverflow.com/questions/7517127/ */


table thead th {
background-clip: padding-box
}
<body>
<div id="wrapper">
<table>
<thead>
<tr>
<th>A</th>
<th>B</th>
<th>C</th>
<th>D</th>
<th>E</th>
</tr>
</thead>
<tbody>
<tr>
<td>1</td>
<td>1</td>
<td>1</td>
<td>1</td>
<td>1</td>
</tr>
<tr>
<td>2</td>
<td>2</td>
<td>2</td>
<td>2</td>
<td>2</td>
</tr>
<tr>
<td>3</td>
<td>3</td>
<td>3</td>
<td>3</td>
<td>3</td>
</tr>
<tr>
<td>4</td>
<td>4</td>
<td>4</td>
<td>4</td>
<td>4</td>
</tr>
<tr>
<td>5</td>
<td>5</td>
<td>5</td>
<td>5</td>
<td>5</td>
</tr>
<tr>
<td>6</td>
<td>6</td>
<td>6</td>
<td>6</td>
<td>6</td>
</tr>
<tr>
<td>7</td>
<td>7</td>
<td>7</td>
<td>7</td>
<td>7</td>
</tr>
<tr>
<td>8</td>
<td>8</td>
<td>8</td>
<td>8</td>
<td>8</td>
</tr>
<tr>
<td>9</td>
<td>9</td>
<td>9</td>
<td>9</td>
<td>9</td>
</tr>
</tbody>
</table>
</div>
</body>

这个问题是因为使用了 border-collapse: collapse而发生的。当浏览器折叠边框时,<th>上下边框必须应用于周围的元素ーー <table>的上边框和 <tr>的底边框。

如果您使用 border-collapse: separate并将您的边框设置为位于一侧,则边框将真正连接到 <th>,按照预期保持固定,并显示为折叠。

下面是可以应用于 HTML 代码片段的示例样式。

#wrapper {
width: 400px;
height: 200px;
overflow: auto;
}


table {
width: 100%;
text-align: center;
border-collapse: separate; /* Don't collapse */
border-spacing: 0;
}


table th {
/* Apply both top and bottom borders to the <th> */
border-top: 2px solid;
border-bottom: 2px solid;
border-right: 2px solid;
}


table td {
/* For cells, apply the border to one of each side only (right but not left, bottom but not top) */
border-bottom: 2px solid;
border-right: 2px solid;
}


table th:first-child,
table td:first-child {
/* Apply a left border on the first <td> or <th> in a row */
border-left: 2px solid;
}


table thead th {
position: sticky;
top: 0;
background-color: #edecec;
}

我相信这是最简单的答案。

接受的答案不提供1px 边界的解决方案。

注意: 这是一个工作周围,所以不要抱怨我。

如果从表头中删除 border-top,则表没有要折叠的内容,因此不会创建空间来查看底层单元格。在保持 DIV 中用相同样式的边框替换 border-top

Css:

table thead tr:nth-child(1) th {
position: sticky;
border-top:0;
}


.table_holder {
border-top:1px solid black;
}

Html:

<div id="table_holder">
<table> ... </table>
</div>
  1. 头部边框可见的粘性

html{
padding: 0px;
margin: 0px;
}
body{
padding: 0px;
margin: 0px;
width:100%;
}


th,td{
padding:10px;
border: 0.1px solid #e8e0e0;
padding-right:10px;
}
th{
text-align: center;
background: #f3f3f3;
background-clip: padding-box;
}




thead th:first-child {
left: 0;
z-index: 1;
}
tbody th:first-child  {
text-align: center;
position: -webkit-sticky; /* for Safari */
position: sticky;
left: 0;
 

}
tbody th,thead th:first-child  {
/* display:flex; */
/* text-align: center;
align-items: center;
align-self: center; */
width:30px;
    

min-width: 30px;
max-width: 30px;
word-break: break-all;
}
.fixed_header{
width: 100%;
/* height: 500px; */
table-layout: fixed;
border-collapse: collapse;
}
/* .fixed_header tbody{
overflow: auto;
 

} */


/* fixed header */
thead th {
/* for Safari */
text-align: center;
position: -webkit-sticky;
position: sticky;


top: 0;




}


.fixed_header th, .fixed_header td {
padding:10px;
/* text-align: left; */
width: 90px;
}


.fixed_header td{
/* padding:10px; */
/* word-break: break-all; */
/* max-width: 200px; */
}
.table_container{
/* position: fixed; */
position: relative;
width:100% ;
min-height: 500px;
overflow: auto;
background:cornsilk;
}
 <table class="fixed_header">
<thead>
<tr>
<th></th>
<th>Col 1</th>
<th>Col 2</th>
<th>Col 3</th>
<th>Col 4</th>
<th>Col 5</th>
<th>Col 1</th>
<th>Col 2</th>
<th>Col 3</th>
<th>Col 4</th>
<th>Col 5</th>
<th>Col 1</th>
<th>Col 2</th>
<th>Col 3</th>
<th>Col 4</th>
<th>Col 5</th>
<th>Col 1</th>
<th>Col 2</th>
<th>Col 3</th>
<th>Col 4</th>
<th>Col 5</th>
</tr>
</thead>
<tbody>
<tr>
<th>1</th>
<td>row 1-1</td>
<td>row 1-2</td>
<td>row 1-3</td>
<td>row 1-4</td>
<td>row 1-1</td>
<td>row 1-2</td>
<td>row 1-3</td>
<td>row 1-4</td>
<td>row 1-1</td>
<td>row 1-2</td>
<td>row 1-3</td>
<td>row 1-4</td>
<td>row 1-1</td>
<td>row 1-2</td>
<td>row 1-3</td>
<td>row 1-4</td>
<td>row 1-1</td>
<td>row 1-2</td>
<td>row 1-3</td>
<td>row 1-4</td>
</tr>


</tbody>
</table>
</div>

尝试了一些现有的答案,但正如评论所提到的,他们导致了一个像素的差距之间的边框。

制作了一个变通方案,虽然它需要 JavaScript。它在每个 <th>中放置一个 <div>,在调整大小时它适合 <div><th>。然后将 <th>边框应用于 <div>

注意: 在撰写本文时,position: sticky不能在 <thead>的 Chromium 中工作,它能在 Firefox 中工作。但是,如果没有执行 JavaScript,则与 position: sticky相关的 CSS 不会影响页面。

在浏览器中单击 Run code snippet查看是否有效。

function onResize() {
$("thead th div").each(function () {
var width = $(this).parent().outerWidth() - 2; // -2 * border-width
$(this).css("width", width + "px");
});
}


$("thead th").each(function () {
$(this).append($("<div>"));
});


$(window).on("resize", onResize);
onResize();
table {
width: 100%;
border-collapse: collapse;
}


th {
text-align: left;
}


th, td {
padding: 12px 20px;


border: 1px solid rgba(0, 0, 0, 0.125);
}


table thead {
position: sticky;
top: 0;


background: #FFF;
}


/* Used as a workaround for position: sticky not rendering the border */
thead th div {
width: 30px;
margin: 0 -20px; /* -20px to negate the 20px from the padding */
position: absolute;
top: 0;
bottom: 0;
z-index: -1;


border-right: 1px solid rgba(0, 0, 0, 0.125);
border-bottom: 1px solid rgba(0, 0, 0, 0.125);
}
<script src="https://code.jquery.com/jquery-3.4.1.min.js"></script>


<table>
<thead>
<tr>
<th>A</th>
<th>B</th>
<th>C</th>
<th>D</th>
</tr>
</thead>
<tbody>
<tr><td>1</td><td>2</td><td>3</td><td>4</td></tr>
<tr><td>1</td><td>2</td><td>3</td><td>4</td></tr>
<tr><td>1</td><td>2</td><td>3</td><td>4</td></tr>
<tr><td>1</td><td>2</td><td>3</td><td>4</td></tr>


<tr><td>1</td><td>2</td><td>3</td><td>4</td></tr>
<tr><td>1</td><td>2</td><td>3</td><td>4</td></tr>
<tr><td>1</td><td>2</td><td>3</td><td>4</td></tr>
<tr><td>1</td><td>2</td><td>3</td><td>4</td></tr>


<tr><td>1</td><td>2</td><td>3</td><td>4</td></tr>
<tr><td>1</td><td>2</td><td>3</td><td>4</td></tr>
<tr><td>1</td><td>2</td><td>3</td><td>4</td></tr>
<tr><td>1</td><td>2</td><td>3</td><td>4</td></tr>


<tr><td>1</td><td>2</td><td>3</td><td>4</td></tr>
<tr><td>1</td><td>2</td><td>3</td><td>4</td></tr>
<tr><td>1</td><td>2</td><td>3</td><td>4</td></tr>
<tr><td>1</td><td>2</td><td>3</td><td>4</td></tr>
</tbody>
</table>

将前面的 JavaScript 包装在下面,将其限制为 Firefox。

if (navigator.userAgent.toLowerCase().indexOf("firefox") > -1) {
// ...
}

截图(Firefox 71) :

Screenshot (Firefox 71)

<td style="position: sticky;
top: 0;
left: 0;
right: 0;
padding: 4px 3px;
background-color: #d3d3d3;
box-shadow: inset 0 1px 0 black, inset 0 -1px 0 black;">
</td>

使用这个100% 工作

使用 ::after伪选择器来模拟,比方说,右边框

例如:

th::after {
content: '';
position: absolute;
top: 0;
right: 0;
height: 100%;
border-right: 1px solid #e7e7e7;
}




outline代替 border怎么样?我敢说,特别是对于表元素,outline的作用几乎与 border相同。我知道它不是开箱即用的模型等,但在视觉上是相同的这里。试试这个:

table tr th,
table tr td {
border: 0;
outline: 2px solid;
}

请记住,outline总是围绕整个元素呈现,没有什么像 outline-left,所以它不是银弹。详情请参阅 MDN 概要

更新 : 我忽略了一个细节,大纲没有与 tbody边框正确对齐。您必须为整个表交换 borderoutline,或者使用 transform并推动 thead,但是这可能不是一个好方法(当然,这取决于具体情况)。

<style>
thead{
position: sticky;
z-index: 2;
top: 0;
background-color: white;
};
    

table {
border-collapse: separate;
}
</style>
<table cellspacing="0">
<!--...-->
</table>