Overlay clipping: _isScrollable should be root- and display-aware, and treat overflow: hidden as cropping
Nessuno ha ancora preso questa issue.
Valutazione
- Difficoltà
- 4/5
- Tempo stimato
- 3-5 giorni
- Idoneità per principianti
- 52/100
- Tipo di issue
- Bug
- Chiarezza
- Specificata chiaramente
- Stato di attività
- Tranquilla
- Stack tecnologico
- javascript, typescript
- Ambito
- frontend
Direzione di ricerca
Inizia in shepherd.js/src/components/shepherd-modal.ts, in _isScrollable, quindi esamina la gestione di scrollTo in step.ts e la suite Cypress esistente. Riproduci i casi overflow-hidden, overflow di body propagato, inline e contents in un browser invece di affidarti a happy-dom. Il lavoro è completato quando la copertura Cypress dimostra il clipping corretto e l’apertura dell’overlay rimane visibile per i layout descritti.
Scritto dal modello di indicizzazione a partire dal testo della issue.
Descrizione
Split out of a review discussion on #3483.
_isScrollable in shepherd.js/src/components/shepherd-modal.ts decides which ancestors crop a highlighted element, and it currently reads:
overflowY !== 'hidden' && overflowY !== 'visible' && el.scrollHeight >= el.clientHeight
Two things are wrong with it, in opposite directions.
It misses ancestors that really do crop
overflow-y: hidden clips its overflowing descendants — it just isn't user-scrollable. Excluding it means the overlay cuts a full-size hole over content the user cannot see: a highlight inside a collapsed overflow: hidden; height: 0 accordion, a carousel track, or a hidden pane that has been scrolled programmatically. Note the predicate already accepts clip, which crops identically and differs only in not establishing a scroll container, so the current handling is internally inconsistent.
But simply dropping the exclusion regresses real layouts
getComputedStyle(el).overflowY === 'hidden' is not the same claim as "this box clips". Reproduced in Chrome:
body { height: 100vh; overflow: hidden; margin: 0 } /* html untouched */
Because html's overflow is visible, body's overflow propagates to the viewport and body's used value becomes visible. Body does not clip, and content below its 100vh box paints normally — but getComputedStyle(body).overflowY still returns "hidden".
Our own scrollTo option (element.scrollIntoView(), step.ts) then scrolls the viewport, which still works under a propagated overflow: hidden. Measured after scrolling a static, in-flow target into view:
body rect: top -998, bottom -554 (entirely off-screen)
target rect: top 202, bottom 242 (fully visible)
excluding hidden (today): chain [] -> opening { y: 202, height: 40 }
including hidden: chain ['body'] -> opening { y: 202, height: 0 }
A fully visible target loses its opening and ends up under the dark overlay. This reaches the attachTo target too, not only extraHighlights, since _getScrollParent supplies targetScrollParent.
Two smaller cases share the root cause — computed hidden on a box that doesn't clip:
display: inline— overflow does not apply to non-replaced inlines;clientHeightis 0 and the rect is the union of line boxes.display: contents— generates no box at all;getBoundingClientRect()is 0×0 at the origin, which would zero every opening beneath it.
The scrollHeight >= clientHeight term is inert
Per CSSOM-View the scrolling area is at least the padding box, so this is true by construction for every element that has a box, and 0 >= 0 for every element that doesn't. It filters nothing and is not the safety valve it looks like. (It is >=, not >, so it doesn't even exclude non-overflowing containers.)
Suggested shape
Make the predicate root- and display-aware rather than just broadening it:
- never treat
document.documentElementas a clipper; - treat
document.bodyas a clipper only whengetComputedStyle(document.documentElement).overflowY !== 'visible', i.e. nothing propagated up from it; - skip ancestors whose computed
displayisinlineorcontents; - then accept
hiddenalongsideauto,scroll, andclip.
Filtering just html/body restores the failing case above to { y: 202, height: 40 }, so the narrowing does work.
Testing note
None of this can be unit tested as things stand. Nothing in the unit or Cypress suites sets overflow-y to hidden, the modal spec mocks getComputedStyle wholesale, and happy-dom has no layout engine — so overflow propagation, display: inline line boxes, and display: contents box generation cannot be expressed there. This needs Cypress coverage, which is a large part of why it was kept out of #3483.
- Lingua principale
- JavaScript
- Stelle
- 13.8k
- Fork
- 658
- Merge medio
- 7g 5h
- PR unite (30g)
- 18
Guida per i contributori
Apri la guida per i contributori
Come iniziare
- Leggi tutta la issue e poi la guida ai contributi del progetto.
- Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
- Fai un fork del repository e lavora su un branch.
- Apri una pull request che faccia riferimento al numero della issue.
Altre issue di shipshapecode/shepherd
-
Docs: rendering framework components as step content, and why DOM injection belongs in when.show Apertadocumentation
Difficoltà 2/5 1-3 ore Idoneità per principianti 84/100
shipshapecode/shepherd#3479 ·
-
Difficoltà 3/5 1-2 giorni Idoneità per principianti 52/100
shipshapecode/shepherd#3505 ·
-
bug
Difficoltà 4/5 3-5 giorni Idoneità per principianti 52/100
shipshapecode/shepherd#3478 ·
-
Difficoltà 4/5 3-5 giorni Idoneità per principianti 48/100
shipshapecode/shepherd#3442 · 1 commento · 2 reazioni ·
-
Difficoltà 5/5 Più di una settimana Idoneità per principianti 25/100
shipshapecode/shepherd#3146 · 2 commenti ·
Tutte le issue di shipshapecode/shepherd
Issue simili
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 65/100
-
Theme loads third-party resources on every page (jsdelivr web font, cdnjs Font Awesome) – GDPR Aperta
Difficoltà 2/5 1-3 ore Idoneità per principianti 75/100
docToolchain/docToolchain#1705 ·
-
Timezone select lists one option per character; duplicate "Failed" reason; shared tracker popover id Apertabug
Difficoltà 2/5 1-3 ore Idoneità per principianti 75/100
nightscout/nocturne#1414 ·
-
bug v2
Difficoltà 2/5 1-3 ore Idoneità per principianti 75/100
modelcontextprotocol/inspector#2458 · 1 commento ·
-
Mend: dependency security vulnerability status: needs triage 🕵️♀️
Difficoltà 2/5 1-3 ore Idoneità per principianti 70/100
carbon-design-system/ibm-products#9907 ·