1. Route queries: the @route rule
The @route rule is a conditional group rule whose condition tests characteristics of the current URL or of the state of navigation between two URLs. These queries are called route queries.
Authors can use it to:
-
write style sheets that apply to multiple pages but behave somewhat differently between those pages,
-
write style sheets that apply to single page applications that change their URL over time, so that style changes when the URL changes, and
-
write style sheets that declaratively start view transitions (or make other appropriate style changes) in response to navigations.
The syntax of the condition in the @route rule is similar to that defined for <supports-condition> in [CSS-CONDITIONAL-3]. Negation, conjunction, and disjunction are all needed so that authors can specify the interaction of multiple styles in ways that are most intuitive and require the simplest code.
The syntax of the @route rule is:
@route <route-condition> { <rule-list> }
with <route-condition> defined as:
<route-condition> = not <route-in-parens> | <route-in-parens> [ and <route-in-parens> ]* | <route-in-parens> [ or <route-in-parens> ]* <route-in-parens> = ( <route-condition> ) | ( <route-test> ) | <general-enclosed> <route-test> = <route-location> | <route-keyword> : <route-location> <route-keyword> = at | from | to <route-location> = <route-name> | <urlpattern()> <route-name> = <custom-ident>
The above grammar is purposely very loose for forwards-compatibility reasons, since the <general-enclosed> production allows for substantial future extensibility. Any @route rule that does not parse according to the grammar above (that is, a rule that does not match this loose grammar which includes the <general-enclosed> production) is invalid. Style sheets must not use such a rule and processors must ignore such a rule (including all of its contents).
A <route-name> is a reference to a route
named in a
in the document.
This should be defined more formally once routemaps are.
Many of these grammar terms are associated with a boolean result, as follows:
- <route-condition>
-
- not <route-in-parens>
-
The result is the negation of the <route-in-parens> term.
- <route-in-parens> [ and <route-in-parens> ]*
-
The result is true if all of the <route-in-parens> child terms are true, and false otherwise.
- <route-in-parens> [ or <route-in-parens> ]*
-
The result is false if all of the <route-in-parens> child terms are false, and true otherwise.
- <route-in-parens>
-
The result is the result of the child subexpression.
- <route-test>
-
- <route-location>
- at: <route-location>
-
The result is true if the document’s URL matches the route location URL pattern of <route-location>.
- from: <route-location>
-
The result is true if the document’s navigation API of the document is non-null, and either:
-
its transition is non-null, its from entry’s
url
is non-null and matches the route location URL pattern of <route-location>. -
its activation is non-null, the document’s has been revealed is false or was false at the start of the current task, and the activation’s
from
’surl
’s is non-null and matches the route location URL pattern of <route-location>.
-
- to: <route-location>
-
The result is true if the document’s navigation API of the document is non-null, and either:
-
its ongoing navigate event is non-null, and its
destination
’surl
matches the route location URL pattern of <route-location>.This assumes that the ongoing navigate event and the transition have the same lifetime, but this isn’t really true if the event is intercepted. After whatwg/html#11690 / whatwg/html#11692. we could probably define this more like "from" above. But which lifetime is the one we want?
-
its activation is non-null, the document’s has been revealed is false or was false at the start of the current task, and the activation’s
entry
’surl
’s is non-null and matches the route location URL pattern of <route-location>.
-
The above definitions of from and to apparently don’t work right if you start a same-document navigation (e.g., with
pushState
) in the middle of a cross-document navigation.Improve integration with has been revealed rather than monkeypatching it.
- <route-location>
- <general-enclosed>
-
The result is false.
Authors must not use <general-enclosed> in their stylesheets. It exists only for future-compatibility, so that new syntax additions do not invalidate too much of a <route-condition> in older user agents.
The route location URL pattern of a <route-location> depends on the type of <route-location>:
- <route-name>
-
the URL pattern of a route named <route-name> declared in a
.< script type = routemap > Once routemaps are defined more formally, this should be defined in terms of the routemap definition instead of referring directly to URLPattern.
- <urlpattern()>
-
The URL pattern represented by the function; see create a URL pattern for urlpattern().
A document’s navigation API is the result of the following steps on document:
-
Let window be the
Window
whose associated Document is document, or null if there is no suchWindow
. -
If window is null, return null.
-
Return window’s navigation API.
The condition of the @route rule is the result of the <route-condition> in its prelude.
2. The urlpattern() function
The urlpattern() function represents a URL pattern, which can be used to match URLs.
<urlpattern()> = urlpattern( <string> )
This function represents a URL pattern that can be created using the steps of the create a URL pattern for urlpattern() algorithm:
-
Let arg be the <string> argument to the urlpattern() function.
-
Let baseURL be the style resource base URL of the rule or declaration block containing the urlpattern() function.
Do we really want this to be the base URL? For this particular use of urlpattern(), it’s likely more useful for the base URL to be the document URL rather than the style sheet URL. However, it would be very awkward for urlpattern() to be inconsistent with url(). Should we introducedocument-urlpattern()
? Should we do something similar to CSS Images 3 § 2.1.1 Ambiguous Reference-or-Image URLs (see w3c/csswg-drafts issue #383)? -
Return the result of create a URL pattern given arg, baseURL, and an empty map.
NOTE: This function requires that its argument is quoted. This differs from the url() function, which allows its argument to be quoted or unquoted.
3. The route() function for @when
This specification defines an additional function for the @when rule:
route() = route( <route-condition> )
The route() function is associated with the boolean result that its contained condition is associated with.
4. The route() function for if()
This specification defines an additional function for the if() function’s <if-test> production:
route() = route( <route-condition> )
This should probably have a more formal definition of the function, but I can’t find the formal definitions of the existing if() functions to model it after.