Skip to content

Fix pressed and focus states of the horizontal activity bar in Modern UI - #329784

Open
Tony (Bosphoramus) wants to merge 2 commits into
microsoft:mainfrom
Bosphoramus:fix/modern-ui-composite-bar-pressed-state
Open

Fix pressed and focus states of the horizontal activity bar in Modern UI#329784
Tony (Bosphoramus) wants to merge 2 commits into
microsoft:mainfrom
Bosphoramus:fix/modern-ui-composite-bar-pressed-state

Conversation

@Bosphoramus

Copy link
Copy Markdown
Contributor

When the activity bar sits at the top or bottom of a part, the rounded box was suppressed on :active, exposing the pre-Modern-UI indicator underneath: a flat, full-bleed fill plus a thin border line. Pressing an inactive item removed all feedback instead.

Keep the box while pressed and give it its own fill, one step beyond the active one on the same ramp, so a press reads as a distinct state.

Drop the border line entirely and replace the keyboard focus affordance with a ring around the box. Gating it on :focus-visible keeps it off every mouse path, including the window after release where the part's .clicked guard expires.

All rules stay behind .style-override, so the default design is unchanged.

Good (Neutral):
Screenshot 2026-08-08 at 23 45 42

Bad (Holding click on nav item)
image

Bad (Focusing nav item with tab)
image

--- Fix

Neutral:
image

Clicking nav item (pressed/active):
image

Focusing with tab:
image

When the activity bar sits at the top or bottom of a part, the rounded
box was suppressed on :active, exposing the pre-Modern-UI indicator
underneath: a flat, full-bleed fill plus a thin border line. Pressing an
inactive item removed all feedback instead.

Keep the box while pressed and give it its own fill, one step beyond the
active one on the same ramp, so a press reads as a distinct state.

Drop the border line entirely and replace the keyboard focus affordance
with a ring around the box. Gating it on :focus-visible keeps it off
every mouse path, including the window after release where the part's
.clicked guard expires.

All rules stay behind .style-override, so the default design is
unchanged.
Copilot AI balanced review requested due to automatic review settings August 8, 2026 21:53

Copilot AI left a comment

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.

Pull request overview

Updates Modern UI’s horizontal activity bar to improve pressed and keyboard-focus states.

Changes:

  • Adds a pressed-state background token.
  • Preserves rounded indicators while pressed.
  • Replaces legacy focus lines with :focus-visible rings.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 1 comment.

File Description
tabs.css Defines pressed-state colors.
activityBar.css Updates pressed and focus styling.
vscode-known-variables.json Registers the new CSS variable.
Suppressed comments (1)

src/vs/workbench/contrib/styleOverrides/browser/media/activityBar.css:229

  • This keyboard focus ring is also invisible for the auxiliary bar and base panel because the targeted .active-item-indicator is set to display: none at lines 370–372. Since those parts suppress the action item's native outline as well (for example browser/parts/auxiliarybar/media/auxiliaryBarPart.css:41-43), keyboard users in non-high-contrast themes still receive no visible focus affordance there. Please apply the :focus-visible ring to those special 24px action items or make their indicator render for focus.
.style-override .pane-composite-part > .title > .composite-bar-container > .composite-bar > .monaco-action-bar .action-item.icon:focus-visible .active-item-indicator,
.style-override .pane-composite-part > .header-or-footer > .composite-bar-container > .composite-bar > .monaco-action-bar .action-item.icon:focus-visible .active-item-indicator {

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment on lines +210 to +214
.style-override .pane-composite-part > .title > .composite-bar-container:not(.dragged-over):not(.dragged-over-head):not(.dragged-over-tail) > .composite-bar > .monaco-action-bar .action-item.icon.checked:active .active-item-indicator,
.style-override .pane-composite-part > .title > .composite-bar-container:not(.dragged-over):not(.dragged-over-head):not(.dragged-over-tail) > .composite-bar > .monaco-action-bar .action-item.icon:not(.checked):hover:active .active-item-indicator,
.style-override .pane-composite-part > .header-or-footer > .composite-bar-container:not(.dragged-over):not(.dragged-over-head):not(.dragged-over-tail) > .composite-bar > .monaco-action-bar .action-item.icon.checked:active .active-item-indicator,
.style-override .pane-composite-part > .header-or-footer > .composite-bar-container:not(.dragged-over):not(.dragged-over-head):not(.dragged-over-tail) > .composite-bar > .monaco-action-bar .action-item.icon:not(.checked):hover:active .active-item-indicator {
background-color: var(--modern-ui-tab-pressed-background);
Both parts hide the active item indicator, since they paint their active
state on the item itself. They also hide the item's own outline, so a
keyboard user tabbing onto them saw nothing at all.

Keep the indicator hidden except while the item has keyboard focus, the
same way the Agents window gates it. There the indicator carries only the
ring, as a fill of its own would stack on the item's and make a focused
active item look brighter than it should.

Also simplify the comments added by the previous commit.

Copilot AI left a comment

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.

Pull request overview

Copilot reviewed 3 out of 3 changed files in this pull request and generated no new comments.

Suppressed comments (2)

src/vs/workbench/contrib/styleOverrides/browser/media/activityBar.css:371

  • These exceptions still suppress the new pressed fill for the auxiliary-bar and base-panel variants. Their item-level fills in tabs.css:417-429 explicitly stop matching on :active; during a pointer press the indicator is also display: none here, and a previously keyboard-focused item reaches the later transparent override. Keep the indicator visible and nontransparent while active so these horizontal items receive the pressed state too.
.style-override.monaco-workbench .part.auxiliarybar > .header-or-footer > .composite-bar-container > .composite-bar > .monaco-action-bar .action-item.icon:not(:focus-visible) .active-item-indicator,
.style-override.monaco-workbench .pane-composite-part.basepanel > .title > .composite-bar-container > .composite-bar > .monaco-action-bar .action-item.icon:not(:focus-visible) .active-item-indicator {

src/vs/workbench/contrib/styleOverrides/browser/media/activityBar.css:215

  • This sentence is missing the comparison needed to connect it to the preceding explanation.
 * and would otherwise show the ring on every click. Same split the
 * `keyboardFocusOnly` module makes on the other panel surfaces.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants