CSS @navigation At-Rule
The @navigation at-rule conditionally applies CSS styles based on the current page URL or navigation between URLs. It can match starting and destination pages, navigation history, and navigation phases. The feature is part of the experimental CSS Navigation Module Level 1 and is not yet supported in major browsers.
@navigation Syntax
@navigation (navigation-condition) {
selector {
property: value;
}
}
The @navigation at-rule begins with a navigation condition followed by a block containing CSS rules.
The condition determines when the enclosed styles apply. A navigation condition can test the current URL, the starting or destination URL, the navigation history, or the navigation phase.
@navigation (at: url-pattern("/contact.html")) {
body {
background-color: #f5f5f5;
}
}
Under the proposed behavior, this rule applies the background color when the current page URL matches /contact.html.
The url-pattern() function describes a URL pattern. The draft also allows named locations defined using @location.
How @navigation Works
The @navigation at-rule is a conditional group rule. Similar to @media, it contains CSS rules that apply only when a specified condition matches.
However, @media tests characteristics such as viewport width or user preferences, while @navigation tests the current URL and navigation state.
@navigation (at: url-pattern("/products")) {
.page-title {
color: #0056b3;
}
}
This example describes a rule that applies to the page title when the current URL matches the specified products path.
The proposed feature can also distinguish navigation from one page to another, allowing styles to depend on the direction of navigation.
Experimental Feature: The @navigation at-rule is defined in an evolving editor's draft. Its syntax and behavior may change, and the examples on this page do not currently produce the intended results in ordinary browsers.
Navigation Conditions
The draft defines several conditions for matching page locations and navigation activity.
| Condition | Description |
|---|---|
at |
Matches the current page URL. |
from |
Matches the URL where a navigation begins. |
to |
Matches the destination URL of a navigation. |
between |
Matches navigation between two locations in either direction. |
history |
Matches a specified navigation history action. |
phase |
Matches a specified phase of navigation. |
Matching the Current Page
@navigation (at: url-pattern("/about.html")) {
.page-title {
color: #0056b3;
}
}
The at condition checks the current page URL.
Matching a Starting Page
@navigation (from: url-pattern("/products")) {
.page-content {
opacity: 0.8;
}
}
The from condition checks the starting URL of the navigation.
Matching a Destination Page
@navigation (to: url-pattern("/contact.html")) {
.page-content {
opacity: 1;
}
}
The to condition checks the destination URL.
The from and to conditions can be combined to match a specific direction of navigation.
URL Patterns and @location
The @navigation at-rule can use URL patterns directly or reference named patterns defined using @location.
Direct URL Pattern
@navigation (at: url-pattern("/products/:id")) {
.product-details {
display: block;
}
}
The :id segment represents a variable portion of the URL, allowing the condition to describe multiple product pages.
Named Locations
@location --home-page {
pattern: url-pattern("/");
}
@location --contact-page {
pattern: url-pattern("/contact.html");
}
@navigation (from: --home-page) and (to: --contact-page) {
.page-content {
opacity: 1;
}
}
The @location rules define reusable names for the home and contact page URL patterns.
The @navigation rule then matches navigation from the home page to the contact page. Reversing the direction does not match this condition.
Matching Either Direction
@navigation (between: --home-page and --contact-page) {
.page-content {
opacity: 1;
}
}
The between condition matches navigation between the two named locations in either direction.
Named locations are useful when multiple navigation rules need to reference the same URL patterns.
Navigation History
The proposed history condition allows styles to respond to different navigation history actions.
| Value | Description |
|---|---|
traverse |
Matches navigation through session history. |
back |
Matches backward navigation through history. |
forward |
Matches forward navigation through history. |
reload |
Matches a page reload. |
Matching Backward Navigation
@navigation (history: back) {
.page-content {
animation-duration: 0.2s;
}
}
This example describes styles intended for backward navigation through the browser's session history.
Matching a Reload
@navigation (history: reload) {
.page-content {
animation: none;
}
}
This example describes a rule that disables the specified animation when the navigation is a reload.
History conditions are part of the proposed navigation matching model and should not be confused with the :visited pseudo-class, which concerns previously visited links.
Navigation Phases
The proposed phase condition identifies the current stage of a navigation.
| Value | Description |
|---|---|
loading |
Matches the loading phase of navigation. |
ready |
Matches the ready phase of navigation. |
committed |
Matches the committed phase of navigation. |
@navigation (phase: loading) {
.loading-indicator {
opacity: 1;
}
}
@navigation (phase: ready) {
.loading-indicator {
opacity: 0;
}
}
These rules illustrate how a loading indicator could receive different styles depending on the navigation phase.
The exact processing model remains under development. Navigation phase conditions should not be relied upon for production loading indicators.
Logical Operators
Navigation conditions can be combined using logical operators, similar to conditional rules such as @supports.
| Operator | Description |
|---|---|
and |
Requires all combined conditions to match. |
or |
Requires at least one condition to match. |
not |
Negates a condition. |
Using and
@navigation (from: --home-page) and (to: --contact-page) {
.page-content {
opacity: 1;
}
}
Both conditions must match for the enclosed styles to apply.
Using or
@navigation (at: --home-page) or (at: --contact-page) {
.page-title {
color: #0056b3;
}
}
The rule matches when the current page belongs to either named location.
Using not
@navigation not (at: --home-page) {
.page-title {
margin-top: 20px;
}
}
The rule matches when the current URL does not match the home page location.
Parentheses can group conditions when more complex expressions are needed.
View Transitions
One proposed use of @navigation is to apply different view transition styles based on the direction of navigation between pages.
@location --listing-page {
pattern: url-pattern("/products");
}
@location --detail-page {
pattern: url-pattern("/products/:id");
}
@navigation (from: --listing-page) and (to: --detail-page) {
::view-transition-new(root) {
animation-duration: 0.4s;
}
}
@navigation (from: --detail-page) and (to: --listing-page) {
::view-transition-new(root) {
animation-duration: 0.2s;
}
}
The first rule describes a longer animation when moving from a product listing to a product detail page.
The second rule describes a shorter animation when returning from a product detail page to the listing.
The ::view-transition-new() pseudo-element is part of the CSS View Transitions system. The @navigation at-rule is intended to provide navigation-aware conditions for styling such transitions.
View transitions are a separate feature with their own browser support requirements. Supporting view transitions does not automatically mean a browser supports @navigation.
@navigation Example
The following example defines two named page locations and uses @navigation to describe different page title styles depending on the current URL.
HTML
<nav>
<a href="/">Home</a>
<a href="/contact.html">Contact</a>
</nav>
<h1 class="page-title">Website Page</h1>
CSS
@location --home-page {
pattern: url-pattern("/");
}
@location --contact-page {
pattern: url-pattern("/contact.html");
}
.page-title {
color: #333;
}
@navigation (at: --home-page) {
.page-title {
color: #0056b3;
}
}
@navigation (at: --contact-page) {
.page-title {
color: #198754;
}
}
Under the proposed behavior, the page title would appear blue on the home page and green on the contact page.
The default dark text color provides a fallback when the experimental rules are unsupported or when neither URL pattern matches.
Browser Support
The @navigation at-rule is experimental and is not a Baseline feature. It is not supported in major browsers. See the CSS Navigation Module Level 1 for specification updates and Can I Use? for future compatibility information.
Specifications
The @navigation at-rule is defined in the experimental CSS Navigation Module Level 1 editor's draft. The module proposes conditional CSS rules based on URL patterns and navigation state, along with related features such as @location and :link-to().
The specification remains under development, and its syntax and processing model may change before browser implementations become available.
