-
Notifications
You must be signed in to change notification settings - Fork 759
Description
When I presented the spec proposal in #12594 that we agreed to adopt as an editor's draft, there was one section of the spec that was blank. This section was intended to have pseudo-classes for links that are related to the current navigation.
This section of the spec now has a proposal in it.
I will fully admit that this proposal is a bit complicated -- but I think the thing we want to do here is a bit complicated, but also quite useful. @noamr, @bramus, and I bounced around a few different ideas to get to this one (and I think the current proposal is mostly theirs rather than mine). I think we've gotten to something that's good enough that I'm not embarassed to propose it (which isn't a particularly high bar, though in this case I think it took some discussion to reach it). But it could probably be better. However, we face competing constraints of:
- making the syntax not too complex to write
- making the syntax such that people who read it are likely to have a reasonable idea about what it does.
The interesting thing that we're trying to add here is that we're adding a selector that is conceptually matching between three different things rather than the normal two (something about the element and something in the selector). In this case we're proposing a selector that is able to match between three things: the target of the link (which is something about the element, as normal), data in the selector (also as normal), and the from or to URL of the currently active navigation (this is the new part).
The current proposal in the spec is a :link-to() pseudo-class that matches links based on the target of the link. The current draft allows this to be used as a normal two-way-match selector. But then it also offers a navigation-param() function that goes in that selector that turns it into this three-way-match concept and connects it to the URLs involved in the currently active navigation.
The reason we think this is useful is that it is intended to allow setting up view transitions between a list of items and a detailed view of one of those items (in either direction), which we've talked about as a list-to-details or details-to-list transition. Such transitions often animate aspects of the list item into aspects of the detailed view to help the user visually understand, through the movement in the animation, how the user interface has changed.
The larger example in the current spec might help make this a little bit clearer (though the spec also has some additional, more technical, detail):
A more interesting example of the ::link-to() pseudo-class is this example which creates a view transition between a item in a list that contains a link (in this document) and the details page for that link (in a different document). This transition works even when the navigation is a back/forward navigation and even if the user has used a language selector UI to change the page into a different language (and thus change the URL). The use of the :link-to() pseudo-class ensures that the view transition animations from or to the correct item in the list by matching the relevant parts of the navigation URL to the link URL.
@view-transition { /* allow cross-document view transitions */ navigation: auto; } @route --movie-details { /* match URLs like /en/movie/123 which is the English page about a movie with ID 123 */ pattern: url-pattern("/:lang/movie/:id"); } /* capture the overall area representing the movie, and a sub-area for its poster image */ /* match an element with class movie-container with a child link that links to a movie whose id is the same as the movie we are currently navigating to or from. (lang can be different, though.) Just :link-to(--movie-details) requires that the target of the link match the URL pattern defined by the "@route --movie-details" rule. The navigation-param(id) further requires that either the from or the to URL of the current navigation also match the URL pattern represented by the "@route --movie-details" rule, and that that the 'id' named group from that match be the same as the 'id' named group from the match with the link’s target. */ .movie-container:has(> .movie-title:link-to( --movie-details with navigation-param(id))) { view-transition-name: movie-container; > .movie-poster { view-transition-name: movie-poster; } /* leave the default cross-fade animation for both image captures */ }