Minimal reproduction for a scroll regression introduced in Filament v5.7.0: interacting with a modal (opening or closing) scroll-jumps the page when the document is the scroll container.
filament/filamentv5.7.1 (regression introduced in v5.7.0; last good: v5.6.8)- Laravel 13, Livewire 4, PHP 8.4
composer install
cp .env.example .env
php artisan key:generate
touch database/database.sqlite
php artisan migrate
php artisan serveThen open http://127.0.0.1:8000/admin/repro (auth is disabled in this repro for convenience).
- Scroll down so the orange “Open confirmation modal” button is near the top of the viewport
but still visible (the
scrollYbadge, top-right, reads > 0). - Click the button to open the confirmation modal.
- Watch the
scrollYbadge: the page scroll-jumps (the modal's focus management scrolls the document). Closing via Confirm / Cancel / Escape does not restore the position.
Expected: opening/closing the modal leaves the scroll position unchanged. Actual (v5.7.x): the page scrolls.
Note: the exact direction/magnitude is browser- and layout-dependent (Chrome uses
block: "nearest"for focus scrolling). ThescrollYbadge makes any jump measurable. In real apps this shows up most visibly as the page jerking toward the top when a modal closes, because focus returns to the top-anchoredmain.fi-main(tabindex="-1").
The modal component's focus trap lost the .noscroll modifier in v5.7.0.
vendor/filament/support/resources/views/components/modal/index.blade.php
- x-trap.noscroll{{ $focusTrapReturnsFocus ? '' : '.noreturn' }}{{ $autofocus ? '' : '.noautofocus' }}="isTrapActive"
+ x-trap{{ $focusTrapReturnsFocus ? '' : '.noreturn' }}{{ $autofocus ? '' : '.noautofocus' }}="isTrapActive"x-trap's focus activation/restoration calls .focus(), which scrolls the element into view.
.noscroll previously suppressed this. It appears to have been dropped while moving scroll-locking
into Filament's own JS (likely for the nested-modal stuck-scroll-lock issue, #10925 /
alpinejs/alpine#3435), which also removed the scroll suppression.
Editing that one line to re-add .noscroll (or calling the focus restoration with
{ preventScroll: true }) eliminates the jump — verified in this exact reproduction: with .noscroll
the modal opens with scrollY unchanged; without it, scrollY jumps (e.g. 687 → 1691).