Conversation
Clone the `<thead>` into a fixed-position overlay that appears below the sticky page header when a `.table-container` table with at least 10 body rows scrolls past the breadcrumbs bar. The overlay mirrors the table's horizontal scroll position and shifts up by the cell's `border-top-width` to overlap the breadcrumbs bar's bottom border. Native `position: sticky` cannot be used here because `.table-container` sets `overflow-x: auto`, which makes it a scroll container on both axes and confines sticky positioning within it instead of relative to the viewport.
Contributor
|
8ab3f6d was deployed to: https://fred-pr1585.review.mdn.allizom.net/ |
The mobile left sidebar is a fixed overlay at `--z-index-sidebar-mobile`, so a sticky table header at `--z-index-sticky-header - 1` floated above it while the sidebar was open.
The overlay is `position: fixed`, which repeats on every printed page when the header happens to be stuck at print time.
Use the actual offset between the table and container rects instead of `-scrollLeft`. This absorbs any container padding or border and is direction-agnostic, should RTL locales ever be added.
`aria-hidden` and `pointer-events: none` left cloned links and buttons in `<th>` keyboard-focusable. `inert` covers focus, hit testing, and the accessibility tree at once. Duplicated `id`s on cloned cells are removed so fragment navigation keeps targeting the original table.
`syncSize` reads a rect per header cell plus a computed style, forcing layout on every scroll frame while stuck. Widths only change when the table or container resizes, so run it on the stick transition and on resize signals, and only reposition the clone on plain scroll frames.
Copy the classes of the closest `.content-section` onto the overlay instead of hardcoding `content-section`, and skip tables outside one, since that is where the table styles the clone relies on are scoped.
Inert nodes are skipped by hit testing, so with `inert` on the overlay clicks fell through to links underneath. Mark only the cloned table inert; the wrapper stays hittable and absorbs the click.
Replace `inert` with `aria-hidden` plus `tabindex="-1"` on focusable descendants. The clone stays out of the tab order and the accessibility tree, but pointer events reach its links so header links keep working while stuck. Clicks elsewhere on the clone are still absorbed by the overlay.
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description
Add a sticky
<thead>for tables wrapped in.table-containerthat have at least 10 body rows. A newhooks/sticky-table-header.js:<thead>into aposition: fixedoverlay placed just below the sticky page header,transform: translateX(...), andThe overlay shifts up by the cell's computed
border-top-widthso it overlaps the breadcrumbs bar's 1px bottom border instead of stacking with it.Motivation
Make column headers remain visible while scrolling through long content tables, without changing how
.table-containerhandles wide tables. Nativeposition: stickycan't be used because.table-containersetsoverflow-x: auto, which makes it a scroll container on both axes and confines sticky positioning within it instead of relative to the viewport.Additional details
.page-layout__header's bottom edge at runtime, so it follows the page header height..table-containeris mirrored on the clone by translating it by the offset between the table and container rects (direction-agnostic, absorbs container padding).aria-hidden, its focusable descendants gettabindex="-1", and duplicatedids are stripped: links inside<th>stay clickable while the clone is shown, but are not announced or reachable via Tab twice, and fragment links keep targeting the original table. Clicks elsewhere on the clone are absorbed by the overlay..content-sectionso the clone picks up the same table styles; tables outside one are skipped.ResizeObserverkeeps cell widths in sync when the table or container resizes; plain scroll frames only reposition the clone.Example: https://fred-pr1585.review.mdn.allizom.net/en-US/docs/Web/HTML/Reference/Attributes#attribute_list
Related issues or pull requests
Fixes #933.