Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Sticky table column #31458

Open
RichardNeill opened this issue Aug 9, 2020 · 6 comments
Open

Sticky table column #31458

RichardNeill opened this issue Aug 9, 2020 · 6 comments

Comments

@RichardNeill
Copy link

In a responsive table, with lots of columns, it's often desirable to make the left-most column sticky, so it doesn't scroll off the page. I think this should be an option within bootstrap, in the same way that we can make the sticky. Sometimes, both the top row and left-col need to be sticky.

Here is how we do it at the moment: note that it seems to work "perfectly" in Chrome, but is broken in Firefox.

/* Sticky first column. NB Firefox Bug #1658119 means that we lose the td-borders! /
table.sticky-x tr td:nth-child(1){
position: sticky; left: 0; z-index: 10;
background-color: #fff; /
Must set a color explicitly, else it is transparent to the text that scrolls by underneath /
}
table.sticky-x tr th:nth-child(1){
position: sticky; left: 0; z-index: 10;
}
table.sticky-x thead tr th:nth-child(1) { /
top-left corner never moves - and we don't override the existing th-color either. /
position: sticky; left: 0; top: 0; z-index: 12;
}
table.sticky-x.table-striped tr:nth-of-type(odd) td:nth-child(1) {
background-color: #f2f2f2; /
restore table-striped */
}

Thanks.

@mdo mdo changed the title wish: sticky left-column, i.e. "table.table-responsive.sticky-left" Sticky table column Aug 17, 2020
@mznet
Copy link

mznet commented Aug 19, 2020

@RichardNeill Your code is not broken on even Firefox, I've tested it on Firefox 79.0. On even Safari and Chrome, It still works nicely.

@RichardNeill
Copy link
Author

Hi and thanks.

The problem in firefox is not that the "sticky column" doesn't work, rather it is that the borders within the sticky first column disappear. https://bugzilla.mozilla.org/show_bug.cgi?id=1658119 includes a test-case and a workaround.

More generally, a good solution for tables (and which I'd love to see in Bootstrap) would be to allow any combinations

table-sticky-header: sticky header (when scrolling vertically)
table-sticky-left: sticky 1st column (when scrolling horizontally)
table-responsive-sticky: table-responsive working with sticky-header.

The major challenges here are:

  • Table borders don't always go with the sticky cell, but seem to be part of the layer beneath. It's necessary to bodge it with box-shadow instead.

  • If the table is responsive horizontally, then it cannot be sticky vertically (this is a limit from CSS, though it should be doable).
    Therefore, some JS is probably needed.

  • It would be helpful if, when sticky behaviour is actually happening, a "stuck" class could be dynamically added.

As an update, below is my current best CSS. But it hardcodes the box-shadow colours, and it doesn't solve the sticky-responsive problem.

/* Sticky tables. Use ".sticky" and ensure we have section (recommended: ".thead-dark"). */
table.sticky thead tr:nth-child(1) th{
position: sticky; top: 0; z-index: 10;
box-shadow: 0 0 0 1px #ddd;
}

/* Sticky first column. NB Firefox Bug #1658119 means that we lose the td-borders! Fudge it with box-shadow; this isn't perfect. See: https://stackoverflow.com/questions/40760241/sticky-row-and-column-header-in-table /
table.sticky-x tr td:nth-child(1){
position: sticky; left: 0; z-index: 10;
background-color: #fff; /
Must set a color explicitly, else it is transparent to the text that scrolls by underneath. c.f. "wholly" */
box-shadow: 0px 0px 0px 1px #ddd, 2px 0px 0px 0px #444; /*Or: box-shadow: 0 0 0 1px #ddd; /
}
table.sticky-x tr th:nth-child(1){
position: sticky; left: 0; z-index: 10;
box-shadow: 0px 0px 0px 1px #ddd, 2px 0px 0px 0px #444;
}
table.sticky-x thead tr th:nth-child(1) { /
top-left corner never moves - and we don't override the existing th-color either. /
position: sticky; left: 0; top: 0; z-index: 12;
box-shadow: 0 0 0 1px #ddd;
}
table.sticky-x.table-striped tr:nth-of-type(odd) td:nth-child(1) {
background-color: #f2f2f2; /
restore table-striped */
}

/* Vertical striped tables */
table.table-striped-columns {
tbody td:nth-of-type(odd), thead th:nth-of-type(odd){ background:#f2f2f2; }
}

@XhmikosR
Copy link
Member

Bug reports must include a live demo of the issue. Per our contributing guidelines, please create a reduced test case via CodePen or JS Bin and report back with your link, Bootstrap version, and specific browser and Operating System details.

This is an automated reply

@RichardNeill
Copy link
Author

I hope this helps.
https://codepen.io/RichardNeill/pen/bGePxpO
This test case works well enough that I use it on production, but it is very ugly in how it does so.,

What I would like to propose is that bootstrap simply offer 3 more table classes:

  • "table-sticky" (which makes the top-row sticky) - and should also not conflict with div.table-responsive if this can be managed.
  • "table-sticky-x" (which makes the left col sticky)
  • "table-striped-columns" (which does vertical striping)

@abhishekrawat22
Copy link

@RichardNeill For the concern that you raised regarding the border not showing on the firefox browser can be solved by adding border-collapse: separate; border-spacing: 0;

@stephanieleary
Copy link

Michelle Barker has a different solution to the border problem using pseudo-elements. This works slightly better for me in Firefox than the border-collapse: separate; style.
https://piccalil.li/blog/styling-tables-the-modern-css-way#sticky-rows-and-columns

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

6 participants