v156 · css · navigation
CSS pseudo-class for navigation source element
:navigation-source selects the element that started the current navigation — the clicked link, the submitted form, or the submit button — and keeps matching it for the whole course of that navigation. It is the CSS reflection of the Navigation API's source element, and it deletes the "add a class to whatever was clicked" script from every loading indicator and every view-transition naming dance.
concepts
-
Loading links
A navigation rail where the link you clicked shows its own in-flight state, styled by
a:navigation-sourceduring an intercepted same-document navigation — with the JS-classname pattern it replaces running beside it, labelled, on browsers that lack the selector. -
Form submit feedback
The practical one: a form with two submit buttons where
form:navigation-sourceandbutton:navigation-sourcestyle the submitting form and the exact button that fired, for the duration of the (deliberately slow) submission. -
Thumbnail view transition
The motivating use case from the explainer:
a:navigation-source .thumb { view-transition-name: hero }names the clicked thumbnail for a real view transition — one declaration instead of the set-name-then-clean-up JavaScript that SPAs do today. Both mechanisms run here, each labelled. -
Selector parse lab
The inspection bench: parse probes for the exact selector, an
@supports selector()rendering check, the idle no-match invariant, which elements are eligible sources, and a live sampler that measures how long the source element stays matched across a navigation.
why it shipped
View transitions made one question urgent: when a navigation starts, which element is it about? Expanding a thumbnail into a hero image needs the clicked thumbnail to carry a view-transition-name — but only that one, and only for this navigation. Until now the answer was JavaScript bookkeeping: listen for the click, set the name, start the transition, clean the name up afterwards so the next navigation doesn't break.
:navigation-source moves that bookkeeping into the selector. It matches any element that is the current navigation's source element — an <a>, <area>, <form>, submit <input> or <button> — while the navigation state is non-null, for same-document navigations (via the Navigation API's notion of an ongoing navigation) and cross-document ones (from initiation to the new page's first frame). Loading spinners on the clicked link, double-submit styling on the fired button, and view-transition naming all become plain CSS.
research record — use cases & exact surface
- Exact selector (CSS Navigation 1 §2.2):
:navigation-source— matches element el where the current navigation state is not null and el is its source element. Eligible sources per the spec:a,area,form,input type=submit,button. - Lifetime: the active navigation state spans a same-document navigation's ongoing period (Navigation API "committed" definition) and, cross-document, from initiation to the first frame of the new page (route-matching explainer, "Active navigation state").
- Runtime flag:
NavigationSourcePseudoClassinruntime_enabled_features.json5(statusstablefor 156;implied_by: RouteMatching). Enable early with--enable-blink-features=NavigationSourcePseudoClassor--enable-experimental-web-platform-features. - Use-case portfolio: canonical link feedback (loading-links), practical form/submitter feedback (form-submit-feedback), novel view-transition composition (thumbnail-view-transition), inspection + idle/negative edge behaviour (selector-parse-lab). Migration is embedded in each: the JS pattern the selector replaces runs as the labelled fallback lane.