Animate SegmentedControl when switching between items - #8304
Conversation
🦋 Changeset detectedLatest commit: 57ffdad The changes in this PR will be included in the next version bump. This PR includes changesets to release 1 package
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
Add a changeset for animating SegmentedControl transitions.
|
| border-style: solid; | ||
| border-width: var(--borderWidth-thin); | ||
| background-color: transparent; | ||
| transition: background-color var(--base-duration-200) var(--base-easing-easeInOut); |
There was a problem hiding this comment.
This ease on the background color helps avoid a slightly glitchy looking appearance when the hover background color appears over the sliding background if you move the mouse fast enough.
There was a problem hiding this comment.
Pull request overview
This PR improves the SegmentedControl UX by adding a smooth “selection knob” transition when switching between items, using CSS Anchor Positioning (with @supports fallback) so consumers get the behavior automatically where supported.
Changes:
- Add an anchor-positioned
::before“knob” on theSegmentedControlroot that transitions itsinsetwhen selection changes (gated byprefers-reduced-motion). - Move selected-state visuals to the anchor-positioned knob in supporting browsers, while preserving the prior per-button styling via an
@supports notfallback. - Add a changeset for a patch release describing the UX improvement.
Show a summary per file
| File | Description |
|---|---|
| packages/react/src/SegmentedControl/SegmentedControl.module.css | Implements anchor-positioning-based selection knob positioning/transition with fallbacks. |
| .changeset/three-places-invent.md | Patch changeset noting SegmentedControl animation when switching items. |
Review details
💡 Add a code-review agent skill for context-aware, tailored reviews. Learn more in the docs.
- Files reviewed: 2/2 changed files
- Comments generated: 1
- Review effort level: Lite
| border-style: solid; | ||
| border-width: var(--borderWidth-thin); | ||
| background-color: transparent; | ||
| transition: background-color var(--base-duration-200) var(--base-easing-easeInOut); |
There was a problem hiding this comment.
Meh, I don't think it's an issue to transition a background color. That's not "motion" like the actual motion is.
|
Integration test results from github/github-ui PR:
All checks passed! |
SegmentedControlworks nicely, but it would feel even nicer if there was a smooth transition when switching between items, as if it was a switch being toggled.Until recently this would have been very challenging to implement. When the background and border are literally implemented as a
backgroundandborder, there's no easy way to transition a background from one element to another one. We could use an absolutely positioned element and transition the position, but how would we know where to put it without expensive and complex JavaScript code?Anchor positioning solves this cleanly! All we need to do is make the current element our anchor, then position the pseudo-element relative to that anchor. We can use
insetwithanchor()function values to get transitionable values and match the size of the underlying element perfectly. The result is simple code and a polished feel:Screen.Recording.2026-08-13.at.5.30.53.PM.mov
Consumers don't need to make any changes to take advantage of this - they'll get the improved UX automatically.
Using
@supports, there is no change in unsupported browsers - they keep the current functionality. And I've gated the motion transition behind an@media (prefers-reduced-motion: no-preference)rule to avoid disrupting/distracting motion for users who prefer to turn it off.Changelog
New
Changed
SegmentedControlRemoved
Rollout strategy
Testing & Reviewing