Skip to content

[css-pseudo-4] ::self-link pseudo, for self-linking #10498

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
tabatkins opened this issue Jun 25, 2024 · 6 comments
Open

[css-pseudo-4] ::self-link pseudo, for self-linking #10498

tabatkins opened this issue Jun 25, 2024 · 6 comments
Labels
css-pseudo-4 Current Work

Comments

@tabatkins
Copy link
Member

A very common UI pattern these days is to have headings (and sometimes other elements with an ID) provide a link to themselves, to make it easy to grab a link specifically to that element. Both Bikeshed and ReSpec specs do this for all headings (and for some other elements); GitHub does this for headings in Markdown files; tools like https://github.com/daviddarnes/heading-anchors exist to make it easy to get this effect in HTML; etc.

We should consider adding this as a pseudo-element for convenience to authors, so they don't have to either add some busywork markup, run a preprocessing step, or run JS over their page, just to get useful self-links.

Previously this wasn't really doable; at the moment, pseudo-elements aren't focusable in Chrome, for example. But we're fixing that for Carousel-related purposes, since that proposal also has navigation-related pseudo-elements that need to be part of the page's focus order. I'll assume that this is indeed fixed in UAs, so a pseudo can participate in the focus order and other AT features the same as an actual link element; we could put a requirement in the spec that UAs have this behavior before they implement this pseudo.

Proposed behavior:

  • New pseudo, named ::self-link (or ::anchor-link, or something else).
  • Similar to ::before/etc, only exists if content isn't none. Also requires the originating element to be linkable, per the host language's semantics. (In HTML, this means the element has an ID.)
  • If created, functions as a hyperlink to its originating element.
  • In the box tree, placed immediately after ::before, I think? Possibly we can go with an approach like Carousel and have a property that controls whether it shows up at the start (just after ::before) or at the end (just before ::after) of the originating element.
  • AT-wise, treated identically to an actual link, in the host language's semantics, placed at that location. The UA can automatically provide a more informative accessible name, tho. (Rather than the symbol that's usually used for its content.)

This is potentially better done as an HTML feature, fwiw, tho that would require adding an attribute or whatever to every element you want to apply this to. That's certainly far less work than adding the markup by hand is today, but it's not nothing, and generally you'll want to apply this to all headings/etc in your document, with identical behavior across all of them, so having an HTML attribute isn't great usability-wise.

@tabatkins tabatkins added the css-pseudo-4 Current Work label Jun 25, 2024
@flackr
Copy link
Contributor

flackr commented Aug 9, 2024

Interestingly, this is effectively a::scroll-marker #10720 that isn't reflowed. I've listed an alternative in https://github.com/flackr/carousel/tree/main/scroll-marker#using-regions-or-grid-flow-instead-of-scroll-marker-group which if you replace ::scroll-marker with ::self-link you basically get scroll markers from self links flowing into a marker area. There may be situations though where you might want both a self link and a scroll marker.

@tabatkins
Copy link
Member Author

Very similar, tho the requirement that the target be linkable (and the pseudo itself being a link and triggering hash-navigation semantics, rather than just scrolling a target into view) does separate them a bit. (You need to be able to right-click and copy link, or click and copy the link from the address bar, for example.) I don't know if the concepts are actually close enough to be worth coalescing.

@astearns astearns moved this to TPAC/FTF agenda items in CSSWG Agenda TPAC 2024 Sep 13, 2024
@astearns astearns moved this from TPAC/FTF agenda items to Regular agenda items in CSSWG Agenda TPAC 2024 Sep 13, 2024
@css-meeting-bot
Copy link
Member

The CSS Working Group just discussed [css-pseudo-4] ::self-link pseudo, for self-linking.

The full IRC log of that discussion <emilio> flackr: as TabAtkins wrote, it's a very common pattern (bikeshed etc mentioned)
<emilio> ... this adds a link to the heading that you can link to
<emilio> ... developers write tools to add these
<emilio> ... the proposal is to add a pseudo to generate this before the element
<emilio> ... long list of proposed behavior
<emilio> ... main one is it requires the content is linkable which means it has to have an ID attr
<Rossen9> ack fantasai
<emilio> fantasai: main issue, sometimes they want it at the start or at the end
<emilio> ... the other is sometimes you want a link to the container, not the heading itself
<emilio> ... e.g. <section id=foo><h1>...
<emilio> ... you could add the id to both but the desired thing is to target the section
<emilio> ... so I like the idea
<emilio> ... I don't think it's a problem to do it with CSS
<emilio> ... but needs a way of solving these two
<emilio> flackr: the second seems more tractable
<emilio> ... we could allow it to refer to the nearest ancestor with id
<emilio> fantasai: that won't get you reasonable behavior for the fifth heading in the section or something
<emilio> ... you'd be jumping too high
<emilio> ... maybe fine
<emilio> ... but if you have somewhat unpredictable markup...
<emilio> ... [missed]
<emilio> ... it's a bit tricky
<emilio> flackr: not sure I understand the use case
<emilio> ... isn't the <section> what you link the one you want?
<emilio> fantasai: the nearest element with an id might be <main> or what not
<emilio> flackr: ah because they forgot or something
<emilio> 1+
<emilio> q+
<emilio> flackr: I supposed if there was a functional pseudo you could use `attr(id)` to refer to yourself or something
<emilio> fantasai: that might be more practical
<Rossen9> ack emilio
<emilio> ... I think those are my two concerns
<fantasai> scribe+
<fantasai> emilio: Is it well-defined to have generated interactive content?
<dandclark> emilio: My question is is it well defined to have generated interactive content?
<dandclark> ...What's the click event target?
<dandclark> ...Might be fine but might need some work on DOM side as well
<emilio> flackr: there is common behavior when you click on pseudos that you dispatch on the outer element, not great but...
<emilio> ... it is at least targettable
<emilio> ... we could explain this in the future
<dandclark> emilio: But I think the targets @@@ is mostly an effect of the generated content. Not quite pointer events but sort of. Must be targetable. Thinking about user-select.
<emilio> flackr: not sure I have the answer about how to support before / after
<emilio> q+
<Rossen9> ack emilio
<dandclark> emilio: What if instead of making new pseudo you make it content function or something? That way you can use ::before and ::after, can target anything
<emilio> ... that way you could use content: self-link(self) or self-link(closest) or something
<emilio> ... and would solve the before / after issue
<emilio> flackr: yeah
<emilio> Rossen9: let's take it back to the issue

@mirisuzanne
Copy link
Contributor

What happens if you apply this pseudo on a link tag? Or is it limited to headings specifically? I've seen people do links for individual paragraphs, though it's not as common. See for example articles on https://publicdomainreview.org/

@astearns astearns removed the Agenda+ label Sep 28, 2024
@tabatkins
Copy link
Member Author

What happens if you apply this pseudo on a link tag?

Same thing that happens if you insert an <a> inside of an <a>. (You can't do this with the parser, but you can with script.)

Or is it limited to headings specifically?

No, any element that's linkable (or, based on the conversation during the meeting, any element at all, as long as some ancestor is linkable).

@tabatkins
Copy link
Member Author

Okay, so distilling the TPAC comments (thanks for running the topic, @flackr!):

  • make it capable of linking to ancestors; probably just "the first element in its originating elements inclusive ancestors that's linkable".
  • make sure that focusable/activatable pseudo-elements are well-defined (this is also needed for the Carousel stuff, so I presume I can piggyback on that proposal)
  • rather than a dedicated pseudo (and having to deal with the "does it go before or after" issue), just extend the power of ::before/::after to handle this, either with a new 'content' value, or a new property that only works on those pseudos

I like these ideas! So, here's a new proposal to discuss:

Add a new link property, only usable on ::before/::after. Its grammar is none | self | <url> | <string>, and it makes the pseudo-element a link, as described earlier in this thread. The self keyword causes it to link to the first element in its originating element's inclusive ancestors that is linkable (aka, has an ID); the <url> | <string> value just makes it a link to that URL. (Mostly useful to, say, grab something from a data-* attribute with attr().)

This rough idea has been proposed in the past, fwiw, but I can't find the old emails about it because Gmail search is a lot less useful now.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
css-pseudo-4 Current Work
Projects
Status: Friday afternoon
Development

No branches or pull requests

5 participants