Position: sticky (firefox) on a <table> element

て烟熏妆下的殇ゞ 提交于 2019-12-19 03:18:28

问题


The new value of position is very confusing to me.. a lot of search result give javascript/jQuery (JavaScript-framework) solutions.

In the example in bottom i have a table with a thead and tbody.

No matter what i cannot achieve the desire result. Desire result is thead to be sticky to the table. sticky means when not in view the element is some kind of position:fixed fixed means it sticks to your screen. What i did try:

  • display: inline/block/inline-block;
  • th element position:sticky (th element is an element inside a tr witch is inside a thead element)
  • mix of display:inline/block etc; (values of property display)

I just cannot find how to achieve this sticky in firefox (supported)

Any solutions ??

(as position:sticky still an experimental API and should not be used in production site http://developer.mozilla.org/en/docs/Web/CSS/position )

table {
  background-color: rgba(241, 31, 0, 0.3);
  width: 100%;
}
thead {
  background-color: rgba(241, 0, 241, 0.3);
  position: -webkit-sticky;
  position: sticky;
}
th {} tbody td:nth-child(2) {
  height: 200px;
}
<table>
  <thead>
    <tr>
      <th>1</th>
      <th>2</th>
      <th>3</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>1</td>
      <td>2</td>
      <td>3</td>
    </tr>
    <tr>
      <td>1</td>
      <td>2</td>
      <td>3</td>
    </tr>
    <tr>
      <td>1</td>
      <td>2</td>
      <td>3</td>
    </tr>
    <tr>
      <td>1</td>
      <td>2</td>
      <td>3</td>
    </tr>
    <tr>
      <td>1</td>
      <td>2</td>
      <td>3</td>
    </tr>
    <tr>
      <td>1</td>
      <td>2</td>
      <td>3</td>
    </tr>
    <tr>
      <td>1</td>
      <td>2</td>
      <td>3</td>
    </tr>
    <tr>
      <td>1</td>
      <td>2</td>
      <td>3</td>
    </tr>
    <tr>
      <td>1</td>
      <td>2</td>
      <td>3</td>
    </tr>
    <tr>
      <td>1</td>
      <td>2</td>
      <td>3</td>
    </tr>
    <tr>
      <td>1</td>
      <td>2</td>
      <td>3</td>
    </tr>
    <tr>
      <td>1</td>
      <td>2</td>
      <td>3</td>
    </tr>
    <tr>
      <td>1</td>
      <td>2</td>
      <td>3</td>
    </tr>
  </tbody>
</table>

回答1:


Firefox seems not to allow yet 'sticky' on table childs elements.

a workaround would be to set table as block, then thead, tbody, tfoot to display:table; so one of them can be sticked.

unfortunately this breaks the table-layout and split table into few tables .. :(

you also need to set coordonates where sticky comes in action http://codepen.io/gc-nomade/pen/reoExq . not the best :(

CSS base would be like:

table {
  display: block;
}

thead {
  position: sticky;
  top: 0px;  /* trigger sticky when reaches coordonates */
}

thead, tbody, tfoot {
  display: table;
  width: 100%;
}

table {
  background-color: rgba(241, 31, 0, 0.3);
  width: 100%;
  margin-top: 1em;
  position: static;
  display: block;
}
thead {
  display: table;
  width: 100%;
  background-color: rgba(241, 0, 241, 0.3);
  position: sticky;
  top: 0px;
  /* trigger sticky when reaches coordonates */
}
tbody {
  display: table;
  width: 100%;
}
th {} tbody td:nth-child(2) {
  height: 200px;
}
<table>
  <thead>
    <tr>
      <th>1</th>
      <th>2</th>
      <th>3</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>1</td>
      <td>2</td>
      <td>3</td>
    </tr>
    <tr>
      <td>1</td>
      <td>2</td>
      <td>3</td>
    </tr>
    <tr>
      <td>1</td>
      <td>2</td>
      <td>3</td>
    </tr>
    <tr>
      <td>1</td>
      <td>2</td>
      <td>3</td>
    </tr>
    <tr>
      <td>1</td>
      <td>2</td>
      <td>3</td>
    </tr>
    <tr>
      <td>1</td>
      <td>2</td>
      <td>3</td>
    </tr>
    <tr>
      <td>1</td>
      <td>2</td>
      <td>3</td>
    </tr>
    <tr>
      <td>1</td>
      <td>2</td>
      <td>3</td>
    </tr>
    <tr>
      <td>1</td>
      <td>2</td>
      <td>3</td>
    </tr>
    <tr>
      <td>1</td>
      <td>2</td>
      <td>3</td>
    </tr>
    <tr>
      <td>1</td>
      <td>2</td>
      <td>3</td>
    </tr>
    <tr>
      <td>1</td>
      <td>2</td>
      <td>3</td>
    </tr>
    <tr>
      <td>1</td>
      <td>2</td>
      <td>3</td>
    </tr>
  </tbody>
</table>
<table>
  <thead>
    <tr>
      <th>1</th>
      <th>2</th>
      <th>3</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>1</td>
      <td>2</td>
      <td>3</td>
    </tr>
    <tr>
      <td>1</td>
      <td>2</td>
      <td>3</td>
    </tr>
    <tr>
      <td>1</td>
      <td>2</td>
      <td>3</td>
    </tr>
    <tr>
      <td>1</td>
      <td>2</td>
      <td>3</td>
    </tr>
    <tr>
      <td>1</td>
      <td>2</td>
      <td>3</td>
    </tr>
    <tr>
      <td>1</td>
      <td>2</td>
      <td>3</td>
    </tr>
    <tr>
      <td>1</td>
      <td>2</td>
      <td>3</td>
    </tr>
    <tr>
      <td>1</td>
      <td>2</td>
      <td>3</td>
    </tr>
    <tr>
      <td>1</td>
      <td>2</td>
      <td>3</td>
    </tr>
    <tr>
      <td>1</td>
      <td>2</td>
      <td>3</td>
    </tr>
    <tr>
      <td>1</td>
      <td>2</td>
      <td>3</td>
    </tr>
    <tr>
      <td>1</td>
      <td>2</td>
      <td>3</td>
    </tr>
    <tr>
      <td>1</td>
      <td>2</td>
      <td>3</td>
    </tr>
  </tbody>
</table>
<table>
  <thead>
    <tr>
      <th>1</th>
      <th>2</th>
      <th>3</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>1</td>
      <td>2</td>
      <td>3</td>
    </tr>
    <tr>
      <td>1</td>
      <td>2</td>
      <td>3</td>
    </tr>
    <tr>
      <td>1</td>
      <td>2</td>
      <td>3</td>
    </tr>
    <tr>
      <td>1</td>
      <td>2</td>
      <td>3</td>
    </tr>
    <tr>
      <td>1</td>
      <td>2</td>
      <td>3</td>
    </tr>
    <tr>
      <td>1</td>
      <td>2</td>
      <td>3</td>
    </tr>
    <tr>
      <td>1</td>
      <td>2</td>
      <td>3</td>
    </tr>
    <tr>
      <td>1</td>
      <td>2</td>
      <td>3</td>
    </tr>
    <tr>
      <td>1</td>
      <td>2</td>
      <td>3</td>
    </tr>
    <tr>
      <td>1</td>
      <td>2</td>
      <td>3</td>
    </tr>
    <tr>
      <td>1</td>
      <td>2</td>
      <td>3</td>
    </tr>
    <tr>
      <td>1</td>
      <td>2</td>
      <td>3</td>
    </tr>
    <tr>
      <td>1</td>
      <td>2</td>
      <td>3</td>
    </tr>
  </tbody>
</table>
<table>
  <thead>
    <tr>
      <th>1</th>
      <th>2</th>
      <th>3</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>1</td>
      <td>2</td>
      <td>3</td>
    </tr>
    <tr>
      <td>1</td>
      <td>2</td>
      <td>3</td>
    </tr>
    <tr>
      <td>1</td>
      <td>2</td>
      <td>3</td>
    </tr>
    <tr>
      <td>1</td>
      <td>2</td>
      <td>3</td>
    </tr>
    <tr>
      <td>1</td>
      <td>2</td>
      <td>3</td>
    </tr>
    <tr>
      <td>1</td>
      <td>2</td>
      <td>3</td>
    </tr>
    <tr>
      <td>1</td>
      <td>2</td>
      <td>3</td>
    </tr>
    <tr>
      <td>1</td>
      <td>2</td>
      <td>3</td>
    </tr>
    <tr>
      <td>1</td>
      <td>2</td>
      <td>3</td>
    </tr>
    <tr>
      <td>1</td>
      <td>2</td>
      <td>3</td>
    </tr>
    <tr>
      <td>1</td>
      <td>2</td>
      <td>3</td>
    </tr>
    <tr>
      <td>1</td>
      <td>2</td>
      <td>3</td>
    </tr>
    <tr>
      <td>1</td>
      <td>2</td>
      <td>3</td>
    </tr>
  </tbody>
</table>



回答2:


Another method is to use css3 to translate the header cells. This method does require javascript and will work in all modern browsers, but because it translates the table cell, the border does not get included for some reason (demo)

Also, this css is necessary to include a background color on the translated cells

thead th,
caption {
  background: #fff;
}

jQuery

var $win = $(window),
  $table = $('table'),
  $thead = $table.children('thead'),
  $tfoot = $table.children('tfoot'),
  $caption = $table.children('caption'),
  $cells = $thead.children().children().add($caption);

$win.on('scroll', function() {
  var bottom = $table.position().top +
        $table.height() -
        $thead.height() -
        ($tfoot.height() || 0),
    delta = $win.scrollTop() -
        $thead.offset().top +
        $caption.outerHeight(),
    // include border thickness (minus 2)
    vertPos = (delta < 0 || delta > bottom ? 0 : delta - 2);
  $cells.css("transform", "translate(0px," + vertPos + "px)");
});



回答3:


Update Q1 2018

position: sticky has now landed in stable Firefox 59. The fiddle linked below now works unchanged in Firefox as well.


I know you specifically asked for Firefox compatibility of position: sticky, but unfortunately its styling effect in Firefox is not defined on inner table elements:

Quoting from https://developer.mozilla.org/en/docs/Web/CSS/position

The effect of position:relative on table-*-group, table-row, table-column, table-cell, and table-caption elements is undefined.

The effect of ‘position: sticky’ on table elements is the same as for ‘position: relative’.

That being said, position: sticky is about to land in Chrome Stable channel (it is in Canary at the time of writing and there's a developer.google.com blog post about it). Their implementation does work fine on thead, solving my own long-standing problem of sticky theads as all other solutions fail when you need to resize the table/cell widths.

I've created a fiddle to test the sticky positioning. On all channels of Firefox, this has no effect.

My hope is that position: sticky now gains tractions due to the more complete implementation in Chrome, it will stir discussions again on the lacking inner table support of sticky.

There's also a bug report on Firefox' Bugzilla: https://bugzilla.mozilla.org/show_bug.cgi?id=975644



来源:https://stackoverflow.com/questions/37071535/position-sticky-firefox-on-a-table-element

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!