Chrome 156:navigation-source Tutorial: Build View Transitions Without Click Handlers
Learn how Chrome 156βs:navigation-source pseudo-class identifies the element that starts a navigation and use it to build View Transitions with less JavaScript.
On this page
A thumbnail can now tell CSS that it was the element that started a navigation. Chrome 156 adds the :navigation-source pseudo-class, which selects the link, button, or form element that triggered the current navigation, giving developers a way to connect navigation state to styling without recording the clicked element in JavaScript. Chrome 156 is currently in beta, with a scheduled stable release of October 20, 2026.
This tutorial shows how to use :navigation-source in a small product-list-to-detail example, why it is useful with the View Transitions API, how to add a fallback, and where the feature should not yet be treated as a universal replacement for JavaScript.
What Chrome 156 changes about navigation styling
Before this feature, CSS could style a link because of its normal state, but it could not directly ask which element had initiated the current navigation. JavaScript therefore had to observe a click, remember the selected element, and coordinate that information with the transition or navigation code. Chrome 156 exposes the same navigation source relationship to CSS through :navigation-source. The CSS Navigation specification defines it as a pseudo-class that matches the element that triggered the current navigation, including links, areas, forms, submit inputs, and buttons.
The important distinction is that this is not simply a replacement for :active. The browser keeps the navigation source associated with the current navigation state, so CSS can use that relationship while the navigation is being processed. Chromium's implementation was explicitly shipped as :navigation-source, and Chrome's platform status lists it among the Chrome 156 features.
Start with a normal link before adding transitions
Build the basic navigation first. The example below uses ordinary HTML links because the feature works with the actual navigation source rather than requiring a JavaScript click handler.
Coffee MakerThe important part is the link itself. When that link starts a document navigation, Chrome can match it with :navigation-source. Your application does not need to attach a click listener merely to remember which link was selected.
That separation matters in applications where navigation is already handled by a framework or by standard browser behavior. The navigation remains the navigation mechanism, while CSS receives information about its source. You can therefore keep the markup and navigation logic straightforward instead of creating a second JavaScript state variable just for visual effects.
Use:navigation-source to identify the element that started navigation
The simplest selector is the pseudo-class itself:
a:navigation-source { outline: 3px solid currentColor; }Only the link that initiated the current navigation matches the selector. The same mechanism can target a submit button or a form:
form:navigation-source.submit { outline: 3px solid currentColor; }
button:navigation-source {
outline: 3px solid currentColor;
}The specification specifically defines the pseudo-class around the navigation state's source element, rather than around a generic pointer or keyboard event. That means the feature describes why the navigation happened, not merely which element happens to be receiving focus. CSS Drafts
Connect the navigation source to a View Transition
The most interesting use is shared-element navigation. Suppose a product grid contains several thumbnails and each thumbnail opens a product page. You may want the image that the user selected to participate in the page transition. Existing implementations often use JavaScript to identify the clicked card and assign a transition name before navigation. Chrome's new selector lets the source element participate in that decision from CSS.
For example, if the image belongs inside the link, you can write:
a:navigation-source.product-image { view-transition-name: product-image; }The browser applies the selector to the link that initiated navigation, so the descendant image can receive the transition name only for that navigation. On the destination page, the corresponding product image can use the same transition name:
.product-detail-image { view-transition-name: product-image; }This builds on the same family of browser-native navigation effects discussed in View Transitions, but the new piece is the ability to identify the navigation source without adding a click-tracking layer to the application.
Keep the HTML structure simple enough for the selector
Because :navigation-source matches the element that triggered navigation, the structure of the markup matters. If the clickable element is the link, put the visual element you want to associate with that navigation inside the link. A product card can therefore look like this:
Coffee MakerNow the relationship is direct: the starts the navigation and the image is its descendant. The selector can express that relationship without a separate JavaScript variable containing the identity of the selected card.
This also makes the technique easier to reason about when there are many cards. You do not need separate selectors for card one, card two, and card three. Every matching link can use the same rule, while the browser determines which one is the current navigation source.
Add feature detection before using it in production
Chrome 156 is still in beta as of October 4, 2026, and the scheduled stable release is October 20. The feature therefore should be treated as progressive enhancement rather than as a requirement for basic navigation.
CSS can test whether the selector is understood before applying the enhanced behavior:
@supports selector(:navigation-source) { a:navigation-source.product-image { view-transition-name: product-image; } }The fallback should remain the ordinary page navigation. If the browser does not understand the selector, the user should still be able to open the product page; they simply will not receive the enhanced source-aware transition.
Important: do not make application functionality depend on :navigation-source. Use it for progressive visual behavior while keeping links, forms, and buttons functional without the feature.
Why this can remove unnecessary JavaScript
The old pattern has several moving parts. A click handler has to identify the selected element, assign or store transition state, initiate or allow navigation, and sometimes clean up that state afterward. That code can become awkward when navigation is handled by a framework, when links are generated dynamically, or when the same component is reused across several routes.
The CSS approach moves only the visual relationship into CSS. The browser already knows which element triggered navigation, so the application does not have to duplicate that information merely to style a transition. This is particularly useful for interfaces built from repeated links, where the developer wants identical behavior for every card but only one card should become the source for a particular navigation.
There is still a boundary. CSS is not replacing navigation logic, application state, data loading, authentication, or error handling. It is exposing navigation context to the styling layer. JavaScript remains appropriate when the application needs to make a decision that CSS cannot express.
Use buttons and forms when they are the real navigation source
The feature is not limited to thumbnail links. The CSS Navigation specification includes form and submit controls among the elements that can become the navigation source.
For a form that navigates to a confirmation page, the submit control can therefore be styled during the navigation:
button:navigation-source { view-transition-name: checkout-submit; }The useful part is semantic: the CSS selector follows the element that actually initiated the navigation. You do not have to infer the source from focus, hover, or a separately maintained application variable.
Understand the browser-support limitation before shipping
The feature is tied to the CSS Navigation work, which is still an evolving web-platform area rather than an old, universally implemented CSS primitive. Chromium's shipping record states that :navigation-source was intended for desktop, Android, and Android WebView in milestone 156.
There is also evidence of active standards discussion outside Chromium. WebKit lists a standards-position entry for the CSS :navigation-source pseudo-class, while Mozilla has a standards-position issue for the same feature. That means developers should check current browser compatibility rather than assuming that a Chrome 156 implementation automatically represents all major browsers.
For that reason, the safest implementation is deliberately small: keep the navigation usable everywhere, put the enhanced transition inside feature detection, and avoid introducing JavaScript solely to reproduce a visual effect in browsers that do not support the selector.
Check the result with a real navigation
Testing this feature requires an actual navigation rather than simply clicking an element and inspecting its hover or active state. Open the page in a browser version that supports the Chrome 156 feature, load the product list, and activate one of the links. The link that initiated the navigation should match :navigation-source during the relevant navigation state.
Then test a second product. The important check is that the second link becomes the source without any JavaScript changing classes or transition names. Finally, open the destination directly rather than arriving through a product link. The destination should still render normally, because the enhanced source-specific behavior should never be required for the page to function.
If the transition fails, first remove the transition-specific CSS and verify that the navigation itself works. Then check the selector support, the location of the transition name, and whether the source element is actually the element performing the navigation. Keeping those concerns separate makes browser-specific debugging much easier.
What to build with:navigation-source now
The feature is most useful when the visual effect depends on which navigation the user started rather than simply on the destination. Product thumbnails, article cards, gallery links, checkout controls, and other repeated navigation elements are natural candidates. The strongest implementations can keep the normal HTML navigation intact and use :navigation-source only to add a richer transition when the browser supports it.
Chrome 156 makes that relationship available directly in CSS, but the feature is still new enough that progressive enhancement is the sensible architecture. Build the page so the link or form works first, add the source-aware selector second, and keep a JavaScript fallback only when the interaction genuinely needs application logic rather than just styling.
Written by


