patterntailwindModerate
Sticky table columns: border-collapse borders, popover display utilities and focus hidden under sticky cells
Viewed 0 times
Chrome 133+ (anchor positioning, popover), Tailwind v4
border-collapse sticky borderpopover display none overridefocus hidden under sticky columnscroll-padding focusanchor-nameWCAG 2.4.11
Problem
Three related bugs in a horizontally scrolling data table with sticky (frozen) left columns and a sticky right "+" column, plus header popovers: (1) a border-left on a position:sticky cell in a border-collapse table is not visible until the table is scrolled to the end; (2) a closed popover list with a Tailwind
flex class is rendered open inside the header cell; (3) keyboard focus lands on a header link half hidden under the sticky columns, even with scroll-padding on the scroll container.Solution
(1) Draw the separator on the sticky cell itself with an inset box-shadow (e.g.
shadow-[inset_1px_0_0_var(--color-line)]) instead of a border: collapsed borders belong to the grid, not to the stuck box. (2) Never put a display utility (flex, grid, block) directly on a [popover] element: it overrides the UA [popover]:not(:popover-open){display:none}. Use [&:popover-open]:flex, and test that the closed popover class has no bare display utility. (3) Set scroll-padding-inline-start/end on the scroll container (frozen width / sticky right width) AND add a focusin listener on the container that, when the target is not inside a sticky cell, computes how far its rect overlaps the padded zones and adjusts scrollLeft: Chrome only honours scroll-padding when it decides to scroll, and an element already inside the scrollport but under a sticky cell is not scrolled. Also: put anchor-name on a sibling of the popover (e.g. the header label), not on a wrapper that contains the popover.Why
Collapsed borders are painted per grid line; sticky only offsets the cell box. Author utilities beat the UA popover display rule. Focus scrolling uses "if needed" semantics against the full scrollport, ignoring overlays from sticky siblings.
Gotchas
- A real-mouse click helper that calls scrollIntoView before clicking can miss items in an anchored popover: the popover re-anchors one frame later.
- Programmatic showPopover() without an invoker still restores focus to the element focused at show time when it closes.
Context
Building data tables with frozen columns and header menus (popover API) in Chromium browsers.
Revisions (0)
No revisions yet.