_table.scss
14.2 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
// --- General styling ---
.table.b-table {
// Table fixed header width layout
&.b-table-fixed {
// Fixed width columns
table-layout: fixed;
}
// Disabled border-collapse
// Mainly for use with sticky headers and columns
&.b-table-no-border-collapse {
border-collapse: separate;
border-spacing: 0;
}
// Table busy styling
&[aria-busy="true"] {
opacity: $b-table-busy-opacity;
}
// Details row styling
> tbody > tr.b-table-details > td {
border-top: none !important;
}
// Caption positioning
> caption {
caption-side: bottom;
}
&.b-table-caption-top {
> caption {
caption-side: top !important;
}
}
// Re-declare `table-active` class here so that it can take
// precedence over row variants when used on selectable rows
// Class can only be applied to rows and not individual cells
> tbody > .table-active {
&,
> th,
> td {
background-color: $table-active-bg;
}
}
// Add special hover styling for `table-active` row variant
&.table-hover > tbody > tr.table-active:hover {
td,
th {
color: $table-hover-color;
// `$table-hover-bg` default is a very transparent black
// We overlay it over the background color to achieve the
// same color effect while keeping the background solid
background-image: linear-gradient($table-hover-bg, $table-hover-bg);
background-repeat: no-repeat;
}
}
// Add in missing `bg-active` class for table tbody rows
// Bootstrap v4.3 is missing this for dark tables
// `bg-active` class cannot be applied to individual cells
> tbody > .bg-active {
&,
> th,
> td {
// Important is needed to override the standard `bg-variants`
// as the also use `!important`
background-color: $table-dark-active-bg !important;
}
}
// Add special hover styling for `bg-active` row variant (dark tables)
&.table-hover.table-dark > tbody > tr.bg-active:hover {
td,
th {
color: $table-dark-hover-color;
// `$table-dark-hover-bg` default is a very transparent white
// We overlay it over the background color to achieve the
// same color effect while keeping the background solid
background-image: linear-gradient($table-dark-hover-bg, $table-dark-hover-bg);
background-repeat: no-repeat;
}
}
}
// --- Table sticky header styling ---
@if $bv-enable-table-sticky {
.b-table-sticky-header,
.table-responsive,
[class*="table-responsive-"] {
// Move the table bottom margin to the wrapper
margin-bottom: $spacer;
> .table {
// Reset `margin-bottom` to we don't get a space after
// the table inside the scroll area
margin-bottom: 0;
}
}
.b-table-sticky-header {
overflow-y: auto;
// Annoyingly, when overflow-y is set, browsers convert
// 'overflow-x: visible' to 'overflow-x: auto' - so it becomes
// responsive in the x axis automatically
// Default `max-height` before a scrollbar will show
// We don't use `height` as table could be shorter than this value
max-height: $b-table-sticky-header-max-height;
}
@media print {
// Override any styles (including inline styles)
// when printing
.b-table-sticky-header {
overflow-y: visible !important;
max-height: none !important;
}
}
@supports (position: sticky) {
// Positioning of sticky headers
.b-table-sticky-header > .table.b-table > thead > tr > th {
// Header cells need to be sticky on top
position: sticky;
top: 0;
z-index: 2;
}
// Positioning of sticky columns
// Sticky columns only work when table has sticky
// headers and/or is responsive
.b-table-sticky-header,
.table-responsive,
[class*="table-responsive-"] {
> .table.b-table {
> thead,
> tbody,
> tfoot {
> tr > .b-table-sticky-column {
position: sticky;
left: 0;
}
}
> thead {
> tr > .b-table-sticky-column {
// z-index needs to be higher than sticky columns and
// sticky headers for correct layering
z-index: 5;
}
}
> tbody,
> tfoot {
> tr > .b-table-sticky-column {
// z-index needs to be lower than sticky header that
// is also a sticky column
z-index: 2;
}
}
}
}
// Default theme color background for table cells that are sticky
// Applied only when no variant is applied to the rows, or no head-variant
// Needed because Bootstrap v4 does not have table child elements set up
// to inherit their background color from parent element by default
//
// An issue made at twbs/bootstrap repo for table
// background color inheritance:
// https://github.com/twbs/bootstrap/issues/29244
// If implemented, would negate the need for all the below SCSS
.table.b-table {
> thead,
> tbody,
> tfoot {
> tr > .table-b-table-default {
// Default cell color
color: $table-color;
// `$table-bg` is null by default in Bootstrap v4 variables
// but could have a value set by the consumer
background-color: if($table-bg, $table-bg, $body-bg);
}
}
&.table-dark {
> thead,
> tbody,
> tfoot {
> tr > .bg-b-table-default {
// Default cell color in table dark mode
color: $table-dark-color;
// Default cell background color in table dark mode
background-color: $table-dark-bg;
}
}
}
// Handle case of zebra striping
&.table-striped {
// "fake" zebra striping via use of a transparent background image
> tbody > tr:nth-of-type(#{$table-striped-order}) > .table-b-table-default {
// `$table-accent-bg` (used for striping) default is a very transparent black
// We overlay it over the background color to achieve the same color
// effect while keeping the background solid.
background-image: linear-gradient($table-accent-bg, $table-accent-bg);
background-repeat: no-repeat;
}
&.table-dark {
> tbody > tr:nth-of-type(#{$table-striped-order}) > .bg-b-table-default {
// `$table-dark-accent-bg` (used for striping) default is a very transparent white
// We overlay it over the background color to achieve the same color
// effect while keeping the background solid.
background-image: linear-gradient($table-dark-accent-bg, $table-dark-accent-bg);
background-repeat: no-repeat;
}
}
}
// Handle case of hover
&.table-hover {
// "fake" hover via use of a transparent background image
> tbody > tr:hover > .table-b-table-default {
color: $table-hover-color;
// `$table-hover-bg` default is a very transparent black
// We overlay it over the background color to achieve the same color
// effect while keeping the background solid.
background-image: linear-gradient($table-hover-bg, $table-hover-bg);
background-repeat: no-repeat;
}
&.table-dark {
> tbody > tr:hover > .bg-b-table-default {
color: $table-dark-hover-color;
// `$table-dark-hover-bg` default is a very transparent white
// We overlay it over the background color to achieve the same color
// effect while keeping the background solid.
background-image: linear-gradient($table-dark-hover-bg, $table-dark-hover-bg);
background-repeat: no-repeat;
}
}
}
}
}
}
// --- Header sort styling ---
// Bootstrap v4.4 will include this variable as `$escaped-characters`
// But if we want to preserve backwards compatibility with v4.3, we leave this in
$bv-escaped-characters: (("<", "%3c"), (">", "%3e"), ("#", "%23"));
// Bootstrap v4.4 will include this method as `escape-svg`
// But if we want to preserve backwards compatibility with v4.3, we leave this in
// See https://codepen.io/kevinweber/pen/dXWoRw
@function bv-escape-svg($string) {
@if str-index($string, "data:image/svg+xml") {
@each $char, $encoded in $bv-escaped-characters {
$string: str-replace($string, $char, $encoded);
}
}
@return $string;
}
.table.b-table {
> thead,
> tfoot {
> tr {
> [aria-sort] {
cursor: pointer;
background-image: none;
background-repeat: no-repeat;
background-size: $b-table-sort-icon-bg-width $b-table-sort-icon-bg-height;
&:not(.b-table-sort-icon-left) {
// Default is icon on the right
background-position: right calc(#{$table-cell-padding} / 2) center;
padding-right: calc(#{$table-cell-padding} + #{$b-table-sort-icon-bg-width});
}
&.b-table-sort-icon-left {
// Left aligned sort icon
background-position: left calc(#{$table-cell-padding} / 2) center;
padding-left: calc(#{$table-cell-padding} + #{$b-table-sort-icon-bg-width});
}
}
> [aria-sort="none"] {
background-image: bv-escape-svg($b-table-sort-icon-bg-not-sorted);
}
> [aria-sort="ascending"] {
background-image: bv-escape-svg($b-table-sort-icon-bg-ascending);
}
> [aria-sort="descending"] {
background-image: bv-escape-svg($b-table-sort-icon-bg-descending);
}
}
}
// Sort icons for dark tables, headers, footers
&.table-dark > thead > tr,
&.table-dark > tfoot > tr,
> .thead-dark > tr {
> [aria-sort="none"] {
background-image: bv-escape-svg($b-table-sort-icon-bg-dark-not-sorted);
}
> [aria-sort="ascending"] {
background-image: bv-escape-svg($b-table-sort-icon-bg-dark-ascending);
}
> [aria-sort="descending"] {
background-image: bv-escape-svg($b-table-sort-icon-bg-dark-descending);
}
}
// Sort icons when header cell has `table-dark` class
> thead > tr > .table-dark,
> tfoot > tr > .table-dark {
&[aria-sort="none"] {
background-image: bv-escape-svg($b-table-sort-icon-bg-dark-not-sorted);
}
&[aria-sort="ascending"] {
background-image: bv-escape-svg($b-table-sort-icon-bg-dark-ascending);
}
&[aria-sort="descending"] {
background-image: bv-escape-svg($b-table-sort-icon-bg-dark-descending);
}
}
// Padding and position adjustment for small tables
&.table-sm {
> thead,
> tfoot {
> tr > [aria-sort] {
&:not(.b-table-sort-icon-left) {
// Default is icon on the right
background-position: right calc(#{$table-cell-padding-sm} / 2) center;
padding-right: calc(#{$table-cell-padding-sm} + #{$b-table-sort-icon-bg-width});
}
&.b-table-sort-icon-left {
// Left aligned sort icon
background-position: left calc(#{$table-cell-padding-sm} / 2) center;
padding-left: calc(#{$table-cell-padding-sm} + #{$b-table-sort-icon-bg-width});
}
}
}
}
}
// --- Selectable rows ---
.table.b-table {
&.b-table-selectable:not(.b-table-selectable-no-click) {
& > tbody > tr {
cursor: pointer;
}
&.b-table-selecting {
// Disabled text-selection when in range mode when
// at least one row selected
&.b-table-select-range > tbody > tr {
user-select: none;
}
}
}
}
// --- Stacked tables ---
@if $bv-enable-table-stacked {
.table.b-table {
&.b-table-stacked {
@each $breakpoint in map-keys($grid-breakpoints) {
$next: breakpoint-next($breakpoint, $grid-breakpoints);
$infix: breakpoint-infix($next, $grid-breakpoints);
&#{$infix} {
@include media-breakpoint-down($breakpoint) {
display: block;
width: 100%;
// Convert to blocks when stacked
> caption,
> tbody,
> tbody > tr,
> tbody > tr > td,
> tbody > tr > th {
display: block;
}
// Hide when stacked
> thead,
> tfoot {
display: none;
> tr.b-table-top-row,
> tr.b-table-bottom-row {
display: none;
}
}
// Caption positioning
> caption {
caption-side: top !important;
}
> tbody {
> tr {
// Turn cells with labels into micro-grids
> [data-label] {
// Cell header label pseudo element
&::before {
content: attr(data-label);
width: $b-table-stacked-heading-width;
float: left;
text-align: right;
overflow-wrap: break-word;
font-weight: bold;
font-style: normal;
padding: 0 calc(#{$b-table-stacked-gap} / 2) 0 0;
margin: 0;
}
// Add clearfix in-case field label wraps
&::after {
display: block;
clear: both;
content: "";
}
// Cell value (we wrap the cell value in a div when stacked)
> div {
display: inline-block;
width: calc(100% - #{$b-table-stacked-heading-width});
// Add "gap" between "cells"
padding: 0 0 0 calc(#{$b-table-stacked-gap} / 2);
margin: 0;
}
}
// Dont show the fixed top/bottom rows
&.top-row,
&.bottom-row {
display: none;
}
// Give the top cell of each "row" a heavy border
> :first-child {
border-top-width: (3 * $table-border-width);
}
// Give any cell after a rowspan'ed cell a heavy top border
> [rowspan] + td,
> [rowspan] + th {
border-top-width: (3 * $table-border-width);
}
}
}
}
}
}
}
}
}