Uh oh!
There was an error while loading. Please reload this page.
- Notifications
You must be signed in to change notification settings - Fork 677
UnderlineNav: Improve flickering by moving icon visibility control to a one-way CSS animation#8108
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Uh oh!
There was an error while loading. Please reload this page.
Changes from all commits
a789e19302d6796fac497a10a95ca1f49a55076e188965e7cf75591315d64ebb79ae2e56140686b360c12c8e848c9c8c00b3e85f5aa035a891f39dbfc168b4File filter
Filter by extension
Conversations
Uh oh!
There was an error while loading. Please reload this page.
Jump to
Uh oh!
There was an error while loading. Please reload this page.
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,5 @@ | ||
| --- | ||
| "@primer/react": patch | ||
| --- | ||
| `UnderlineNav`: Fix icon flickering on some screen sizes before initial render/hydration |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -2,31 +2,50 @@ | ||
| /* Progressive enhancement: Detect overflow using scroll-based animations. | ||
| The idiomatic way would be a scroll-state container query but browser support | ||
| is slightly better for animations. */ | ||
| animation: detect-overflow linear; | ||
| animation: detect-overflow; | ||
| animation-timeline: scroll(self block); | ||
| --UnderlineNav_moreButton-visibility: hidden; | ||
| --UnderlineNav_icons-display: inline; | ||
| &[data-hide-icons='true'] { | ||
| --UnderlineNav_icons-display: none; | ||
| } | ||
| --UnderlineNav_hide-icons-play-state: paused; | ||
| &[data-has-overflow='true'] { | ||
| --UnderlineNav_moreButton-visibility: visible; | ||
| } | ||
| &[data-hide-icons='true'] [data-component='icon'] { | ||
| display: none; | ||
| } | ||
| } | ||
| @keyframes detect-overflow { | ||
| 0%, | ||
| 100% { | ||
| --UnderlineNav_moreButton-visibility: visible; | ||
| --UnderlineNav_icons-display: none; | ||
| --UnderlineNav_hide-icons-play-state: running; | ||
| } | ||
| } | ||
| .ItemsList [data-component='icon'] { | ||
| display: var(--UnderlineNav_icons-display); | ||
| /* Unlike the more button, the icons are removed from the layout when hidden. This can cause the container to no | ||
| longer overflow, which would cause a flickering loop if we just drove the visibility directly from the scroll state. | ||
| So instead we drive an animation that can only play forwards so the icons stay hidden for the life of the page, even | ||
| if the container is no longer overflowing. We can't just make the scroll-driven animation itself play forwards, | ||
| because scroll-driven animations are conditionally applied and revert when not scrollable. */ | ||
| animation-name: hide-icons; | ||
| animation-fill-mode: forwards; | ||
| animation-play-state: var(--UnderlineNav_hide-icons-play-state); | ||
| animation-duration: 0.1ms; /* must be greater than 0 */ | ||
| } | ||
| @keyframes hide-icons { | ||
| 0% { | ||
| display: inline; | ||
| } | ||
| 0.1%, | ||
| 100% { | ||
| display: none; | ||
| } | ||
| } | ||
iansan5653 marked this conversation as resolved.
Uh oh!There was an error while loading. Please reload this page. | ||
| .MoreButtonContainer { | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -18,18 +18,14 @@ | ||
| padding-inline: unset; | ||
| } | ||
| &[data-hide-icons='true'] [data-component='icon'] { | ||
| display: none; | ||
| } | ||
| &[data-overflow-mode='wrap'] { | ||
| /* Wrap items onto hidden next lines */ | ||
| overflow: hidden; | ||
| max-height: var(--control-xlarge-size); | ||
| .UnderlineItemList { | ||
| flex-wrap: wrap; | ||
| overflow: hidden; | ||
| flex: 1; | ||
Comment on lines
-32
to
+28
ContributorAuthor There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
| ||
| } | ||
| } | ||
| } | ||
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Interestingly, this can't be arbitrarily small;
0.0001msis treated as0in Chrome.0.1msseems to work very consistently though.I did try making the duration dynamic, instead of the play state, and setting the duration to
0to immediately resolve the animation when I want to toggle it. That didn't work though; the style didn't 'stick' if the duration was increased again.