Skip to content

Add scrollbar-width and scrollbar-color utilities#19981

Merged
RobinMalfait merged 5 commits into
mainfrom
claude/add-scrollbar-css-properties-EBKFM
May 4, 2026
Merged

Add scrollbar-width and scrollbar-color utilities#19981
RobinMalfait merged 5 commits into
mainfrom
claude/add-scrollbar-css-properties-EBKFM

Conversation

@adamwathan
Copy link
Copy Markdown
Member

Summary

Adds utilities for the scrollbar-width and scrollbar-color CSS properties.

scrollbar-width

Three static utilities mirroring the spec keywords:

Class CSS
scrollbar-auto scrollbar-width: auto;
scrollbar-thin scrollbar-width: thin;
scrollbar-none scrollbar-width: none;

scrollbar-color

The scrollbar-color property 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-thumb and --tw-scrollbar-track), following the same pattern as the gradient stop utilities (from-* / via-* / to-*):

Class CSS
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-color with --color as 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.

<div class="scrollbar-thin scrollbar-thumb-red-500 scrollbar-track-zinc-200"></div>

Test plan

  • pnpm test (all 4480 tests pass)
  • New scrollbar-width, scrollbar-thumb, and scrollbar-track test cases in utilities.test.ts covering palette colors, theme-key colors, current / inherit / transparent, arbitrary colors, /<alpha> modifiers, and invalid candidates
  • intellisense.test.ts snapshot updated to include the new class names

Generated by Claude Code

@adamwathan adamwathan requested a review from a team as a code owner April 25, 2026 20:33
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Apr 25, 2026

Caution

Review failed

The pull request is closed.

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: c633de97-50c9-48cf-85b4-3d37801da5a5

📥 Commits

Reviewing files that changed from the base of the PR and between 3e7ad5a and d8aa582.

📒 Files selected for processing (1)
  • CHANGELOG.md

Walkthrough

Adds a feature-flagged set of scrollbar utilities and tests. Introduces exported flag enableScrollbarUtilities (true when process.env.FEATURES_ENV !== 'stable'). When enabled, registers scrollbar-auto, scrollbar-thin, scrollbar-none (map to scrollbar-width) and functional scrollbar-thumb-* / scrollbar-track-* utilities that emit @property blocks for --tw-scrollbar-thumb and --tw-scrollbar-track, assign the resolved color to the targeted variable, and output scrollbar-color: var(--tw-scrollbar-thumb) var(--tw-scrollbar-track). Updates CHANGELOG.md and adds unit tests for these utilities.

🚥 Pre-merge checks | ✅ 4
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title 'Add scrollbar-width and scrollbar-color utilities' clearly and directly summarizes the main objective of the changeset.
Description check ✅ Passed The pull request description provides a comprehensive explanation of the utilities being added, including examples, implementation details, and test coverage.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ 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 @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

🧹 Nitpick comments (1)
CHANGELOG.md (1)

13-13: Add PR reference link for changelog consistency

Line 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

📥 Commits

Reviewing files that changed from the base of the PR and between 3a890c3 and da4c45b.

⛔ Files ignored due to path filters (1)
  • packages/tailwindcss/src/__snapshots__/intellisense.test.ts.snap is excluded by !**/*.snap
📒 Files selected for processing (3)
  • CHANGELOG.md
  • packages/tailwindcss/src/utilities.test.ts
  • packages/tailwindcss/src/utilities.ts

@uta-bogle
Copy link
Copy Markdown

uta-bogle commented Apr 28, 2026

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 scrollbar-gutter classes)

/*
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.

@RobinMalfait RobinMalfait force-pushed the claude/add-scrollbar-css-properties-EBKFM branch from da4c45b to 9b98b3f Compare April 28, 2026 13:29
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

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

📥 Commits

Reviewing files that changed from the base of the PR and between da4c45b and 9b98b3f.

⛔ Files ignored due to path filters (1)
  • packages/tailwindcss/src/__snapshots__/intellisense.test.ts.snap is excluded by !**/*.snap
📒 Files selected for processing (4)
  • CHANGELOG.md
  • packages/tailwindcss/src/feature-flags.ts
  • packages/tailwindcss/src/utilities.test.ts
  • packages/tailwindcss/src/utilities.ts
✅ Files skipped from review due to trivial changes (2)
  • packages/tailwindcss/src/feature-flags.ts
  • CHANGELOG.md

Comment on lines +2230 to +2240
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)'),
],
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot Apr 28, 2026

Choose a reason for hiding this comment

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

🛠️ 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:


🏁 Script executed:

# First, let's examine the exact code around lines 2230-2240
sed -n '2220,2250p' packages/tailwindcss/src/utilities.ts

Repository: 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 -100

Repository: 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 -20

Repository: 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 -20

Repository: 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.md

Repository: 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 -50

Repository: 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.

Suggested change
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.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

  • We rely on @property in 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-color work 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.

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.

@RobinMalfait, thank you for the clarification — both points are well taken.

  1. @property fallbacks: Understood. Since Tailwind v4 already depends on @property pervasively (border-spacing, translate, scale, gradient stops, shadows, etc.), bare var(--tw-scrollbar-thumb) without inline fallbacks is consistent with the established pattern. The @property initial-value serves as the fallback.

  2. Progressive enhancement: That's a good framing. The browser minimum target governs core layout/color infrastructure, not the availability of newer CSS features. scrollbar-color simply 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.

claude and others added 4 commits May 4, 2026 17:04
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.
@RobinMalfait RobinMalfait force-pushed the claude/add-scrollbar-css-properties-EBKFM branch from 980dacd to 3e7ad5a Compare May 4, 2026 15:06
@greptile-apps
Copy link
Copy Markdown
Contributor

greptile-apps Bot commented May 4, 2026

Confidence Score: 5/5

Safe 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

Comment thread CHANGELOG.md Outdated
Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
@RobinMalfait RobinMalfait merged commit b4db3b9 into main May 4, 2026
6 of 7 checks passed
@RobinMalfait RobinMalfait deleted the claude/add-scrollbar-css-properties-EBKFM branch May 4, 2026 15:16
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.

4 participants