【问题标题】:Border style do not work with sticky position element边框样式不适用于粘性位置元素
【发布时间】:2018-10-25 23:11:08
【问题描述】:

我不知道为什么我的边框样式不适用于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>

以下是我想要的以及对我的问题不够清楚的屏幕截图。

您可以看到 th 的内联边框样式不起作用(删除 css 的 position 属性,您将看到周围的边框。)。

向下滚动一点后。你会看到所有的边框样式都消失了。

【问题讨论】:

  • 您没有为table tr th, table tr td 选择器提供颜色。语法应该如下border: &lt;unit&gt; &lt;border-style&gt; &lt;color&gt;
  • @soulshined 不,实际上它不需要。 &lt;color&gt; 部分不是虚构的。默认为#000000AFAIK。

标签: html css


【解决方案1】:

使用table thead th 而不是table thead。 这是演示。 https://jsfiddle.net/nhatphamcdn/9dhqchtu/

【讨论】:

  • 我已经这样尝试过了。您应该向下滚动并检查 thead 样式发生了什么。
【解决方案2】:

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

我确信有一种更优雅的方式来实现这一点,但我只会更改 :after:before 伪类以提供具有绝对定位的边框。

#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>

【讨论】:

  • 感谢您更新的答案。但是左右还是不行吧?
  • 查看编辑@Cataclysm,让我知道你的想法。我只是将表格边框放回去,还是您希望它们具有与表格边框颜色分开的某种颜色?
  • 谢谢!现在我几乎完成了你的想法。这里是updated fiddle
【解决方案3】:

现在我可以按照用户@soulshined 的建议使用psuedo classes 设置边框样式。下面是工作的 css 更改,这里是 JSFiddle Link。已经在 chrome 和 firefox 上测试过。

#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;
}

【讨论】:

    【解决方案4】:

    您需要使用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>

    【讨论】:

    • 在 FF 上我仍然看到边界间隙
    • 为火狐更新。
    • 这是唯一对我有用的答案。处理 Material UI 和一些 theme.js 覆盖。
    • 谢谢。背景剪辑:填充框!重要;帮助了我
    • 当将它与引导样式表一起使用时,应删除标题边框以避免一些奇怪的样式问题。例如。 .wrapper thead th { border: none; }
    【解决方案5】:

    由于使用了border-collapse: collapse 而出现问题。当浏览器折叠边框时,&lt;th&gt; 上的顶部和底部边框必须应用于周围的元素——&lt;table&gt; 的顶部边框和下面的&lt;tr&gt; 的底部边框。

    如果您使用 border-collapse: separate 并将边框设计为位于一侧,则边框将真正连接到 &lt;th&gt;,按预期保持固定,并显示为折叠状态。

    以下是可应用于 HTML sn-p 的示例样式。

    #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;
    }
    

    【讨论】:

    • 这种方法从根本上解决了问题,并且易于理解。我认为这应该比使用伪类更可取。
    • 是的,但是当我使用它时,沿未使用的边框两侧似乎有一个像素的间隙
    • 这个解决方案很简洁,但不幸的是,Edge 中似乎有一个错误阻止它工作。
    • 在我看来没有必要添加这么多的 css 类你唯一需要添加的一件事:table {border-collapse:separate;边框间距:0; }
    • 不幸的是,不能将此解决方案用于引导样式表,因为它使用了border-collapse: collapse :/。建议使用 box-shadow 的答案虽然有效。
    【解决方案6】:

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

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

    注意:这是一种变通方法,所以不要抱怨我。

    如果您从表格标题中删除 border-top,表格将不会折叠,因此不会创建空间来查看底层单元格。将border-top替换为控股DIV中相同样式的边框。

    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>
    

    【讨论】:

    • 你的意思是 class="table_holder" 吗?
    【解决方案7】:
    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>

    【讨论】:

      【解决方案8】:

      尝试了一些现有的答案,但正如 cmets 所提到的,它们会导致边框之间出现一个像素的间隙。

      做了一个解决方法,虽然它需要 JavaScript。它在每个&lt;th&gt; 中放置一个&lt;div&gt;,在调整大小时它适合&lt;div&gt;&lt;th&gt;。然后将&lt;th&gt; 边框应用于&lt;div&gt;

      注意,在撰写本文时,position: sticky&lt;thead&gt; 上的 Chromium 中不工作,它在 Firefox 中工作。但是,如果不执行 JavaScript,position: sticky 相关的 CSS 不会影响页面。

      在浏览器中单击Run code sn-p 看看它是否有效。

      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):

      【讨论】:

        【解决方案9】:
        <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% 的工作

        【讨论】:

        • 我使用 box-shadow 添加了一个“底部边框”。对我来说比其他答案更容易使用。
        【解决方案10】:

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

        例子:

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

        【讨论】:

        • 为了使其更加对称,可以添加以下内容:th:not(:last-of-type):after { ... }
        【解决方案11】:

        outline 替换border 怎么样?我敢说,特别是对于表格元素,outline 的行为与border 几乎相同。我知道它不是开箱即用的模型等,但在这里看起来是相同的。试试这个:

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

        请记住,outline 总是围绕整个元素渲染,没有像 outline-left 这样的东西,所以它不是灵丹妙药。详情请见outline on MDN

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

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2019-02-28
          • 1970-01-01
          • 2017-11-04
          • 1970-01-01
          • 1970-01-01
          • 2016-07-07
          • 2023-01-29
          相关资源
          最近更新 更多