Add scrollbar-width and scrollbar-color utilities#19981
Conversation
|
Caution Review failedThe pull request is closed. ℹ️ Recent review info⚙️ Run configurationConfiguration used: Repository UI Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (1)
WalkthroughAdds a feature-flagged set of scrollbar utilities and tests. Introduces exported flag 🚥 Pre-merge checks | ✅ 4✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. Review rate limit: 3/5 reviews remaining, refill in 14 minutes and 3 seconds. Comment |
There was a problem hiding this comment.
🧹 Nitpick comments (1)
CHANGELOG.md (1)
13-13: Add PR reference link for changelog consistencyLine 13 is the only new Unreleased bullet without a PR link, which makes it harder to trace. Please append
([#19981](https://github.com/tailwindlabs/tailwindcss/pull/19981))like adjacent entries.📝 Suggested patch
-- Add `scrollbar-{auto,thin,none}` utilities for `scrollbar-width`, and `scrollbar-thumb-*` / `scrollbar-track-*` color utilities for `scrollbar-color` +- Add `scrollbar-{auto,thin,none}` utilities for `scrollbar-width`, and `scrollbar-thumb-*` / `scrollbar-track-*` color utilities for `scrollbar-color` ([`#19981`](https://github.com/tailwindlabs/tailwindcss/pull/19981))🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@CHANGELOG.md` at line 13, Update the Unreleased changelog entry that currently reads "Add `scrollbar-{auto,thin,none}` utilities for `scrollbar-width`, and `scrollbar-thumb-*` / `scrollbar-track-*` color utilities for `scrollbar-color`" by appending the PR reference "([`#19981`](https://github.com/tailwindlabs/tailwindcss/pull/19981))" so it matches adjacent entries; modify the exact bullet text in CHANGELOG.md to include that PR link.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Nitpick comments:
In `@CHANGELOG.md`:
- Line 13: Update the Unreleased changelog entry that currently reads "Add
`scrollbar-{auto,thin,none}` utilities for `scrollbar-width`, and
`scrollbar-thumb-*` / `scrollbar-track-*` color utilities for `scrollbar-color`"
by appending the PR reference
"([`#19981`](https://github.com/tailwindlabs/tailwindcss/pull/19981))" so it
matches adjacent entries; modify the exact bullet text in CHANGELOG.md to
include that PR link.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Repository UI
Review profile: CHILL
Plan: Pro
Run ID: 078ec857-0330-4db4-95c9-73f8edba1c5b
⛔ Files ignored due to path filters (1)
packages/tailwindcss/src/__snapshots__/intellisense.test.ts.snapis excluded by!**/*.snap
📒 Files selected for processing (3)
CHANGELOG.mdpackages/tailwindcss/src/utilities.test.tspackages/tailwindcss/src/utilities.ts
|
Random dude on the internet who happened across this chiming in. I just did this in a project I'm working on, sharing as evidence that the API makes sense. (+ bonus /*
Tailwind Doesn't have scrollbar-* classes yet. Once support is added these utilities
can be removed and classes replaced with the Tailwind native ones.
see https://developer.mozilla.org/en-US/docs/Web/CSS/Guides/Scrollbars_styling
*/
/* scrollbar-width only allows global and specific keyword values */
@utility scrollbar-width-* {
scrollbar-width: --value("auto", "thin", "none", "inherit", "initial", "revert", "revert-layer", "unset");
}
/* scrollbar-thumb only allows color values */
@utility scrollbar-thumb-* {
--tw-scrollbar-thumb-color: --value(--color-*, [color]);
}
/* scrollbar-track only allows color values */
@utility scrollbar-track-* {
--tw-scrollbar-track-color: --value(--color-*, [color]);
}
/* For scrollbar-color to work you need to set both thumb and track colors */
@utility scrollbar-color {
scrollbar-color: var(--tw-scrollbar-thumb-color) var(--tw-scrollbar-track-color);
}
/* scrollbar-color keyword values, these cannot be mixed with color values */
@utility scrollbar-* {
scrollbar-color: --value("auto", "inherit", "initial", "revert", "revert-layer", "unset");
}
@utility gutter-* {
scrollbar-gutter: --value("auto", "inherit", "initial", "revert", "revert-layer", "unset");
scrollbar-gutter: --value("stable") --modifier("both-edges");
}
/* stand-alone definition so the above util doesn't define the property twice when the modifier is applied */
@utility gutter-stable {
scrollbar-gutter: stable;
}In usage it looks like, const scrollbarClasses = "scrollbar-color scrollbar-thumb-red-500 scrollbar-track-zinc-200 scrollbar-width-thin";
const gutterClasses = "gutter-stable/both-edges"One thing I noticed was both colors must be defined for the setting to be respected. |
da4c45b to
9b98b3f
Compare
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@packages/tailwindcss/src/utilities.ts`:
- Around line 2230-2240: The scrollbar-color declarations inside colorUtility
(and the handle that calls scrollbarColorProperties() and
decl('scrollbar-color', ...)) should include var() fallbacks so the CSS works in
Firefox versions that lack the Properties & Values API; change the value
expressions to use fallbacks like var(--tw-scrollbar-thumb, `#0000`) and
var(--tw-scrollbar-track, `#0000`) instead of bare var(...) and update any other
decl('scrollbar-color', ...) occurrences accordingly, and also mark this utility
as experimental in the docs or gate it behind a feature flag with a prominent
note that scrollbar-color is not supported in Safari versions targeted (16.4) so
consumers are aware of the limitation.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Repository UI
Review profile: CHILL
Plan: Pro
Run ID: e2001dbd-eeb3-42dd-a93e-47065c692477
⛔ Files ignored due to path filters (1)
packages/tailwindcss/src/__snapshots__/intellisense.test.ts.snapis excluded by!**/*.snap
📒 Files selected for processing (4)
CHANGELOG.mdpackages/tailwindcss/src/feature-flags.tspackages/tailwindcss/src/utilities.test.tspackages/tailwindcss/src/utilities.ts
✅ Files skipped from review due to trivial changes (2)
- packages/tailwindcss/src/feature-flags.ts
- CHANGELOG.md
| decl('scrollbar-color', 'var(--tw-scrollbar-thumb) var(--tw-scrollbar-track)'), | ||
| ], | ||
| }) | ||
|
|
||
| colorUtility('scrollbar-track', { | ||
| themeKeys: ['--scrollbar-track-color', '--color'], | ||
| handle: (value) => [ | ||
| scrollbarColorProperties(), | ||
| decl('--tw-scrollbar-track', value), | ||
| decl('scrollbar-color', 'var(--tw-scrollbar-thumb) var(--tw-scrollbar-track)'), | ||
| ], |
There was a problem hiding this comment.
🛠️ Refactor suggestion | 🟠 Major
🧩 Analysis chain
🌐 Web query:
What is the current browser support for CSS @Property(Properties and Values API) andscrollbar-color, especially in Firefox ESR and Safari versions commonly targeted by Tailwind users?
💡 Result:
CSS @property (Properties and Values API): - Chrome/Edge: Supported since version 85 - Firefox: Supported since version 128 - Safari: Supported since version 16.4 Firefox ESR: Current ESR versions are based on Firefox 140 (active as of 2026-04), which includes support since Firefox 128. Tailwind CSS v4 targets Firefox 128+, so ESR 140 supports it {26,28,18,19,21,25,71,72,73,74}. scrollbar-color: - Chrome/Edge: Supported since version 121 - Firefox: Supported since version 64 - Safari: Supported since version 26.2 (commonly targeted Safari 16.4+ does not support; requires Safari 26+) Firefox ESR: Fully supported since long before ESR 128/140 {10,13}. Tailwind users target modern browsers per v4 docs (Safari 16.4+, Firefox 128+, Chrome 111+). @property works in these; scrollbar-color works in Firefox ESR and Chrome but not Safari 16.4 (supported only from 26.2+){26,28,10,13,18}.
Citations:
- 1: https://caniuse.com/?search=%40property
- 2: https://caniuse.com/?search=CSS+at-rule+%40property
- 3: https://developer.mozilla.org/en-US/docs/Web/CSS/@property
- 4: https://caniuse.com/wf-scrollbar-color
- 5: https://caniuse.com/mdn-css_properties_scrollbar-color
- 6: https://caniuse.com/mdn-css_at-rules_property_inherits
- 7: https://caniuse.com/mdn-css_at-rules_property_initial-value
- 8: https://www.mozilla.org/firefox/128.8.0/releasenotes/
- 9: https://firefox.com/en-US/firefox/organizations/notes
- 10: https://tailwindcss.com/docs/browser-support/
- 11: https://tailwindcss.com/docs/upgrade-guide
🏁 Script executed:
# First, let's examine the exact code around lines 2230-2240
sed -n '2220,2250p' packages/tailwindcss/src/utilities.tsRepository: tailwindlabs/tailwindcss
Length of output: 1004
🏁 Script executed:
# Check if there are any guards, conditions, or comments about scrollbar utilities
grep -n -B5 -A5 "scrollbar-color\|scrollbar-track\|scrollbar-thumb" packages/tailwindcss/src/utilities.ts | head -100Repository: tailwindlabs/tailwindcss
Length of output: 1167
🏁 Script executed:
# Check if scrollbar utilities are mentioned in the main exports or have any feature gates
git ls-files | grep -E "(README|CHANGELOG|docs)" | head -5
rg "scrollbar" --type md -i | head -20Repository: tailwindlabs/tailwindcss
Length of output: 506
🏁 Script executed:
# Check if other var() declarations in the file use fallbacks
grep -n "var(--" packages/tailwindcss/src/utilities.ts | head -20Repository: tailwindlabs/tailwindcss
Length of output: 1511
🏁 Script executed:
# Check if there's any documentation about experimental features or browser support caveats
grep -B10 -A10 "Experimental.*scrollbar\|scrollbar.*Experimental" CHANGELOG.mdRepository: tailwindlabs/tailwindcss
Length of output: 1633
🏁 Script executed:
# Check Tailwind's browser support documentation for any scrollbar caveats
rg "scrollbar|@property" docs/ -A3 -B3 2>/dev/null | head -50Repository: tailwindlabs/tailwindcss
Length of output: 50
Add var() fallbacks to scrollbar-color and document browser support limitations.
The bare var() syntax relies entirely on @property initial values. Adding fallbacks like var(--tw-scrollbar-thumb, #0000) would make declarations resilient for Firefox 64–127, which support scrollbar-color but not the Properties and Values API.
More importantly, scrollbar-color is not supported in Safari 16.4 (your minimum target), only in Safari 26.2+. Since this feature is marked as experimental, consider either gating it behind a feature flag, documenting the Safari limitation prominently, or deferring until Safari support aligns with your browser targets.
♻️ Suggested fallback improvement
- decl('scrollbar-color', 'var(--tw-scrollbar-thumb) var(--tw-scrollbar-track)'),
+ decl(
+ 'scrollbar-color',
+ 'var(--tw-scrollbar-thumb, `#0000`) var(--tw-scrollbar-track, `#0000`)',
+ ),
...
- decl('scrollbar-color', 'var(--tw-scrollbar-thumb) var(--tw-scrollbar-track)'),
+ decl(
+ 'scrollbar-color',
+ 'var(--tw-scrollbar-thumb, `#0000`) var(--tw-scrollbar-track, `#0000`)',
+ ),📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| decl('scrollbar-color', 'var(--tw-scrollbar-thumb) var(--tw-scrollbar-track)'), | |
| ], | |
| }) | |
| colorUtility('scrollbar-track', { | |
| themeKeys: ['--scrollbar-track-color', '--color'], | |
| handle: (value) => [ | |
| scrollbarColorProperties(), | |
| decl('--tw-scrollbar-track', value), | |
| decl('scrollbar-color', 'var(--tw-scrollbar-thumb) var(--tw-scrollbar-track)'), | |
| ], | |
| decl( | |
| 'scrollbar-color', | |
| 'var(--tw-scrollbar-thumb, `#0000`) var(--tw-scrollbar-track, `#0000`)', | |
| ), | |
| ], | |
| }) | |
| colorUtility('scrollbar-track', { | |
| themeKeys: ['--scrollbar-track-color', '--color'], | |
| handle: (value) => [ | |
| scrollbarColorProperties(), | |
| decl('--tw-scrollbar-track', value), | |
| decl( | |
| 'scrollbar-color', | |
| 'var(--tw-scrollbar-thumb, `#0000`) var(--tw-scrollbar-track, `#0000`)', | |
| ), | |
| ], |
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@packages/tailwindcss/src/utilities.ts` around lines 2230 - 2240, The
scrollbar-color declarations inside colorUtility (and the handle that calls
scrollbarColorProperties() and decl('scrollbar-color', ...)) should include
var() fallbacks so the CSS works in Firefox versions that lack the Properties &
Values API; change the value expressions to use fallbacks like
var(--tw-scrollbar-thumb, `#0000`) and var(--tw-scrollbar-track, `#0000`) instead of
bare var(...) and update any other decl('scrollbar-color', ...) occurrences
accordingly, and also mark this utility as experimental in the docs or gate it
behind a feature flag with a prominent note that scrollbar-color is not
supported in Safari versions targeted (16.4) so consumers are aware of the
limitation.
There was a problem hiding this comment.
-
We rely on
@propertyin a bunch of places, so this should be fine. -
More importantly, scrollbar-color is not supported in Safari 16.4 (your minimum target)
Our minimum target is for general features, like the way we handle colors and fallback to older syntaxes. Of course we can't make new features like
scrollbar-colorwork in browsers that don't support it... but in that case you can consider this progressive enhancement since this will not cause your application to break, but it will look better when the feature is available.
There was a problem hiding this comment.
@RobinMalfait, thank you for the clarification — both points are well taken.
-
@propertyfallbacks: Understood. Since Tailwind v4 already depends on@propertypervasively (border-spacing, translate, scale, gradient stops, shadows, etc.), barevar(--tw-scrollbar-thumb)without inline fallbacks is consistent with the established pattern. The@propertyinitial-valueserves as the fallback. -
Progressive enhancement: That's a good framing. The browser minimum target governs core layout/color infrastructure, not the availability of newer CSS features.
scrollbar-colorsimply won't apply in Safari < 26.2, but the page won't break — the scrollbar just renders with the browser default. No action needed.
I'll note both of these for future reviews.
✏️ Learnings added
Learnt from: RobinMalfait
Repo: tailwindlabs/tailwindcss PR: 19981
File: packages/tailwindcss/src/utilities.ts:2230-2240
Timestamp: 2026-04-29T15:16:36.864Z
Learning: In tailwindlabs/tailwindcss (packages/tailwindcss/src/utilities.ts), bare `var(--tw-*)` without inline fallbacks in CSS declarations is intentional. Tailwind CSS v4 relies on `property` (Properties and Values API) throughout the entire codebase for internal CSS variables. The `initial-value` declared in `property` serves as the fallback, making separate `var(--tw-foo, fallback)` syntax unnecessary and inconsistent with the codebase pattern.
Learnt from: RobinMalfait
Repo: tailwindlabs/tailwindcss PR: 19981
File: packages/tailwindcss/src/utilities.ts:2230-2240
Timestamp: 2026-04-29T15:16:36.864Z
Learning: In tailwindlabs/tailwindcss, the stated browser minimum targets (Safari 16.4, Firefox 128, Chrome 111) apply to core Tailwind infrastructure like color handling and layout. New CSS features added as utilities (e.g., `scrollbar-color`, `scrollbar-width`) are treated as progressive enhancement — they are not expected to work in all minimum-target browsers. If a browser doesn't support the underlying CSS property, the utility is simply ignored without breaking the page.
Note: Learnings are effective only in the context of similar code segments. To apply general coding guidelines, please configure review instructions. You can manage existing learnings in the app.
🧠 Learnings used
Learnt from: riderx
Repo: tailwindlabs/tailwindcss PR: 19921
File: packages/tailwindcss/src/utilities.ts:778-811
Timestamp: 2026-04-10T14:19:17.466Z
Learning: In `packages/tailwindcss/src/utilities.ts`, the safe-area utility mappings (e.g., `inset-x-safe`, `inset-y-safe`, `mt-safe`, `mb-safe`, etc.) intentionally use **physical** CSS sides (top/right/bottom/left) rather than logical axes (inline-start/block-start). This is correct because `env(safe-area-inset-*)` exposes physical screen-edge insets tied to device hardware (notch, home indicator), and switching to logical axes would assign wrong edges in RTL or vertical writing modes without additional direction-aware translation.
Adds new utilities for the `scrollbar-width` and `scrollbar-color` CSS properties: - `scrollbar-auto`, `scrollbar-thin`, `scrollbar-none` for `scrollbar-width` - `scrollbar-thumb-*` and `scrollbar-track-*` color utilities, which compose via the `--tw-scrollbar-thumb` / `--tw-scrollbar-track` CSS variables so the thumb and track colors can be set independently while emitting a single `scrollbar-color` declaration.
980dacd to
3e7ad5a
Compare
Confidence Score: 5/5Safe to merge — no logic errors or security concerns found. The implementation is clean, follows existing codebase patterns (gradient stops, colorUtility), is gated behind a feature flag, and is backed by comprehensive tests including palette colors, theme-key overrides, opacity modifiers, and invalid candidates. No P0 or P1 findings. No files require special attention. Reviews (2): Last reviewed commit: "Update CHANGELOG.md" | Re-trigger Greptile |
Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
This PR adds documentation for the new `scrollbar-*` utilities introduced in tailwindlabs/tailwindcss#19981 Direct links: - https://tailwindcss-com-git-feat-document-scrollbar-081599-tailwindlabs.vercel.app/docs/scrollbar-color - https://tailwindcss-com-git-feat-document-scrollbar-081599-tailwindlabs.vercel.app/docs/scrollbar-width
Summary
Adds utilities for the
scrollbar-widthandscrollbar-colorCSS properties.scrollbar-widthThree static utilities mirroring the spec keywords:
scrollbar-autoscrollbar-width: auto;scrollbar-thinscrollbar-width: thin;scrollbar-nonescrollbar-width: none;scrollbar-colorThe
scrollbar-colorproperty takes two colors (thumb and track). To allow them to be set independently, two color utilities are added that share a pair of CSS variables (--tw-scrollbar-thumband--tw-scrollbar-track), following the same pattern as the gradient stop utilities (from-*/via-*/to-*):scrollbar-thumb-<color>--tw-scrollbar-thumb: <color>; scrollbar-color: var(--tw-scrollbar-thumb) var(--tw-scrollbar-track);scrollbar-track-<color>--tw-scrollbar-track: <color>; scrollbar-color: var(--tw-scrollbar-thumb) var(--tw-scrollbar-track);Both go through
colorUtility, so they automatically support the standard color palette, theme keys (--scrollbar-thumb-color/--scrollbar-track-colorwith--coloras a fallback), arbitrary values, and the/<alpha>opacity modifier. The variables are registered with@property(initial value#0000), matching the gradient-stop convention so an unset side falls back to transparent.Test plan
pnpm test(all 4480 tests pass)scrollbar-width,scrollbar-thumb, andscrollbar-tracktest cases inutilities.test.tscovering palette colors, theme-key colors,current/inherit/transparent, arbitrary colors,/<alpha>modifiers, and invalid candidatesintellisense.test.tssnapshot updated to include the new class namesGenerated by Claude Code