当背景色存在时,为啥“位置:粘性”边框不可见?

Posted

技术标签:

【中文标题】当背景色存在时,为啥“位置:粘性”边框不可见?【英文标题】:Why border is not visible with "position: sticky" when background-color exists?当背景色存在时,为什么“位置:粘性”边框不可见? 【发布时间】:2017-01-26 20:41:34 【问题描述】:

position: 'sticky' landed in Chrome 56,但它使边框在某些情况下不可见。

考虑以下示例:

table 
  border-collapse: collapse;


thead 
  position: sticky;
  top: 0;


th 
  background-color: #fff;
  border-right: 5px solid red;
<table>
  <thead>
    <tr>
      <th>First</th>
      <th>Second</th>
      <th>Third</th>
    </tr>
  </thead>
</table>

在 Chrome 56.0.2924.76 中,只有最后一个 &lt;th&gt; 的边框是可见的,并且只有在 &lt;th&gt; 指定了 background-color 时才可见。

这是 Chrome 中的错误吗?

Playground

【问题讨论】:

这可以在 Firefox 52.0a2 上重现。当border-collapse: collapse; 被移除时,边框会重新出现在所有表格标题上。 旁边的表格元素+位置:粘性;在 Firefox 中不起作用,因为它仍然是实验性的,我相信它还没有修复 如前所述,它在 Firefox 中仍然有效,但无法在 Chromium 中重现。似乎已经固定在那里了。 这里是 Firefox 的错误报告:bugzilla.mozilla.org/show_bug.cgi?id=1450584 请在此处表达自己的意见,以便修复 【参考方案1】:

我遇到了同样的问题。我的解决方法是使用:after 伪元素来模拟底部边框。

th:after
  content:'';
  position:absolute;
  left: 0;
  bottom: 0;
  width:100%;
  border-bottom: 1px solid rgba(0,0,0,0.12);

【讨论】:

很高兴我向下滚动到接受的答案并看到了这个! 现在似乎可以在 Firefox 上完美运行,但在 chrome 上我需要使用 bottom: -1px;【参考方案2】:

似乎强制回流会部分帮助:

table 
  border-collapse: collapse;


thead 
  position: sticky;
  top: 0;


th 
  border-right: 5px solid red;
  transform:scale(0.999);
  <table>
    <thead>
      <tr>
        <th>First</th>
        <th>Second</th>
        <th>Third</th>
      </tr>
    </thead>
  </table>

background-clip 似乎也高效且无害:

table 
  margin-top: 1em;
  border-collapse: collapse;
  margin-bottom: 200vh


thead 
  position: sticky;
  top: 0;


th 
  border-right: 5px solid red;
  background:white; 
  background-clip: padding-box;
  <table>
    <thead>
      <tr>
        <th>First</th>
        <th>Second</th>
        <th>Third</th>
      </tr>
    </thead>
  </table>

【讨论】:

【参考方案3】:

如果表格包含列周围的边框并且我们添加了粘性位置, 当我们滚动表格时显示重叠效果以消除此效果并 保留边框我们需要删除边框并添加轮廓而不是边框​​

table tr th
  outline: 1px solid #e9ecef;
  border:none;
  outline-offset: -1px;

【讨论】:

如果表格在列周围包含边框并且我们添加了粘性位置,当我们滚动表格时会显示重叠效果以移除此效果并保留边框我们需要移除边框并添加轮廓而不是边框​​ 绝对是最好的答案(至少对于 Chrome)。 @shahida 我建议您移动您的评论,以解释为什么它在您的答案正文中起作用。 这是非常有限的,因为它只能在所有边上画一条线,并且这些线不会与相邻的单元格一起折叠。看起来很丑。不能用这个。 将轮廓更改为 2px 以避免在我的情况下移动标题,这个解决方案就像一个魅力。【参考方案4】:

我已经用影子解决了

table tr th 
  position: -webkit-sticky;
  position: sticky;
  top: -1px;
  z-index: 2;
  background-color: white;
  -moz-box-shadow: 0 0 1px -1px #ccc;
  -webkit-box-shadow: 0 0 1px -1px #ccc;
  box-shadow: 0 0 1px -1px #ccc;

【讨论】:

这是唯一对我有用的解决方案,但使用box shadow: inset 0 0 0 1px #ccc;【参考方案5】:

下一个示例目前在 Chrome (65) 和 Firefox (59) 下运行良好。

SCSS 代码更好地说明了值之间的关系。您可以通过更改变量来设置所需的值。

SCSS:

table 

    &.sticky-table-head 

        // Variables

        $border-width: 2px;

        $head-background-color: #ded;
        $head-border-color: #8a8;

        $background-color: #f8fff8;
        $border-color: #cdc;

        $color: #686;

        // Declarations

        margin-bottom: 1em;
        border-collapse: collapse;
        background-color: $background-color;
        color: $color;

        &:last-child 
            margin-bottom: 100vh;
        

        th,
        td 
            border: $border-width solid $border-color;
        

        thead 

            th 
                position: sticky;
                top: ($border-width / 2);
                background-color: $head-background-color;
                outline: $border-width solid $head-border-color;
                outline-offset: (- $border-width / 2);
            
        
    

html 和编译后的 CSS:

table.sticky-table-head 
	margin-bottom: 1em;
	border-collapse: collapse;
	background-color: #f8fff8;
	color: #686;


table.sticky-table-head:last-child 
	margin-bottom: 100vh;


table.sticky-table-head th,
table.sticky-table-head td 
	border: 2px solid #cdc;


table.sticky-table-head thead th 
	position: -webkit-sticky;
	position: sticky;
	top: 1px;
	background-color: #ded;
	outline: 2px solid #8a8;
	outline-offset: -1px;
<div>
	<!-- First table -->
	<table class="sticky-table-head">
		<thead>
			<tr>
				<th>Lorem</th>
				<th>Ipsum</th>
				<th>Dolor sit amet</th>
			</tr>
		</thead>
		<tbody>
			<tr>
				<td>ipsum</td>
				<td>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.</td>
				<td>sit</td>
			</tr>
			<tr>
				<td>ipsum</td>
				<td>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.</td>
				<td>sit</td>
			</tr>
			<tr>
				<td>ipsum</td>
				<td>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.</td>
				<td>sit</td>
			</tr>
			<tr>
				<td>ipsum</td>
				<td>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.</td>
				<td>sit</td>
			</tr>
			<tr>
				<td>ipsum</td>
				<td>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.</td>
				<td>sit</td>
			</tr>
			<tr>
				<td>ipsum</td>
				<td>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.</td>
				<td>sit</td>
			</tr>
			<tr>
				<td>ipsum</td>
				<td>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.</td>
				<td>sit</td>
			</tr>
			<tr>
				<td>ipsum</td>
				<td>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.</td>
				<td>sit</td>
			</tr>
		</tbody>
	</table>
	<!-- Second table -->
	<table class="sticky-table-head">
		<thead>
			<tr>
				<th>Lorem</th>
				<th>Ipsum</th>
				<th>Dolor sit amet</th>
			</tr>
		</thead>
		<tbody>
			<tr>
				<td>ipsum</td>
				<td>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.</td>
				<td>sit</td>
			</tr>
			<tr>
				<td>ipsum</td>
				<td>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.</td>
				<td>sit</td>
			</tr>
			<tr>
				<td>ipsum</td>
				<td>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.</td>
				<td>sit</td>
			</tr>
			<tr>
				<td>ipsum</td>
				<td>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.</td>
				<td>sit</td>
			</tr>
			<tr>
				<td>ipsum</td>
				<td>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.</td>
				<td>sit</td>
			</tr>
			<tr>
				<td>ipsum</td>
				<td>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.</td>
				<td>sit</td>
			</tr>
			<tr>
				<td>ipsum</td>
				<td>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.</td>
				<td>sit</td>
			</tr>
			<tr>
				<td>ipsum</td>
				<td>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.</td>
				<td>sit</td>
			</tr>
		</tbody>
	</table>
</div>

【讨论】:

【参考方案6】:

试试这个:

background-clip: padding-box;

【讨论】:

【参考方案7】:

使用::after 伪选择器模拟右边框

例子:

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

【讨论】:

【参考方案8】:

box-shadow: inset 0 0 0px 2px #555; 而不是border: solid 2px #555; 将起作用。但这确实是一个错误,应该由浏览器修复。

【讨论】:

【参考方案9】:

另一种选择是将您的内容包装在一个元素中并在其上放置边框:

.th-inner 
  padding: 10px;
  border-bottom: 1px solid #ccc;
<th>
  <div class="th-inner">your content</div>
</th>

但是我发现在th 上设置边框可以在没有border-collapse: collapse 的情况下使用,所以我就这么做了。

【讨论】:

【参考方案10】:

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 
  width: 30px;
  min-width: 30px;
  max-width: 30px;
  word-break: break-all;


.fixed_header 
  width: 100%;
  table-layout: fixed;
  border-collapse: collapse;



/* fixed header */

thead th 
  /* for Safari */
  text-align: center;
  position: -webkit-sticky;
  position: sticky;
  top: 0;


.fixed_header th,
.fixed_header td 
  padding: 10px;
  width: 90px;


.table_container 
  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>jhhhh-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>

【讨论】:

【参考方案11】:
thead::after 
  content: '';
  display: block;
  position: absolute;
  right: 0;
  bottom: 0;
  left: 0;
  height: 1px;
  background-color: #333333;

我用伪元素而不是边框​​解决了同样的问题。不过,不知道为什么会发生这种情况。

【讨论】:

【参考方案12】:

我在页面中仅使用水平边框,因此可能需要根据您的具体情况进行调整。通过为表格单元格使用半透明的背景颜色,我发现覆盖水平边框的是背景的底端。我想它与垂直边框的右端相同。为了避免边框重叠,我设置了一个线性渐变来填充所有内容,但保留最后一个像素。不幸的是,这仅适用于 Firefox 和 Chrome,但不适用于 Edge。

td:first-child 
  position: sticky;
  left: 0px;
  z-index: 2;
  background: linear-gradient(to bottom, white, white calc(100% - 1px),
                              transparent calc(100% - 1px), transparent);

Edge 确实绘制了一个线性渐变,但从顶部的白色到底部的透明,忽略了 100% - 1px 处的硬变化。

【讨论】:

以上是关于当背景色存在时,为啥“位置:粘性”边框不可见?的主要内容,如果未能解决你的问题,请参考以下文章

用div+css做下拉菜单,当鼠标移向2级菜单时,为啥1级菜单的a:hover背景色就不管用了?

DIV+CSS中复选框的背景颜色不显示,但是边框显示,为啥?

当图像内部存在背景颜色(不仅仅是边框)时,Imagemagick trimimage功能也会修剪

css 一口气实现切角+边框+投影+内容背景色渐变

css 一口气实现切角+边框+投影+内容背景色渐变

Android 使用shape定义不同控件的的颜色背景色边框色