-
-
Notifications
You must be signed in to change notification settings - Fork 79.1k
Description
When working on "sticky header" and "sticky column" features for BootstrapVue (using Bootstrap v4.3.1 CSS), I had to generate a huge amount of SCSS (and conditionals in JS) to ensure that the cells had a background color (they were transparent by default, as table cells do not inherit their parent background color).
It would be nice if Bootstrap set up the table child elements to inherit their parent element's background color, so if a color is applied to a cell, row, or table they will have a solid background.
We also came up with a simple way to generate zebra striping and hover state with much less lines of CSS by cheating with a transparent solid gradient background image (which gets overlayed on the background color).
Something like this would be great in Bootstrap (v5), and it probably would decrease the amount of CSS rules generated (specifically for the them color variants):
.table {
// Ensure table has a background color by default, plus handle reset
// of color for nested tables
background-color: if($table-bg, $table-bg, $body-bg);
// Ensure child elements inherit their parent element's background color
// As table child elements do not inherit bg-color by default.
// Must be defined before any table theme colors are defined
thead,
tbody,
tfoot,
tr,
th,
td {
background-color: inherit;
}
// ...
// Define table theme background and border color stuff here
// But no hover/striping stuff, as it is handled below
// ...
// Zebra striping (regardless of background color)
// Also works when cells have their on theme color variant applied
// table cell backgrounds remain `solid` so if sticky headers/columns is
// used, the header cells won't show the scrolled table contents through them
&.table-striped {
> tbody {
> tr:nth-of-type(#{$table-striped-order}) {
// Could do this to reduce the number of rules generated
// > :nth-child(1n) {
> td,
> th {
// Simple way to "darken" a row, regardless of it's `.table-<variant>` color
// using transparent black, which is overlayed on top of bg color
// No need to generate special striping states for each theme color
background-image: linear-gradient($table-accent-bg, $table-accent-bg);
background-repeat: no-repeat;
}
}
}
// Dark mode Zebra striping
&.table-dark {
> tbody {
> tr:nth-of-type(#{$table-striped-order}) {
// Could do this to reduce the number of rules generated
// > :nth-child(1n) {
> td,
> th {
// Simple way to "lighten" a row, regardless of it's `.bg-<variant>` color,
// using transparent white, which is overlayed on top of bg color
// No need to generate special striping states for each theme color
background-image: linear-gradient($table-dark-accent-bg, $table-dark-accent-bg);
background-repeat: no-repeat;
}
}
}
}
}
// Table hover rows (regardless of background color)
// Also Works when cells have their on theme color applied
&.table-hover {
> tbody {
> tr:hover {
// Could do this to reduce the number of rules generated
// > :nth-child(1n) {
> td,
> th {
// Simple way to "darken" a row, regardless of it's `.table-<variant>` color
// using transparent black, which is overlayed on top of bg color
// No need to generate special hover states for each theme color
background-image: linear-gradient($table-hover-bg, $table-hover-bg);
background-repeat: no-repeat;
}
}
}
// Dark mode table hover
&.table-dark {
> tbody {
> tr:hover {
// Could do this to reduce the number of rules generated
// > :nth-child(1n) {
> td,
> th {
// Simple way to "lighten" a row, regardless of it's `.bg-<variant>` color
// using transparent white, which is overlayed on top of bg color
// No need to generate special hover states for each theme color
background-image: linear-gradient($table-dark-hover-bg, $table-dark-hover-bg);
background-repeat: no-repeat;
}
}
}
}
}
}If you want to take a peek at what it looks like, check out https://bootstrap-vue.js.org/docs/components/table/#sticky-headers and https://bootstrap-vue.js.org/docs/components/table/#sticky-columns
The only issue we have is that the table borders scroll with the body since tables are set to border-collapse: collapsed; (which has the effect of transferring the borders to the table element instead of the cells). Setting that to border-collapse: separate; border-spacing: 0; fixes the border scrolling issue, but doubles the borders in some instances... but that could be fixed by only applying border to the left, bottom, and right where needed.
Here is what a scrollable table with sticky headers looks like without the above changes (cells in behind of the sticky headers show through):
And with the above changes (for background-color inheritance):
/cc @mdo

