@appius-fr/apx 2.7.0 → 2.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/APX.mjs +1 -2
- package/README.md +32 -7
- package/dist/APX.dev.mjs +777 -296
- package/dist/APX.mjs +1 -1
- package/dist/APX.prod.mjs +1 -1
- package/dist/APX.standalone.js +691 -160
- package/dist/APX.standalone.js.map +1 -1
- package/modules/scrollableTable/CHANGELOG.md +45 -0
- package/modules/scrollableTable/README.md +122 -52
- package/modules/scrollableTable/css/scrollableTable.css +67 -60
- package/modules/scrollableTable/scrollableTable.mjs +594 -198
- package/modules/tools/CHANGELOG.md +29 -0
- package/modules/tools/README.md +50 -1
- package/modules/tools/exports.mjs +7 -1
- package/modules/tools/getScrollbarSize.mjs +24 -0
- package/modules/tools/loadCss.mjs +46 -0
- package/modules/tristate/CHANGELOG.md +5 -3
- package/package.json +1 -1
- package/modules/common.mjs +0 -18
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
# Changelog — Scrollable Table module
|
|
2
|
+
|
|
3
|
+
All notable changes to this module are documented here.
|
|
4
|
+
|
|
5
|
+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
|
|
6
|
+
|
|
7
|
+
## [2.8.0] - 2026-02-19
|
|
8
|
+
|
|
9
|
+
### Added
|
|
10
|
+
- Option **`defaultSizingUnit`**: `{ cols?: string, rows?: string }` — controls the CSS unit used for measured column widths and row heights. `cols` defaults to `'fr'` (proportional), `rows` defaults to `'px'` (exact). Accepts any CSS unit string, but only `'fr'` and `'px'` produce meaningful results with measured pixel values. Per-column/per-row overrides and full template strings still take precedence.
|
|
11
|
+
|
|
12
|
+
### Changed
|
|
13
|
+
- **Scrollbar gutter default**: the fallback for `--apx-scrollable-gutter-width` is now the measured vertical scrollbar width (`getScrollbarSize('vertical')`) instead of a fixed 17px. Override in CSS or set to `0` still works as before.
|
|
14
|
+
|
|
15
|
+
## [2.7.1] - 2025-02-16
|
|
16
|
+
|
|
17
|
+
### Added
|
|
18
|
+
- Option **`height`**: fixed body height (number or CSS length). When set, the tbody row always uses this height; `maxHeight` is ignored. Class `apx-scrollable-table--body-height` is applied.
|
|
19
|
+
- Option **`bodyHeightDynamic`**: dynamic body height — `{ get: (table) => number|string, useAs: 'height'|'maxHeight', updateOn?: { scroll?, resize?, scrollOn?, resizeOn? } }`. Re-resolves body size when scroll/resize sources fire (viewport, scrollbar appearance, or custom elements). **updateOn** uses booleans `scroll`/`resize` (default true = document scroll + window resize) or explicit `scrollOn`/`resizeOn` arrays with sentinels `'document'`/`'window'` or elements (ResizeObserver for resize elements). Lazy cleanup: tables removed from the DOM are dropped from updates on the next event (no MutationObserver).
|
|
20
|
+
- Option **`gridTemplateColumns`**: full override for column tracks (e.g. `'1fr 2fr 1fr'`). Skips width measurement.
|
|
21
|
+
- Option **`gridTemplateRows`**: per-section override `{ thead?, tbody?, tfoot? }` for row tracks.
|
|
22
|
+
- Option **`columnOverrides`**: hybrid mode — column index → CSS value (object or array). Columns not overridden keep measured width.
|
|
23
|
+
- Option **`rowOverrides`**: hybrid mode — per-section row index → CSS value. Rows not overridden keep measured height.
|
|
24
|
+
- **Column width preservation**: widths are measured from the table’s natural layout (before applying the module) and applied as `grid-template-columns`; stored in ref for refresh.
|
|
25
|
+
- **Row height preservation**: each `<tr>` height is measured and applied so rowspan cells keep correct proportions.
|
|
26
|
+
- **Scrollbar gutter**: dedicated grid column for the vertical scrollbar so it does not overlap the last data column. CSS variable `--apx-scrollable-gutter-width` (default 17px); set to `0` to allow overlap.
|
|
27
|
+
- CSS variables **`--apx-scrollable-thead-template-rows`**, **`--apx-scrollable-tbody-template-rows`**, **`--apx-scrollable-tfoot-template-rows`** for row track overrides.
|
|
28
|
+
|
|
29
|
+
### Fixed
|
|
30
|
+
- **Horizontal scrollbar on init**: the grid class and template-columns were applied in the same layout pass, causing the tbody to overflow horizontally. The grid is now established first (with a forced reflow) before setting the measured template-columns.
|
|
31
|
+
- Measured column widths now use `fr` units instead of `px` so they remain flexible alongside the fixed gutter column.
|
|
32
|
+
|
|
33
|
+
### Changed
|
|
34
|
+
- Removed `scrollbar-gutter: stable` from tbody; scrollbar space is now the dedicated gutter column.
|
|
35
|
+
- Grid template columns: value is set via `--apx-scrollable-template-columns` (with gutter suffix). Fallback in CSS includes gutter.
|
|
36
|
+
- Body size: when `height` is set, grid row uses fixed size; otherwise `fit-content(max-height)` as before. With `bodyHeightDynamic`, body size is resolved from `get(table)` at init and on scroll/resize (throttled).
|
|
37
|
+
|
|
38
|
+
## [2.7.0] - 2025-02-16
|
|
39
|
+
|
|
40
|
+
### Added
|
|
41
|
+
- Initial release: scrollable tbody with fixed thead/tfoot, CSS Grid + subgrid.
|
|
42
|
+
- `APX('table').scrollableTable(options)` and `scrollableTable('refresh')`.
|
|
43
|
+
- Option `maxHeight` (number or CSS length).
|
|
44
|
+
- Full colspan/rowspan support via explicit grid placement.
|
|
45
|
+
- Demo: `demo/modules/scrollableTable/index.html`.
|
|
@@ -1,52 +1,122 @@
|
|
|
1
|
-
# APX Scrollable Table Module
|
|
2
|
-
|
|
3
|
-
Makes the **tbody** of a table scrollable while keeping **thead** and **tfoot** fixed and column alignment consistent. Uses CSS Grid with subgrid so no JavaScript is needed for width syncing or scrollbar compensation.
|
|
4
|
-
|
|
5
|
-
## Requirements
|
|
6
|
-
|
|
7
|
-
- Modern browsers with **CSS subgrid** support (Chrome 117+, Safari 16+, Firefox 71+). See [caniuse](https://caniuse.com/css-subgrid).
|
|
8
|
-
|
|
9
|
-
## Installation
|
|
10
|
-
|
|
11
|
-
The module is part of APX. Ensure the scrollableTable augment is applied (see `APX.mjs`).
|
|
12
|
-
|
|
13
|
-
CSS is loaded automatically when the module is imported.
|
|
14
|
-
|
|
15
|
-
## Usage
|
|
16
|
-
|
|
17
|
-
### Init
|
|
18
|
-
|
|
19
|
-
```js
|
|
20
|
-
APX('table.my-table').scrollableTable({ maxHeight: 300 });
|
|
21
|
-
// or with a CSS length
|
|
22
|
-
APX('table.my-table').scrollableTable({ maxHeight: '50vh' });
|
|
23
|
-
```
|
|
24
|
-
|
|
25
|
-
Calling `scrollableTable(options)` again with no options or an empty object does nothing (idempotent). Passing new options (e.g. a different `maxHeight`) updates the stored options and re-applies the layout.
|
|
26
|
-
|
|
27
|
-
### Refresh
|
|
28
|
-
|
|
29
|
-
After changing the table DOM (adding/removing rows, changing colspan/rowspan), re-apply the layout with the same options:
|
|
30
|
-
|
|
31
|
-
```js
|
|
32
|
-
APX('table.my-table').scrollableTable('refresh');
|
|
33
|
-
```
|
|
34
|
-
|
|
35
|
-
## Options
|
|
36
|
-
|
|
37
|
-
| Option
|
|
38
|
-
|
|
|
39
|
-
| `maxHeight`
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
1
|
+
# APX Scrollable Table Module
|
|
2
|
+
|
|
3
|
+
Makes the **tbody** of a table scrollable while keeping **thead** and **tfoot** fixed and column alignment consistent. Uses CSS Grid with subgrid so no JavaScript is needed for width syncing or scrollbar compensation.
|
|
4
|
+
|
|
5
|
+
## Requirements
|
|
6
|
+
|
|
7
|
+
- Modern browsers with **CSS subgrid** support (Chrome 117+, Safari 16+, Firefox 71+). See [caniuse](https://caniuse.com/css-subgrid).
|
|
8
|
+
|
|
9
|
+
## Installation
|
|
10
|
+
|
|
11
|
+
The module is part of APX. Ensure the scrollableTable augment is applied (see `APX.mjs`).
|
|
12
|
+
|
|
13
|
+
CSS is loaded automatically when the module is imported.
|
|
14
|
+
|
|
15
|
+
## Usage
|
|
16
|
+
|
|
17
|
+
### Init
|
|
18
|
+
|
|
19
|
+
```js
|
|
20
|
+
APX('table.my-table').scrollableTable({ maxHeight: 300 });
|
|
21
|
+
// or with a CSS length
|
|
22
|
+
APX('table.my-table').scrollableTable({ maxHeight: '50vh' });
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
Calling `scrollableTable(options)` again with no options or an empty object does nothing (idempotent). Passing new options (e.g. a different `maxHeight`) updates the stored options and re-applies the layout.
|
|
26
|
+
|
|
27
|
+
### Refresh
|
|
28
|
+
|
|
29
|
+
After changing the table DOM (adding/removing rows, changing colspan/rowspan), re-apply the layout with the same options:
|
|
30
|
+
|
|
31
|
+
```js
|
|
32
|
+
APX('table.my-table').scrollableTable('refresh');
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
## Options
|
|
36
|
+
|
|
37
|
+
| Option | Type | Default | Description |
|
|
38
|
+
| ---------------------- | ---------------- | --------- | --------------------------------------------------------------------------- |
|
|
39
|
+
| `maxHeight` | `number` or `string` | `'200px'` | Max height of the tbody (content can be shorter). Number = pixels; string = any CSS length (e.g. `'50vh'`). Ignored when `height` or `bodyHeightDynamic` is set. |
|
|
40
|
+
| `height` | `number` or `string` | — | Fixed height of the tbody (same syntax as `maxHeight`). When set, the tbody row always uses this height even with few rows. Ignored when `bodyHeightDynamic` is set. |
|
|
41
|
+
| `bodyHeightDynamic` | `object` | — | **Dynamic body height:** `{ get: (table) => number|string, useAs: 'height'\|'maxHeight', updateOn?: { scroll?, resize?, scrollOn?, resizeOn? } }`. Re-resolves height when scroll/resize sources fire. See [Dynamic body height](#dynamic-body-height) below. |
|
|
42
|
+
| `gridTemplateColumns` | `string` | — | CSS value for column tracks (e.g. `'1fr 2fr 1fr'`). When set, measured widths are skipped and this value is used as-is. |
|
|
43
|
+
| `gridTemplateRows` | `object` | — | Per-section row tracks: `{ thead?: string, tbody?: string, tfoot?: string }` (e.g. `{ tbody: 'auto 40px 40px' }`). When set for a section, measured row heights are skipped for that section. |
|
|
44
|
+
| `rowOverrides` | `object` | — | **Hybrid mode (rows):** per-section row index → CSS value. E.g. `{ tbody: { 0: '48px', 2: '2fr' } }` or `{ thead: ['50px', null] }`. Rows not overridden keep the measured height. Ignored when `gridTemplateRows` is set for that section. |
|
|
45
|
+
| `columnOverrides` | `object` or `array` | — | **Hybrid mode:** column index → CSS value. Columns not overridden keep the measured width. E.g. `{ 0: '2fr', 2: '80px' }` or `['2fr', null, '80px']`. Ignored when `gridTemplateColumns` is set. |
|
|
46
|
+
| `defaultSizingUnit` | `object` | — | CSS unit for measured widths/heights: `{ cols?: string, rows?: string }`. `cols` defaults to `'fr'` (proportional), `rows` defaults to `'px'` (exact). See [Default sizing unit](#default-sizing-unit) below. |
|
|
47
|
+
|
|
48
|
+
### Dynamic body height
|
|
49
|
+
|
|
50
|
+
When `bodyHeightDynamic` is set, the tbody size is computed by `get(table)` (returning a number or CSS length string) and applied as `height` or `maxHeight` according to `useAs`. The value is re-resolved when the sources in `updateOn` fire, so the table can adapt to viewport resize or scrollbar appearance.
|
|
51
|
+
|
|
52
|
+
**updateOn** (optional) controls where we listen:
|
|
53
|
+
|
|
54
|
+
- **Booleans:** `scroll` (default `false`) / `resize` (default `true` when omitted). When `scroll` is `true`, we listen to document/window scroll. When `resize` is `true`, we listen to window resize and observe `document.documentElement` (so scrollbar appearance triggers an update). Set to `false` to disable.
|
|
55
|
+
- **Explicit sources:** `scrollOn` / `resizeOn` — arrays of targets. Use sentinels `'document'` (scroll) and `'window'` (resize), or pass elements (we listen to `scroll` on them, or observe them with `ResizeObserver` for resize). When provided (non-empty), they override the boolean defaults.
|
|
56
|
+
|
|
57
|
+
Example: viewport-based max-height with default resize (scrollbar pop + window resize):
|
|
58
|
+
|
|
59
|
+
```js
|
|
60
|
+
APX('table.my-table').scrollableTable({
|
|
61
|
+
bodyHeightDynamic: {
|
|
62
|
+
get: (table) => window.innerHeight - table.getBoundingClientRect().top - 40,
|
|
63
|
+
useAs: 'maxHeight',
|
|
64
|
+
// updateOn omitted => scroll: false, resize: true (window + ResizeObserver on document)
|
|
65
|
+
}
|
|
66
|
+
});
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
Example: also react to a scrollable parent:
|
|
70
|
+
|
|
71
|
+
```js
|
|
72
|
+
APX('table.my-table').scrollableTable({
|
|
73
|
+
bodyHeightDynamic: {
|
|
74
|
+
get: (table) => ...,
|
|
75
|
+
useAs: 'maxHeight',
|
|
76
|
+
updateOn: { scrollOn: ['document', document.querySelector('#main')], resizeOn: ['window'] }
|
|
77
|
+
}
|
|
78
|
+
});
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
**Cleanup:** Tables removed from the DOM are removed from the update set on the next scroll/resize (lazy cleanup via `isConnected`). No MutationObserver is used.
|
|
82
|
+
|
|
83
|
+
### Default sizing unit
|
|
84
|
+
|
|
85
|
+
By default, measured column widths are applied as `fr` (proportional — columns fill the container and maintain their ratios) and row heights as `px` (exact pixel values). Use `defaultSizingUnit` to swap these defaults:
|
|
86
|
+
|
|
87
|
+
```js
|
|
88
|
+
// Lock columns to exact pixel widths instead of proportional
|
|
89
|
+
APX('table.my-table').scrollableTable({
|
|
90
|
+
maxHeight: 300,
|
|
91
|
+
defaultSizingUnit: { cols: 'px' }
|
|
92
|
+
});
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
Only `'fr'` and `'px'` produce meaningful results (the numeric values come from `getBoundingClientRect()`). Per-column/per-row overrides (`columnOverrides`, `rowOverrides`) and full template strings (`gridTemplateColumns`, `gridTemplateRows`) still take precedence over the default unit.
|
|
96
|
+
|
|
97
|
+
## CSS variables (override)
|
|
98
|
+
|
|
99
|
+
You can override row tracks in CSS via custom properties (e.g. on the table or a parent):
|
|
100
|
+
|
|
101
|
+
- `--apx-scrollable-thead-template-rows` — thead row tracks (e.g. `50px 50px`)
|
|
102
|
+
- `--apx-scrollable-tbody-template-rows` — tbody row tracks
|
|
103
|
+
- `--apx-scrollable-tfoot-template-rows` — tfoot row tracks
|
|
104
|
+
|
|
105
|
+
If set, they override the measured or default row heights for that section.
|
|
106
|
+
|
|
107
|
+
A dedicated column is reserved for the vertical scrollbar so it does not overlap the last data column. Its width is controlled by:
|
|
108
|
+
|
|
109
|
+
- `--apx-scrollable-gutter-width` — default is the measured vertical scrollbar width (via `getScrollbarSize`). Set to `0` if you want the scrollbar to overlap (e.g. with thin scrollbars).
|
|
110
|
+
|
|
111
|
+
## Colspan and rowspan
|
|
112
|
+
|
|
113
|
+
Tables with **colspan** and **rowspan** are supported. The module sets explicit grid placement on each cell so thead, tbody, and tfoot stay aligned. Complex headers or merged cells in the body/foot work as expected.
|
|
114
|
+
|
|
115
|
+
## Edge cases
|
|
116
|
+
|
|
117
|
+
- **Empty tbody:** The layout is still applied; the tbody area is scrollable with no content.
|
|
118
|
+
- **No thead or no tfoot:** Tables with only thead+tbody or tbody+tfoot are supported; grid rows adjust automatically.
|
|
119
|
+
|
|
120
|
+
## Browser support
|
|
121
|
+
|
|
122
|
+
Requires **CSS subgrid**. No fallback is provided in this module; for legacy browsers, consider a different approach or a separate fallback implementation.
|
|
@@ -1,60 +1,67 @@
|
|
|
1
|
-
/* APX Scrollable Table: scrollable tbody with fixed thead/tfoot and aligned columns (CSS Grid + subgrid)
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
.apx-scrollable-table
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
grid-template-rows:
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
.apx-scrollable-table > thead
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
grid-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
.apx-scrollable-table
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
1
|
+
/* APX Scrollable Table: scrollable tbody with fixed thead/tfoot and aligned columns (CSS Grid + subgrid)
|
|
2
|
+
Use !important so page styles (e.g. display: table) do not override the grid layout. */
|
|
3
|
+
|
|
4
|
+
/* --apx-scrollable-template-columns: set by JS (measured widths + gutter); fallback = equal columns + gutter */
|
|
5
|
+
/* --apx-scrollable-gutter-width: space for vertical scrollbar so it does not overlap the last column (set to 0 to allow overlap) */
|
|
6
|
+
/* --apx-scrollable-body-height: when class apx-scrollable-table--body-height is set, tbody row uses fixed height instead of max-height */
|
|
7
|
+
.apx-scrollable-table {
|
|
8
|
+
display: grid !important;
|
|
9
|
+
grid-template-columns: var(--apx-scrollable-template-columns, repeat(var(--apx-scrollable-cols, 3), minmax(0, 1fr)) minmax(var(--apx-scrollable-gutter-width, 17px), var(--apx-scrollable-gutter-width, 17px)));
|
|
10
|
+
grid-template-rows: auto var(--apx-scrollable-body-row-size, fit-content(var(--apx-scrollable-body-max-height, 200px))) auto;
|
|
11
|
+
width: 100%;
|
|
12
|
+
table-layout: unset !important;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
.apx-scrollable-table--body-height {
|
|
16
|
+
--apx-scrollable-body-row-size: var(--apx-scrollable-body-max-height, 200px);
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
/* Table with no tfoot: thead + tbody only */
|
|
20
|
+
.apx-scrollable-table:not(.apx-scrollable-table--has-tfoot) {
|
|
21
|
+
grid-template-rows: auto var(--apx-scrollable-body-row-size, fit-content(var(--apx-scrollable-body-max-height, 200px)));
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
/* Table with no thead: tbody + tfoot only */
|
|
25
|
+
.apx-scrollable-table.apx-scrollable-table--no-thead {
|
|
26
|
+
grid-template-rows: var(--apx-scrollable-body-row-size, fit-content(var(--apx-scrollable-body-max-height, 200px))) auto;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/* Table with neither thead nor tfoot: tbody only */
|
|
30
|
+
.apx-scrollable-table.apx-scrollable-table--no-thead:not(.apx-scrollable-table--has-tfoot) {
|
|
31
|
+
grid-template-rows: var(--apx-scrollable-body-row-size, fit-content(var(--apx-scrollable-body-max-height, 200px)));
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/* --apx-scrollable-*-template-rows: set by JS (measured heights) or override in CSS / via options */
|
|
35
|
+
.apx-scrollable-table > thead,
|
|
36
|
+
.apx-scrollable-table > tbody,
|
|
37
|
+
.apx-scrollable-table > tfoot {
|
|
38
|
+
display: grid !important;
|
|
39
|
+
grid-template-columns: subgrid;
|
|
40
|
+
grid-column: 1 / -1;
|
|
41
|
+
min-height: 0;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
.apx-scrollable-table > thead {
|
|
45
|
+
grid-template-rows: var(--apx-scrollable-thead-template-rows, repeat(var(--apx-scrollable-thead-rows, 1), auto));
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
.apx-scrollable-table > tbody {
|
|
49
|
+
grid-template-rows: var(--apx-scrollable-tbody-template-rows, repeat(var(--apx-scrollable-tbody-rows, 1), auto));
|
|
50
|
+
overflow: auto;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
.apx-scrollable-table > tfoot {
|
|
54
|
+
grid-template-rows: var(--apx-scrollable-tfoot-template-rows, repeat(var(--apx-scrollable-tfoot-rows, 1), auto));
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
.apx-scrollable-table > thead > tr,
|
|
58
|
+
.apx-scrollable-table > tbody > tr,
|
|
59
|
+
.apx-scrollable-table > tfoot > tr {
|
|
60
|
+
display: contents !important;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
.apx-scrollable-table th,
|
|
64
|
+
.apx-scrollable-table td {
|
|
65
|
+
min-width: 0;
|
|
66
|
+
box-sizing: border-box;
|
|
67
|
+
}
|