Skip to content

Commit

Permalink
feat(table): all scroll stuck head foot first last variant
Browse files Browse the repository at this point in the history
This PR adds a stuck variant which supports to have the head, foot, first column and last column of a table being stuck while scrolling (using position sticky)

You can freely stick any combination like head first stuck, foot first last stuck, head foot first stuck, first last stuck, etc.
This feature needs to have the table being wrapped by a overflowing container having a fixed height (and/or optional width).
That said, i also added a new scrolling container and scrolling segment variant, which can be used for that purpose.

Why stuck instead of sticky or fixed?
Because the other classnames already exists and provide different functionality

Why not use classnames "header, footer, top, bottom, left, right" ?
Because the other classnames (beside "footer") already exists and provide different functionality

What about the already merged scrolling table #2134 ? Why another approach?
Unfortunately the other approach cannot properly support having the first or last column fixed (I tried some very ugly approaches which needed a fixed width of the columns and especially were not able to fill the background color into the whole cell.)

The new stuck variant makes use of sticky positioning which supports using a usual table element and does not have the above mentioned issues.

The scrolling table works in any browser, while stuck needs modern browsers with position:sticky support to table elements .

stuck possibly needs a wrapper when horizontal scrolling is not needed, while scrolling does not.
That said, i also added new scrolling container and scrolling segment variants, which can be used for that purpose.

If you don't want to have an extra wrapper, you can use overflowing stuck table. However, this only works if your overall table columns exceed available width.

Each new variant of scrolling container, scrolling segment or overflowing table support predefined heights using short, very short, long and very long

See comparison table for details.

Comparison
Feature	stuck table	scrolling table
Supports fixed thead	✔️	✔️
Supports fixed tfoot	✔️	✔️
Supports fixed left column	✔️	
Supports fixed right column	✔️	
Supports combinations	✔️	
Supports column sizing (wide)1	✔️	
Supports (single line)	✔️	
Supports vertical scrolling	✔️	✔️
Supports horizontal scrolling	✔️	
Needs wrapper2	✔️	
Needs modern browser	✔️	
Scrollbar only for tbody		✔️
  • Loading branch information
lubber-de committed Nov 3, 2021
1 parent f14cf4b commit 46bc57a
Show file tree
Hide file tree
Showing 7 changed files with 531 additions and 0 deletions.
253 changes: 253 additions & 0 deletions src/definitions/collections/table.less
Original file line number Diff line number Diff line change
Expand Up @@ -288,6 +288,31 @@
}
}
}
& when (@variationTableOverflowing) {
& when (@variationTableOverflowingShort) {
.ui.overflowing.table.short {
max-height: @overflowingMobileMaxHeight * 0.75;
}
}
& when (@variationTableOverflowingVeryShort) {
.ui.overflowing.table[class*="very short"] {
max-height: @overflowingMobileMaxHeight * 0.5;
}
}
.ui.overflowing.table {
max-height: @overflowingMobileMaxHeight;
}
& when (@variationTableOverflowingLong) {
.ui.overflowing.table.long {
max-height: @overflowingMobileMaxHeight * 2;
}
}
& when (@variationTableOverflowingVeryLong) {
.ui.overflowing.table[class*="very long"] {
max-height: @overflowingMobileMaxHeight * 3;
}
}
}
}
& when (@variationTableScrolling) {
/*--------------
Expand Down Expand Up @@ -461,6 +486,90 @@
}

}
& when (@variationTableOverflowing) {
/*--------------
Overflowing
---------------*/
.ui.overflowing.table {
display: block;
overflow: auto;
}
@media only screen and (min-width: @tabletBreakpoint) {
& when (@variationTableOverflowingShort) {
.ui.overflowing.table.short {
max-height: @overflowingTabletMaxHeight * 0.75;
}
}
& when (@variationTableOverflowingVeryShort) {
.ui.overflowing.table[class*="very short"] {
max-height: @overflowingTabletMaxHeight * 0.5;
}
}
.ui.overflowing.table {
max-height: @overflowingTabletMaxHeight;
}
& when (@variationTableOverflowingLong) {
.ui.overflowing.table.long {
max-height: @overflowingTabletMaxHeight * 2;
}
}
& when (@variationTableOverflowingVeryLong) {
.ui.overflowing.table[class*="very long"] {
max-height: @overflowingTabletMaxHeight * 3;
}
}
}
@media only screen and (min-width: @computerBreakpoint) {
& when (@variationTableOverflowingShort) {
.ui.overflowing.table.short {
max-height: @overflowingComputerMaxHeight * 0.75;
}
}
& when (@variationTableOverflowingVeryShort) {
.ui.overflowing.table[class*="very short"] {
max-height: @overflowingComputerMaxHeight * 0.5;
}
}
.ui.overflowing.table {
max-height: @overflowingComputerMaxHeight;
}
& when (@variationTableOverflowingLong) {
.ui.overflowing.table.long {
max-height: @overflowingComputerMaxHeight * 2;
}
}
& when (@variationTableOverflowingVeryLong) {
.ui.overflowing.table[class*="very long"]{
max-height: @overflowingComputerMaxHeight * 3;
}
}
}
@media only screen and (min-width: @widescreenMonitorBreakpoint) {
& when (@variationTableOverflowingShort) {
.ui.overflowing.table.short {
max-height: @overflowingWidescreenMaxHeight * 0.75;
}
}
& when (@variationTableOverflowingVeryShort) {
.ui.overflowing.table[class*="very short"] {
max-height: @overflowingWidescreenMaxHeight * 0.5;
}
}
.ui.overflowing.table {
max-height: @overflowingWidescreenMaxHeight;
}
& when (@variationTableOverflowingLong) {
.ui.overflowing.table.long {
max-height: @overflowingWidescreenMaxHeight * 2;
}
}
& when (@variationTableOverflowingVeryLong) {
.ui.overflowing.table[class*="very long"] {
max-height: @overflowingWidescreenMaxHeight * 3;
}
}
}
}


/*******************************
Expand Down Expand Up @@ -1638,6 +1747,150 @@
}
}

& when (@variationTableStuck) {
/*--------------
Stuck
---------------*/

.ui.stuck.table:not(.inverted) {
background: @stuckBackground;
& > thead > tr {
background: @stuckHeaderBackground;
}
& > tbody > tr {
background: @stuckBackground;
}
& > tfoot > tr {
background: @stuckFooterBackground;
}
&.basic when (@variationTableBasic) {
& > thead > tr,
> tfoot > tr {
background: @stuckBackground;
}
}
}
.ui.inverted.stuck.table when (@variationTableInverted) {
& > thead > tr {
background: @invertedStuckHeaderBackground;
}
& > tbody > tr {
background: @invertedStuckBackground;
}
& > tfoot > tr {
background: @invertedStuckFooterBackground;
}
&.basic when (@variationTableBasic){
& > thead > tr,
> tfoot > tr {
background: @invertedStuckBackground;
}
}
}
& when (@variationTableStuckHead) or (@variationTableStuckFoot) {
.ui.head.stuck.table > thead,
.ui.foot.stuck.table > tfoot {
position: -webkit-sticky;
position: sticky;
z-index: @stuckZIndex;
}
}
.ui.head.stuck.table when (@variationTableStuckHead) {
border-top: 0;
& > thead {
top: 0;
bottom: auto;
& > tr:first-child > th {
border-top: @cellBorder;
}
}
&.inverted > thead > tr:first-child > th when (@variationTableInverted) {
border-top: @invertedCellBorder;
}
}
.ui.foot.stuck.table when (@variationTableStuckFoot) {
border-bottom: 0;
& > tfoot {
top: auto;
bottom: 0;
& > tr:last-child > td,
> tr:last-child > th {
border-bottom: @cellBorder;
}
}
& when (@variationTableInverted) {
&.inverted > tfoot > tr:first-child > td,
&.inverted > tfoot > tr:first-child > th {
border-top: @invertedCellBorder;
}
}
}

.ui.first.stuck.table when (@variationTableStuckFirst) {
border-left: 0;
& th:first-child,
td:first-child {
position: -webkit-sticky;
position: sticky;
left: 0;
border-left: @cellBorder;
background: inherit;
}
& when (@variationTableInverted) {
&.inverted th:first-child,
&.inverted td:first-child {
border-left: @invertedCellBorder;
}
}
}

.ui.last.stuck.table when (@variationTableStuckLast) {
border-right: 0;
& th:last-child,
td:last-child {
position: -webkit-sticky;
position: sticky;
right: 0;
border-right: @cellBorder;
background: inherit;
}
& when (@variationTableInverted) {
&.inverted th:last-child,
&.inverted td:last-child {
border-right: @invertedCellBorder;
}
}
}
& when (@variationTableCelled) {
& when (@variationTableStuckFirst) {
.ui.celled.first.stuck.table th:first-child,
.ui.celled.first.stuck.table td:first-child {
border-right: @cellBorder;
}
}
& when (@variationTableStuckLast) {
.ui.celled.last.stuck.table th:last-child,
.ui.celled.last.stuck.table td:last-child {
border-left: @cellBorder;
}
}
& when (@variationTableInverted) {
& when (@variationTableStuckFirst) {
.ui.inverted.celled.first.stuck.table th:first-child,
.ui.inverted.celled.first.stuck.table td:first-child {
border-right: @invertedCellBorder;
}
}
& when (@variationTableStuckLast) {
.ui.inverted.celled.last.stuck.table th:last-child,
.ui.inverted.celled.last.stuck.table td:last-child {
border-left: @invertedCellBorder;
}
}
}
}
}

/*--------------
Sizes
---------------*/
Expand Down
110 changes: 110 additions & 0 deletions src/definitions/elements/container.less
Original file line number Diff line number Diff line change
Expand Up @@ -164,5 +164,115 @@
hyphens: auto;
}
}
& when (@variationContainerScrolling) {
/*--------------
Scrolling
---------------*/
.ui.scrolling.container {
overflow: auto;
}
@media only screen and (max-width : @largestMobileScreen) {
& when (@variationContainerScrollingShort) {
.ui.scrolling.container.short {
max-height: @scrollingMobileMaxHeight * 0.75;
}
}
& when (@variationContainerScrollingVeryShort) {
.ui.scrolling.container[class*="very short"] {
max-height: @scrollingMobileMaxHeight * 0.5;
}
}
.ui.scrolling.container {
max-height: @scrollingMobileMaxHeight;
}
& when (@variationContainerScrollingLong) {
.ui.scrolling.container.long {
max-height: @scrollingMobileMaxHeight * 2;
}
}
& when (@variationContainerScrollingVeryLong) {
.ui.scrolling.container[class*="very long"] {
max-height: @scrollingMobileMaxHeight * 3;
}
}
}

@media only screen and (min-width: @tabletBreakpoint) {
& when (@variationContainerScrollingShort) {
.ui.scrolling.container.short {
max-height: @scrollingTabletMaxHeight * 0.75;
}
}
& when (@variationContainerScrollingVeryShort) {
.ui.scrolling.container[class*="very short"] {
max-height: @scrollingTabletMaxHeight * 0.5;
}
}
.ui.scrolling.container {
max-height: @scrollingTabletMaxHeight;
}
& when (@variationContainerScrollingLong) {
.ui.scrolling.container.long {
max-height: @scrollingTabletMaxHeight * 2;
}
}
& when (@variationContainerScrollingVeryLong) {
.ui.scrolling.container[class*="very long"] {
max-height: @scrollingTabletMaxHeight * 3;
}
}
}
@media only screen and (min-width: @computerBreakpoint) {
& when (@variationContainerScrollingShort) {
.ui.scrolling.container.short {
max-height: @scrollingComputerMaxHeight * 0.75;
}
}
& when (@variationContainerScrollingVeryShort) {
.ui.scrolling.container[class*="very short"] {
max-height: @scrollingComputerMaxHeight * 0.5;
}
}
.ui.scrolling.container {
max-height: @scrollingComputerMaxHeight;
}
& when (@variationContainerScrollingLong) {
.ui.scrolling.container.long {
max-height: @scrollingComputerMaxHeight * 2;
}
}
& when (@variationContainerScrollingVeryLong) {
.ui.scrolling.container[class*="very long"]{
max-height: @scrollingComputerMaxHeight * 3;
}
}
}
@media only screen and (min-width: @widescreenMonitorBreakpoint) {
& when (@variationContainerScrollingShort) {
.ui.scrolling.container.short {
max-height: @scrollingWidescreenMaxHeight * 0.75;
}
}
& when (@variationContainerScrollingVeryShort) {
.ui.scrolling.container[class*="very short"] {
max-height: @scrollingWidescreenMaxHeight * 0.5;
}
}
.ui.scrolling.container {
max-height: @scrollingWidescreenMaxHeight;
}
& when (@variationContainerScrollingLong) {
.ui.scrolling.container.long {
max-height: @scrollingWidescreenMaxHeight * 2;
}
}
& when (@variationContainerScrollingVeryLong) {
.ui.scrolling.container[class*="very long"] {
max-height: @scrollingWidescreenMaxHeight * 3;
}
}
}
}


.loadUIOverrides();
Loading

0 comments on commit 46bc57a

Please sign in to comment.