Skip to content

fix(scrollbar): consistent scrollbar styling across Firefox and Chromium browsers (Windows)#514

Open
reniko wants to merge 7 commits into
fccview:developfrom
reniko:fix/scrollbar-edge-chromium
Open

fix(scrollbar): consistent scrollbar styling across Firefox and Chromium browsers (Windows)#514
reniko wants to merge 7 commits into
fccview:developfrom
reniko:fix/scrollbar-edge-chromium

Conversation

@reniko
Copy link
Copy Markdown
Contributor

@reniko reniko commented May 19, 2026

That one was a little harder. My detail knowledge about CSS is a little limited so that one is much more done with Claude. Fell free to merge, adjust, send back or recect this PR.

Problem

Scrollbars were visually inconsistent across browsers:

  • Chrome/Edge: no styled scrollbar on most scrollable containers — the OS-standard scrollbar was shown instead of the app-styled one.
  • Firefox: scrollbar-width: auto !important in globals.css overrode hide-scrollbar's scrollbar-width: none, causing scrollbars to appear where they were explicitly hidden.
  • KanbanCardDetail modal: both scroll panes were not scrollable in Firefox/Edge after a previous change introduced a wrapper div around children.

Root cause

Chrome 121+ changed behaviour: if scrollbar-width is set on an element, Chrome ignores all ::-webkit-scrollbar pseudo-element rules and uses the standard API instead, falling back to the native OS scrollbar on Windows.

The existing globals.css set scrollbar-width: auto !important without a browser guard, which broke the webkit-styled scrollbars in Chromium. The same effect was triggered by tailwind-scrollbar plugin classes (scrollbar-thin, scrollbar-thumb-* etc.) — these also set scrollbar-width on the element.

For KanbanCardDetail: Modal.tsx wraps children in a bare <div className=""> for size="default", which broke the flex height chain needed by the two-pane layout.

Changes

globals.css

  • Moved scrollbar-width: thin + scrollbar-color inside @supports (-moz-appearance: none) (Firefox-only guard), so Firefox gets styled scrollbars without triggering Chrome's standard-API path.
  • Rewrote the ::-webkit-scrollbar block to cover .overflow-y-auto, .overflow-x-auto, .overflow-auto, and .scrollbar-thin consistently — 6 px width, primary/0.3 thumb, transparent track, no scrollbar buttons.
  • Removed the old scrollbar-width: auto !important rule that was breaking hide-scrollbar in Firefox.

KanbanCardDetail.tsx

  • Switched to size="fullscreen" on <Modal> — this wraps children in flex-1 overflow-auto instead of a bare div, restoring the flex chain.
  • Inner container uses min-h-full (not flex-1) since the fullscreen wrapper is not itself a flex container.
  • Both scroll panes use overflow-y-auto without the lg: responsive prefix — the globals.css webkit rules target .overflow-y-auto exactly; the responsive variant .lg\:overflow-y-auto is a different class name and would not match.

ChecklistHome.tsx / NotesHome.tsx

  • Removed hide-scrollbar from main containers. With the corrected global scrollbar styling, hidden scrollbars on these containers caused visual inconsistency with the rest of the app where scrollbars are now consistently visible and styled.

SidebarWrapper.tsx / Kanban.tsx

  • Removed tailwind-scrollbar plugin classes (scrollbar-thin, scrollbar-thumb-*, scrollbar-track-*, scrollbar-*-rounded-md). These set scrollbar-width on the element, which triggers Chrome 121+'s standard-API path and causes the webkit rules in globals.css to be ignored. The global styles already cover .overflow-y-auto and .overflow-auto, so the plugin classes are redundant.

Minor visual change: KanbanCardDetail modal header

Using size="fullscreen" changes the modal header from p-6 padding + mb-6 separator to p-3 border-b — a tighter, more compact look. This is a side effect of the existing fullscreen variant in Modal.tsx and is intentional in this PR; happy to address the original header style separately if preferred.

Tested

  • Chrome / Edge (Chromium): scrollbars visible, styled, no layout regressions in Sidebar, Kanban board, KanbanCardDetail (both panes), ChecklistHome, NotesHome.
  • Firefox: scrollbars styled and thin via @supports guard; hide-scrollbar works again where used.

reniko and others added 7 commits May 18, 2026 16:25
…omium

Replace the old webkit-only 8px scrollbar block with a unified approach:
- @supports (-moz-appearance: none) guard so Firefox-only scrollbar-width/color
  rules don't trigger Chrome 121+ standard scrollbar API
- Unified 6px webkit pseudo-element rules for .overflow-y-auto, .overflow-x-auto,
  .overflow-auto and .scrollbar-thin (no arrows, transparent track)
- Remove hide-scrollbar from Notes/Checklist overview and Sidebar so scrollbars
  are visible in both browsers
- Add tailwind-scrollbar plugin classes to KanbanCardDetail panes and Kanban board

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…change

Upstream added a bare <div> wrapper around Modal children in default size mode,
breaking the flex height chain. Target it via [&>div:last-child] to give it
flex-1 + flex-col so the inner panes get a defined height and can scroll again.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…efox

- Remove tailwind-scrollbar plugin classes from both scroll panes; the plugin
  sets scrollbar-width:thin unconditionally which triggers Chrome 121+ standard
  scrollbar API (auto-hide overlay) making scrollbars invisible in Edge
- Change lg:overflow-y-auto to overflow-y-auto so globals.css webkit rules
  (.overflow-y-auto::-webkit-scrollbar) apply, giving a always-visible 6px bar
- Add lg:[&>div:last-child]:overflow-hidden to prevent the Modal wrapper div
  from showing its own scrollbar on desktop, which overlapped in Firefox

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Tailwind arbitrary variants with pseudo-selectors ([&>div:last-child])
do not compile reliably. Replace with a dedicated CSS class:
.jotty-modal-content.jotty-kanban-detail-modal > div:last-child targets
the bare wrapper div upstream injected, making it flex-1 flex-col so the
inner layout and per-pane overflow-y-auto work again.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
The upstream Modal wrapper div breaks the flex chain for default size.
size=fullscreen gives the children wrapper flex-1 overflow-auto by design.
Inner div uses min-h-full + lg:overflow-hidden so panes scroll independently
on desktop while the wrapper scrolls as one unit on mobile.
Removes the fragile CSS child selector approach.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
scrollbar-thin and related plugin classes set scrollbar-width on Chrome
121+, which causes it to ignore the ::-webkit-scrollbar rules in globals.css
and fall back to native auto-hide scrollbars. The global webkit rules already
cover .overflow-y-auto and .overflow-auto, so the plugin classes are
counterproductive on those elements.
The Firefox-only @supports block listed overflow-y-auto and overflow-auto
but missed overflow-x-auto, leaving horizontally scrolling containers with
the default OS scrollbar in Firefox. The corresponding webkit rules
already include overflow-x-auto.
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.

1 participant