angular / angular/components

bug(focus): Persistent focus/ripple indicator stays visible on click

Đang mở
#32,365 1 bình luận 2 reaction 0 người được giao Xem trên GitHub
needs: discussion P4
Ngôn ngữ chính
TypeScript
Star
25k
Fork
6.8k
Merge trung bình
1 ngày 8 giờ
Pull request đã merge (30 ngày)
91

Mô tả

### Is this a regression?

- [x] Yes, this behavior used to work in the previous version

### The previous version in which this bug was not present was

v14.2.7

### Description

There is a long-standing issue in Angular Material where, after clicking on interactive components (buttons, radio buttons, checkboxes, slide-toggle), the focus or “ripple” visual indicator remains visible until the user clicks somewhere else (i.e., until the component loses focus).

### Key points:

1. **History of this issue**
- In issue #13544 (Oct 2018), a user reported that the radio ripple doesn’t fade when clicking: "the ripple doesn't fade away until it loses focus." The team responded that "it is intentional ***but only supposed to be for keyboard and programmatic focus.***"
- In #14349 (Dec 2018), the animation "outer circle remains at the end [...] disappears only if I click somewhere" — also closed as _working as intended_ for some obscure reasons (contradicting the answer from 2 months before)
- In #23807 (Oct. 2021), someones note that this started around Angular 11 and continues through Angular 12 and 13, and _**has been patched on v14**_, even if the issue was apparently related to PR #16512, which was merged for accessibility reasons, and maintainers indicated at that time they didn’t want to revert it
- In #25188 (June 2022), someone reports that "clicked element contains cdk-program-focused class instead of cdk-mouse-focused", got answered that it "_Should've been fixed_ in #25232", but linked PR doesn't seem to be about cdk-mouse-focused at all?
- In #31569 (July 2025), it's a bit different as it concerns menu items but still has the same issue: "right click first item gets focus (which he should), but he also receive focus:visible ring design". Another user points out that it may be related to "the sequence of events the CDK sends to it", but the issue died without any proper investigation.

2. **Fixes attempted**
- The FocusMonitor bug #25188 (Jun 2022) where `cdk-program-focused` is incorrectly applied on mouse click was marked as completed
- The associated PR #25232 improved focus detection, especially when a label is clicked, but it doesn’t entirely solve the visual persistence issue for all components.

3. **Version testing on the Angular Material doc site**
After checking each latest minor version on the material.angular.dev website:
- For checkboxes, the issue does not appear in earlier **latest** minor versions (before v15), but is present again from v15 onward (tested in v16, v17… up to v21 RC). A few issues also indicate this bug actually existed in version like v14 but got fixed before the latest minor, hence why I couldn't check it today.
- For radio buttons, the bug is visible from v11 to v13, was fixed in v14 (see #23807), but was reintroduced somewhen during v15 until today

4. **Accessibility & UX concerns**
- The persistent indicator can be confusing: after clicking, the element looks like it’s still “active” or focused, which might not reflect its real state
- Most other libraries I've checked fade out ripples after *mouse* click, so this behavior is surprising for people used to other websites
- According to the CSS `:focus-visible` mechanism, focus indication should ideally reflect input modality (e.g. keyboard vs mouse). The MDN spec explains that `:focus-visible` is designed to show focus rings only when useful (e.g. keyboard navigation), precisely to differentiate when focus indicators should be shown depending on input modality (y'know, on the contrary to `:focus`...).
- Persistent focus indicators can degrade usability or cause visual noise, especially in complex UI flows (I actually got several bug reports from customers confused by it)

### Reproduction

StackBlitz link: https://stackblitz.com/edit/components-issue-starter-dqjhk5mq?file=src%2Fmain.ts
Steps to reproduce:
1. Use Angular Material (e.g. version 15+)
2. Render a component like `` or ``
3. Click the element with the mouse
4. Observe that the ripple or focus ring stays visible after the click completes
5. Click somewhere else (outside the element) to unfocus and notice how the focus indicator disappears

### Expected Behavior

- After a mouse click, the ripple/focus indicator should fade out (or be removed) even if the component remains focused.
- The behavior should be consistent across input types: mouse clicks vs keyboard interactions
- Persistent focus indicators should align with modern focus pseudo-attributes (`:focus` vs `:focus-visible`), showing visible indicators only when needed and not “sticking” unnecessarily after click interactions

### Actual Behavior

- Ripple or focus ring remains on the component after click and only goes away when the component loses focus (when clicking away)
- This behavior is visible on both checkboxes, radio buttons and actual buttons
- The bug has appeared, disappeared, and reappeared across versions, suggesting regression or incomplete fix

### Environment

Doesn't really matter that much but here's the linked Stackblitz env.
- Angular: 18.2.8
- Browser(s): Firefox 145.0
- Operating System (e.g. Windows, macOS, Ubuntu): Windows 11, macOS 26

Hướng dẫn đóng góp

Mở hướng dẫn đóng góp

Hướng nghiên cứu

Bắt đầu với bản tái hiện StackBlitz được liên kết và so sánh hành vi khi nhấp chuột đối với mat-radio-button, mat-checkbox và các nút giữa những phiên bản được báo cáo. Theo dõi cách xử lý focus và ripple được các component này sử dụng, sau đó xác minh rằng các chỉ báo chuột mờ dần mà không ngăn hiển thị focus bằng bàn phím, đồng thời hành vi nhất quán trên các loại input được liệt kê.

Do mô hình lập chỉ mục viết ra từ nội dung của issue.

Đánh giá

Công nghệ
angular, typescript
Lĩnh vực
accessibility, frontend
Loại issue
Lỗi
Độ khó
4/5
Thời gian dự kiến
3-5 ngày
Mức độ hoạt động
Đình trệ
Độ rõ ràng
Khá rõ ràng
Mức phù hợp với người mới
38/100

Nhận issue mới trong hộp thư của bạn

Bản tóm tắt ngắn những issue GitHub phù hợp với người mới.