Skip to content

fix(router): stop adding tabindex to non-anchor elements with routerLink - #70573

Open
arturovt wants to merge 1 commit into
angular:mainfrom
arturovt:fix/router_28345_no-auto-tabindex
Open

arturovt wants to merge 1 commit into
angular:mainfrom
arturovt:fix/router_28345_no-auto-tabindex

Conversation

@arturovt

@arturovt arturovt commented Sep 4, 2026 •

Copy link
Copy Markdown
Contributor

RouterLink set tabindex="0" on every non-anchor element it was put on.
There was no way to opt out, other than writing a tabindex attribute in
the template yourself.

The behavior now sits behind ADD_TABINDEX_TO_NON_ANCHOR_ELEMENTS, a
module-level const. It is false in the published package and stays
true inside Google while internal callers migrate off it.

BREAKING CHANGE: RouterLink no longer adds tabindex="0" to non-anchor
elements, such as <div routerLink> or <button routerLink>. If you
want such an element in the tab order, put tabindex="0" on it in the
template.

Not much is lost here. That tabindex never made the element accessible
anyway. RouterLink only listens for clicks, so a focused <div routerLink>
did nothing when you pressed Enter. Anyone relying on it already had to
add their own keyboard handling to make the element work.

Fixes #28345

@angular-robot angular-robot Bot added detected: breaking change PR contains a commit with a breaking change area: router labels Sep 4, 2026
@ngbot ngbot Bot added this to the Backlog milestone Sep 4, 2026
@arturovt
arturovt marked this pull request as ready for review September 4, 2026 20:00
@pullapprove
pullapprove Bot requested a review from crisbeto September 4, 2026 20:01
@arturovt
arturovt force-pushed the fix/router_28345_no-auto-tabindex branch 2 times, most recently from d5ff504 to 858d62a Compare September 5, 2026 20:52
}
this.applyAttributeValue('tabindex', newTabIndex);
const nativeElement = this.el.nativeElement as HTMLElement;
if (newTabIndex !== null) {

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.

The goal was to retain the current behavior in g3 and this has changed it. This PR should have only 2 things in it. The addition of ADD_TABINDEX_TO_NON_ANCHOR_ELEMENTS const and the early return on that const in this function. The rest will be left for cleanup if/when we can land it internally as well.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Thanks for review, I was waiting for your opinion, updated the code with a minimal change

@arturovt
arturovt force-pushed the fix/router_28345_no-auto-tabindex branch from 858d62a to ec182f8 Compare September 22, 2026 11:40
@atscott
atscott force-pushed the fix/router_28345_no-auto-tabindex branch from ec182f8 to 33ac75e Compare September 22, 2026 17:56
@atscott atscott modified the milestones: Backlog, v23 candidates Sep 22, 2026
@JeanMeche
JeanMeche removed the request for review from crisbeto September 29, 2026 13:08
@JeanMeche JeanMeche added breaking changes target: major This PR is targeted for the next major release and removed state: blocked detected: breaking change PR contains a commit with a breaking change labels Sep 29, 2026
@atscott

atscott commented Oct 1, 2026

Copy link
Copy Markdown
Contributor

Can we also add a note to this that mentions simply adding the tabindex wasn't ever even enough to be correct for a11y anyways? It makes the link focusable but you can't hit enter and have it navigate because there's only a click listener. So to that extent, I don't know how breaking this really is in the end.

RouterLink set `tabindex="0"` on every non-anchor element it was put on.
There was no way to opt out, other than writing a tabindex attribute in
the template yourself.

The behavior now sits behind `ADD_TABINDEX_TO_NON_ANCHOR_ELEMENTS`, a
module-level const. It is `false` in the published package and stays
`true` inside Google while internal callers migrate off it.

BREAKING CHANGE: RouterLink no longer adds `tabindex="0"` to non-anchor
elements, such as `<div routerLink>` or `<button routerLink>`. If you
want such an element in the tab order, put `tabindex="0"` on it in the
template.

Not much is lost here. That tabindex never made the element accessible
anyway. RouterLink only listens for clicks, so a focused `<div routerLink>`
did nothing when you pressed Enter. Anyone relying on it already had to
add their own keyboard handling to make the element work.

Fixes angular#28345
@arturovt
arturovt force-pushed the fix/router_28345_no-auto-tabindex branch from 33ac75e to cbdd707 Compare October 1, 2026 20:57
@arturovt

arturovt commented Oct 1, 2026

Copy link
Copy Markdown
Contributor Author

Can we also add a note to this that mentions simply adding the tabindex wasn't ever even enough to be correct for a11y anyways? It makes the link focusable but you can't hit enter and have it navigate because there's only a click listener. So to that extent, I don't know how breaking this really is in the end.

done

@angular-robot angular-robot Bot added the detected: breaking change PR contains a commit with a breaking change label Oct 1, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area: router breaking changes detected: breaking change PR contains a commit with a breaking change target: major This PR is targeted for the next major release

Projects

None yet

Development

Successfully merging this pull request may close these issues.

routerLink directive always makes element focusable

3 participants