Skip to content

[selectors] New pseudo-class that matches the current URL fragment #6942

@domenic

Description

@domenic

Original issue: WICG/navigation-api#162; /cc @jakearchibald @stephband.

Currently the :target pseudo-class is defined like so:

The :target pseudo-class matches the document’s target elements.

HTML then defines this based on a target element pointer, which is updated at specific points when the scroll to the fragment algorithm is run during navigation/history traversal.

This approach of updating a pointer at specific points in time is not equivalent to ":target always matches the first document-tree element with an ID corresponding to the document's URL's fragment component". This is true in several regards:

  1. You can update a document's URL's fragment via history.pushState(null, "", "#foo"). (Or by using cursed magics.) This does not trigger "scroll to the fragment" and so does not update the target element.

  2. Inserting a new element does not trigger "scroll to the fragment". So if the current URL fragment is #foo, but no element currently has ID foo, then adding such an element will not cause that element to match :target. Adding such an element can sometimes work, if you do so early in the document lifecycle before "scroll to a fragment" has completed. But usually it does not.

  3. There are various legacy-seeming string processing tricks going on that make the fragment/ID matching non-exact. E.g. special processing for #top (not sure if this impacts :target), and how the algorithm first tries exact match and then tries to do an extra round of percent-decoding (so, #%66oo will cause an element with ID foo to match, unless there is another element with ID %66oo somewhere in the DOM).

  4. Similarly, there is a presumably-legacy affordance for <a> elements with name="" attributes.

@stephband has expressed that he much prefers the "always matches the first document-tree element with an ID corresponding to the document's URL's fragment component" model, mentioning specifically (1)-(2). ((3) and (4) were just things I noticed reviewing the algorithms, which maybe are worth considering while we're here.) And this use case makes sense to me.

I strongly suspect changing :target's behavior is not web-compatible, and further I think there are probably people who want the currently-specified target behavior. E.g. if you use :target to highlight an element after the user scrolls to it via a fragment hyperlink, with some sort of fading-out flash, you might not want that fading-out flash effect for newly-inserted elements, even if they have an ID that happens to match the current URL fragment.

But introducing a new pseudo-class, with the always-match semantics, might be worthwhile. My strawperson names are :current-url-fragment or :location-hash.

It's not clear to me how much of a problem this is. So far only @stephband has expressed this to be an issue for their applications. Lots of developers "liked" my corresponding tweet but nobody else showed up to the original issue on WICG/app-history or replied with comments. But I wanted to log this feature suggestion here since it does make sense to me.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions