Skip to content

Fix inconsistent modal scroll behavior#48789

Draft
noahtalerman wants to merge 3 commits into
fleetdm:mainfrom
noahtalerman:noahtalerman/modal-scroll-lock
Draft

Fix inconsistent modal scroll behavior#48789
noahtalerman wants to merge 3 commits into
fleetdm:mainfrom
noahtalerman:noahtalerman/modal-scroll-lock

Conversation

@noahtalerman

@noahtalerman noahtalerman commented Jul 6, 2026

Copy link
Copy Markdown
Member

Related issue: Resolves #48788

Checklist for submitter

If some of the following don't apply, delete the relevant line.

  • Changes file added for user-visible changes in changes/, orbit/changes/ or ee/fleetd-chrome/changes.
    See Changes files for more information.

Testing

  • Added/updated automated tests
  • QA'd all new/changed functionality manually

Summary

Two fixes for inconsistent modal scroll behavior:

  1. Page scroll lock. Adds a modal-open class on document.body, toggled from the shared Modal component (frontend/components/Modal/Modal.tsx), that sets overflow: hidden on the page while any modal is mounted. The modal's own background overlay is unaffected (overflow: auto, unchanged) so the modal's own content still scrolls. The unlock-on-unmount check counts remaining .modal__background nodes in the DOM rather than a module-level counter, so stacked/hidden modals (e.g. via the isHidden prop) keep the page locked until the last modal closes. Covered by two new Jest tests in Modal.tests.tsx, including a stacked-modal regression case.

  2. Certificate details modal. CertificateDetailsModal's content area had max-height: 600px; overflow-y: auto, so only the content scrolled while the "Close" button footer stayed fixed below it — a "sticky footer" look inconsistent with other Fleet modals (e.g. "Edit columns" on the Hosts page), which scroll as a single unit via the outer modal overlay. Removed the internal height/scroll constraint so this modal now behaves the same way.

Note: I wasn't able to manually QA either fix in a running browser in this environment. The scroll-lock fix has automated test coverage exercising the DOM class toggling directly; the certificate modal fix is a 2-line SCSS-only change. Someone should confirm both visually via make generate-dev before merge — particularly the certificate modal with enough fields to overflow the viewport.

Adds a body.modal-open class, toggled in the shared Modal component, that
sets overflow: hidden on the page while any modal is mounted. The modal's
own background overlay keeps overflow: auto so its content can still
scroll.

Fixes fleetdm#48788
A component's own .modal__background node is already detached from the
DOM by the time its unmount cleanup runs, so the unlock check must be
=== 0 remaining backgrounds, not <= 1 — the latter unlocked scroll one
modal too early when two modals were stacked.
@noahtalerman noahtalerman requested a review from a team as a code owner July 6, 2026 18:25

@claude claude Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Claude Code Review

This pull request is from a fork — automated review is disabled. A repository maintainer can comment @claude review to run a one-time review.

@codecov

codecov Bot commented Jul 6, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 68.03%. Comparing base (2c5bba6) to head (6764d5c).
⚠️ Report is 1 commits behind head on main.

Additional details and impacted files
@@           Coverage Diff           @@
##             main   #48789   +/-   ##
=======================================
  Coverage   68.02%   68.03%           
=======================================
  Files        3682     3682           
  Lines      233995   234000    +5     
  Branches    12308    12309    +1     
=======================================
+ Hits       159186   159191    +5     
  Misses      60490    60490           
  Partials    14319    14319           
Flag Coverage Δ
frontend 58.97% <100.00%> (+<0.01%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

__content had max-height: 600px; overflow-y: auto, which clipped only
the content area while the Close button footer stayed fixed below it,
reading as a sticky footer. Removed so the whole modal scrolls via the
outer overlay, matching EditColumnsModal and other Fleet modals.
@coderabbitai

coderabbitai Bot commented Jul 6, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Walkthrough

This PR adds body scroll locking for open modals. Modal now adds a modal-open class to document.body on mount and removes it only when no modal backgrounds remain. Global styles set body.modal-open to overflow: hidden. Tests cover single and stacked modal cases, and a changelog entry notes the behavior. The certificate details modal also no longer enforces an internal max height or vertical scroll, and its change note is updated.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Out of Scope Changes check ⚠️ Warning The certificate-details modal style change appears unrelated to the linked scroll-lock issue and adds separate behavior changes. Move the certificate modal scroll changes into a separate PR or link the relevant issue if that scope is intended.
✅ Passed checks (4 passed)
Check name Status Explanation
Linked Issues check ✅ Passed The PR implements the requested modal scroll lock and preserves modal content scrolling, matching issue #48788.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Title check ✅ Passed The title clearly summarizes the main change: modal scroll behavior is fixed.
Description check ✅ Passed The description matches the template well and includes the issue, checklist, tests, and summary.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
frontend/styles/global/_global.scss (1)

25-31: 🩺 Stability & Availability | 🔵 Trivial | ⚡ Quick win

No scrollbar-gutter compensation — possible layout shift on modal open.

Setting overflow: hidden on body removes the vertical scrollbar on pages that have one, shifting page content horizontally by the scrollbar width while the modal is open (and shifting back on close). Consider reserving the gutter (e.g. scrollbar-gutter: stable on html, or compensating with padding-right equal to the scrollbar width) to avoid the visible content jump.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@frontend/styles/global/_global.scss` around lines 25 - 31, The body lock in
the modal-open rule currently hides overflow without preserving the scrollbar
gutter, which can cause a horizontal content jump when the modal opens and
closes. Update the global modal scrolling styles in the modal-open block to
reserve space for the scrollbar, either by applying a stable gutter on the root
element or by adding equivalent right-side compensation when overflow is hidden,
so the layout stays fixed while the modal is mounted.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@frontend/styles/global/_global.scss`:
- Around line 25-31: The body lock in the modal-open rule currently hides
overflow without preserving the scrollbar gutter, which can cause a horizontal
content jump when the modal opens and closes. Update the global modal scrolling
styles in the modal-open block to reserve space for the scrollbar, either by
applying a stable gutter on the root element or by adding equivalent right-side
compensation when overflow is hidden, so the layout stays fixed while the modal
is mounted.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 942d9b40-f4b4-44b8-b54f-10817c242711

📥 Commits

Reviewing files that changed from the base of the PR and between 2c5bba6 and a508a21.

📒 Files selected for processing (4)
  • changes/48788-modal-scroll-lock
  • frontend/components/Modal/Modal.tests.tsx
  • frontend/components/Modal/Modal.tsx
  • frontend/styles/global/_global.scss

@noahtalerman noahtalerman marked this pull request as draft July 6, 2026 19:59
@noahtalerman noahtalerman changed the title Lock page scroll while a modal is open Fix inconsistent modal scroll behavior Jul 6, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Modal scroll behavior is inconsistent across the app

1 participant