Skip to content
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

[css-values] Clarify fragment URLs resolve against the current tree, not document tree #3320

Open
rniwa opened this issue Nov 14, 2018 · 17 comments
Labels
css-values-4 Current Work topic: urls Tracking issues that'll need edits when CSS URLs are defined on top of Fetch.

Comments

@rniwa
Copy link

Right now, section 4.4.1.1. fragment URLs say that:

If a url()’s value starts with a U+0023 NUMBER SIGN (#) character, parse it as per normal for URLs, but additionally set the local url flag of the url().

When matching a url() with the local url flag set, ignore everything but the URL’s fragment, and resolve that fragment against the current document that relative URLs are resolved against. This reference must always be treated as same-document (rather than cross-document).

We text should be updated to refer to the current tree so that when the local url flag is set, the fragment is resolved against the current tree.

@rniwa
Copy link
Author

Also see #2715

@rniwa
Copy link
Author

Also see #1995

@fantasai fantasai added the css-values-4 Current Work label Nov 15, 2018
@tabatkins tabatkins added the topic: urls Tracking issues that'll need edits when CSS URLs are defined on top of Fetch. label Oct 21, 2021
tabatkins added a commit that referenced this issue Oct 10, 2022
…ree, not the document (so they're shadow-scoped), per WebAppsWG discussion. #3320
@tabatkins
Copy link
Member

All right seems like the webapps people were pretty united on this a few years ago, so I've gone ahead and made this change.

@fantasai
Copy link
Collaborator

fantasai commented Oct 12, 2022

Re-opening for CSSWG resolution.
Note testcase which shows that Firefox and Blink are currently honoring <base href=...> when resolving fragment URLs, but WebKit does not.

@css-meeting-bot
Copy link
Member

The CSS Working Group just discussed [css-values] Clarify fragment URLs resolve against the current tree, not document tree.

The full IRC log of that discussion <astearns> topic: [css-values] Clarify fragment URLs resolve against the current tree, not document tree
<astearns> github: https://github.com//issues/3320
<dandclark> fantasai: Short version of problem is there was resolution to change how fragment urls are handled when fragment url is changed.
<dandclark> fantasai: e.g. using rel tag. but most implementations don't follow that, so not sure if we want to keep. Need implementers to review.
<fantasai> s/rel tag/<base href>/
<dandclark> fantasai: Different engines doing different things.
<dandclark> emilio: I think what FF and Blink do is consistent with other things. Like other specs, ??? and stuff that should behave consistently for base URI case.
<astearns> s/???/SVG/
<dandclark> emilio: Whatever we do should also check...is the WebKit behavior constent here?
<fantasai> https://www.w3.org/TR/css-values-4/#local-urls
<tantek> +1 emilio, what FF + Blink do seems both consistent and interoperable, can we resolve on that being what we want?
<dandclark> fantasai: Pasted link to what spec currently says.
<fantasai> fantasai: I'm not convinced this is what we want to do, and it's certainly not what's implemented.
<tantek> q?
<florian> q-
<dandclark> emilio: Resolving against ??? is a bit undefined I think. Also I'm pretty sure we don't use StyleSheet owner node.
<tantek> q+
<astearns> s/???/node tree/
<dandclark> emilio: I suspect blink does the same, so it's tricky
<dandclark> emilio: I guess that's the intention for ShadowDOM.
<astearns> ack tantek
<dandclark> tantek: I would flip question around. Are there objections/problems from web dev perspective to how it's implemented? If there are no problems, makes sense to resolve and move forward. Spec is behind, fix the spec accordingly.
<dandclark> fantasai: This is a change from L3 that was requested. Not convinced this is what we need to do.
<dandclark> tantek: I mean behind reality. THis has happened before.
<fantasai> I would say it differs from reality, it's not *behind* reality.
<dandclark> astearns: So the q is should resolve fragment against node tree or current tree?
<dandclark> emelio: The tree we're resolving against, is it correct? And are base URIs taken into account? I think they should be, agree w/ fantasai that it's weird they're not.
<dandclark> emilio: There's also trickiness in shadowDOM behavior.
<dandclark> emilio: Not sure we match with spec here.
<dandclark> s/emelio/emilio
<dandclark> astearns: I assume motivating bit is what we do with shadowDOM, given linked issues.
<dandclark> asteans: Don't know enough about this to have good idea of what direction to take.
<dandclark> fantasai: Might make sense to kick to f2f
<dandclark> tantek: To decide, is the methodology. Define from 1st principles or based on interoperable implementation behaviors. I'm OK with either approach but that's high level question to settle first.
<dandclark> astearns: Closing to take back up in a couple weeks. I will ping ??? to try to get more details.
<dbaron> s/???/ryosuke/

@annevk
Copy link
Member

I'm not sure I understand the minutes. @emilio or @astearns would you mind elaborating?

The idea here is that you want to have a same-node-tree reference, essentially id(foo), but all we have is url() so the plan was that url(#foo) would have special semantics (i.e., whenever the url() argument starts with #) and end up being a local reference. This would allow various SVG and CSS features to work better inside shadow trees.

Because to be clear, if they are not treated as local references, you can only target nodes in the main document tree, not the shadow tree.

@tabatkins
Copy link
Member

Yeah, I'm not sure I understand what was being argued here either (I unfortunately had to miss this meeting).

@emilio
Copy link
Collaborator

@annevk @tabatkins my point was that there are two orthogonal issues:

  • Whether <base> is respected or we should just ignore and treat as local refs.
  • Which tree we find stuff in. And it's unclear browsers are consistent, I'm pretty sure we don't use the stylesheet's tree.

I guess you would be opposed to honor <base> and lookup inside shadow trees if the document uri matches?

@tabatkins
Copy link
Member

Your first question was resolved back in the day, when we discussed this original behavior and I added the "local url" flag. Browser support was uncertain at the time but it was considered desirable to make the fragment URLs local-only.

The only new question was whether they were truly fragments resolved against the current page (thus only capable of resolving to IDs visible in the topmost light DOM) or if they were tree-specific (so you could target IDs in your shadow). The Webapps folks seemed reasonably consistent in wanting the latter, and that made sense to me, so I updated the spec here.

Apologies for not being around to introduce the topic properly, this was meant to just be a review of the most recent change for box-ticking purposes, not a relitigation of the earlier discussions.

@annevk
Copy link
Member

I guess you would be opposed to honor <base> and lookup inside shadow trees if the document uri matches?

Yeah that breaks encapsulation.

@atanassov atanassov moved this from Agenda+ to Agenda+ F2F in November 30 2022 Nov 29, 2022
@css-meeting-bot
Copy link
Member

The CSS Working Group just discussed [css-values] Clarify fragment URLs resolve against the current tree, not document tree, and agreed to the following:

  • RESOLVED: ID-Fragment-only URLs use tree-scoped reference mechanics
  • RESOLVED: bring back text for WG review
The full IRC log of that discussion <emeyer> TabAtkins: Brought up a few weeks ago and wasn’t inroduced properly
<emeyer> …Several years ago, we discussed behavior of fragment-only URLs and how they react to the <base> element or Navigation API, chaning page URL, etc.
<emeyer> …They’re necessary for SVG references, and if they can be shifted, that can break things
<emeyer> …Fragment URLs are supposed to be special, if y ou write a fragment-only URL in they’re always resolved against the current document, regardless of URL situation
<emeyer> …Browsers were in several places at the time, but we decided this was a good place to go
<emeyer> …The question arose how this works in Shadow trees. Are fragment-only URLs resovled against the current document, or are they resolved against the tree they appear in?
<emeyer> …Web Components group thought it was most reasonable to resolve inside the current tree, I agreed
<Rossen_> q?
<emeyer> …Question is: is this okay that fragment URLs resolve against the current tree? Is the spec text okay or do I need to fix it up?
<emeyer> emilio: The current tree means the tree of the stylesheet that specified the URL, right?
<emeyer> TabAtkins: Yes.
<emeyer> emilio: That may be tricky with SVG <use> elements, which sucks
<emeyer> …Seems the most sensible, but it isn’t the current behavior of anyone
<heycam> q+
<emeyer> TabAtkins: No other behavior allows SVGs with references to work inside of a shadow tree at all
<PaulG> would this apply to text-selection fragments as well?
<emeyer> emilio: The tree of the stytlesheet makes more sense
<Rossen_> ack heycam
<TabAtkins> Essentially, treating fragment-only URLs as being tree-scoped
<PaulG> q+
<JakeA> q+
<emeyer> heycam: I can understand using this proposal
<Rossen_> ack PaulG
<emeyer> PaulG: Does this apply to text-fragment URLs, and is a web component has CSS and it uses fragment URLs, can that leak to other shadow DOMs and the parent document?
<heycam> q+
<emeyer> TabAtkins: For the first, the spec assumes only IDs exist, and I’ll clarify that this only applies to fragment URLs and doesn’t apply to other things like text-fragment
<fantasai> There's also #xywh= fragments etc. to worry about ...
<emeyer> PaulG: It sounds like will process such that CSS in a component could detect IDs in other trees
<emeyer> TabAtkins: Nope, the opposite
<TabAtkins> TabAtkins: If the stylesheet is in the shadow, it'll only see IDs in the shadow; if it's in the light, it'll only see IDs in the light.
<emeyer> JakeA: This wouldn’t change the scope of ARIA things like aria-describedby, yes?
<emeyer> TabAtkins: This is just about the CSS url() function
<emeyer> …This is why we need raw element references so we can reference across trees
<Rossen_> ack JakeA
<Rossen_> ack heycam
<emeyer> heycam: 1. It might be weird with the stylesheet relative thing when you look at computed style, now you have a state behind the computed value not represented by that style
<emeyer> …2. Have we considered an alternative approach where we change the way IDs get resolved by looking up the tree?
<emeyer> TabAtkins: 1. Yes, this does introduce state not expressed in the text. This is how we handle tree-scope references already and explicitly resolved to do it that way.
<emeyer> …If you set font family, it remembers the tree it was set in. If you read computed style in a shadow, you read it and set it back to the inline style, it will change that reference
<emeyer> …2. Automaticlly searching up trees is how tree scope works today
<Rossen_> q
<emeyer> …assuming i use the same behavior, you look up the tree and if you don’t find anything, you can maybe find things in the light
<emeyer> heycam: Ah, that’s different from how I was understanding things.
<fantasai> I think the spec doesn't currently express this nuance
<emeyer> TabAtkins: There’s still state. If you use a ::part, it will search in the light DOM, not the shadow
<emeyer> …If you explicitly inherit, that will capture the original tree it was set on. If it inherits into a shadow tree, it will still search the light tree.
<Rossen_> ack fantasai
<Zakim> fantasai, you wanted to ask about base URLs again; and also non-ID fragment references
<emeyer> fantasai: We’re binding the fragment to a tree, and inherting that binding. Need to make that clear in the spec.
<emeyer> …Also that it doesn’t just look in its own tree, it looks up trees.
<fantasai> ACTION: TabAtkins to clarify above
<emeyer> TabAtkins: I need to use tree-scoped references explicitly.
<emeyer> fantasai: In this text to handle ID fragments, you hadn’t considered other fragments. Wht do we anticipate what happens there?
<emeyer> TabAtkins: I don’t know, haven’t thought about it in detail. For ID references, we get this behavior, the rest are undefined.
<emeyer> fantasai: We have to define those
<fantasai> <!DOCTYPE html>
<fantasai> <base href="http://example.com/">
<fantasai> ...
<fantasai> <a href="#anchor" style="background-image: url(#image)">link</a>
<emeyer> …Other question: with base URLs, there’s an example (see above) which is resolved against one document and an image resolving against a different document
<emeyer> …Firefox and WebKit don’t handle this
<emeyer> …Do we actually want to change this behavior to something I think authors will find more confusing?
<emeyer> TabAtkins: This is based in an older decision and didn’t want to re-litigate it
<emeyer> fantasai: Do we want to keep going in this direction?
<emeyer> TabAtkins: We have to, or else SVGs in shadow DOMs will break and can’t be fixed
<Rossen_> q?
<emeyer> fantasai: Can’t you put a base in a component and have it resolve against that?
<emeyer> TabAtkins: Probably not. <base> is terrible old HTML we should discourage
<emeyer> fantasai: I do want confirmation from browsers that they still want this to be where we go
<fantasai> tescase: capable of resolving to IDs visible in the topmost light DOM) or if the
<emeyer> emilio: It seems okay from my point of view
<emeyer> heycam: I think it’s fine as well
<fantasai> testcase: https://www.software.hixie.ch/utilities/js/live-dom-viewer/?%3C!DOCTYPE%20html%3E%0A%3Cbase%20href%3D%22https%3A%2F%2Fxanthir.com%2Fpony%22%3E%0A%3Ca%20href%3D%22%23linky%22%20style%3D%22background%3A%20url(%23foo)%3B%20font-size%3A%202em%22%3Etest%3C%2Fa%3E%0A
<Rossen_> q?
<fantasai> s/tescase: capable of resolving to IDs visible in the topmost light DOM) or if the//
<TabAtkins> proposed resolution: ID-Fragment-only URLs use tree-scoped reference mechanics
<emeyer> RESOLVED: ID-Fragment-only URLs use tree-scoped reference mechanics
<fantasai> RESOLVED: bring back text for WG review

@tabatkins
Copy link
Member

Okay, new text committed as a result of the WG discussion - fragment-only URLs are now explicitly treated as tree-scoped references, with the set of IDs in the tree as the associated tree-scoped names.

This implies that x-foo::part(foo) { mask: url(#foo); } will resolve to the element with id=foo in the light DOM, regardless of what IDs are used inside the shadow, while <div part=foo style="mask: url(#foo)"> inside the shadow will resolve to the element with id=foo in the shadow. (But if there is no such element, it'll walk up to the light and look for the ID there.)

For the question of what to do with Media Fragments and similar non-ID fragment syntaxes, I'm currently just treating them identically to anything else - I try to find an element with a matching ID and if it fails (as it almost certainly will) it fails as normal, and is treated the same as if #foo wasn't in the document.

This probably needs some more work to make this good. In particular, this doesn't work properly with fragment directives - url(#foo:~:text=foo) will search for an element with id="foo:~:text=foo", rather than stripping the directive. I've opened an issue (WICG/scroll-to-text-fragment#198) to get an algo exposed for doing that easily.

Anything else the WG thinks is still wrong, or needs to be added?

@fantasai
Copy link
Collaborator

If the intention of this special behavior is to apply this to ID fragments, then scope it to ID fragments. There are other types of fragment identifiers, scroll-to-text-fragment is only one, see e.g. https://www.w3.org/TR/media-frags/ for some others. In general URL fragments are an extension point. Even if we special-case some things, we need to define their generic behavior in a way that's going to work generically.

@fantasai fantasai added this to Complex Discussions in Agenda Scratchpad Dec 5, 2022
@tabatkins
Copy link
Member

If the intention of this special behavior is to apply this to ID fragments, then scope it to ID fragments.

I would if I could. The problem is that as far as I can tell, there isn't a well-defined notion of "ID fragments".

@css-meeting-bot
Copy link
Member

The CSS Working Group just discussed [css-values] Clarify fragment URLs resolve against the current tree, not document tree.

The full IRC log of that discussion <dael> TabAtkins: Last month I committed the initial spec text. fragement urls are now tree scoped references. Look up in tree style is in to find url. Lets you refer to global if nothing intervening
<dael> TabAtkins: A bit of changes to make. I don't strip fragment directives b/c waiting on that spec to extract that algorithm. They do that now so I'll make the change; that's minor
<dael> TabAtkins: Only other issue is fantasai comment on there that I'm not handling other types of fragments like media fragments in an intelligent way. Right now see if there's an element with the frag as the idea great. If not fail. Means media fragments almost always fail. Would like to specifically exclude them
<dael> TabAtkins: Don't think there's a conceptual definition of media fragments so right now I'm not. If someone knows a way to refer to these that is testable, great. For now no practical effects so I think spec is workable but not idea.
<dael> TabAtkins: If that's okay, we can accept and then tweak
<astearns> ack fantasai
<dael> fantasai: Disagree it's good now. Things like media fragments should just work. URL fragments are not about pointing at an element. They're sometimes pointing at an image. Often that.
<dael> fantasai: Media fragment is reasonable way to clip out section of image. I think spec text should work for these things
<dael> TabAtkins: If you can find a well defined way to talk about it, great
<dael> fantasai: Vaguely defined and correc tis better than precise and wrong. And you can file issue against url spec
<dael> TabAtkins: File and issue against me and I'll figure out some way to talk about that
<dael> astearns: Split into a separate issue or have that accurate but not precise issue before we close
<dael> fantasai: These changes are a regression so would like to address. It did not spec how you do it, but it wasn't wrong
<dael> TabAtkins: Didn't say anything about that in previous
<dael> fantasai: Which is better than saying something wrong
<dael> TabAtkins: Don't think that is a follow-up, but alright.
<dael> TabAtkins: Happy to figure out how to address. Would like it sep. so SVG working is in there
<dael> fantasai: If there's spec text that excludes ID is fine
<dael> TabAtkins: Can we do that as sep so we close this issue that's been open for years
<dael> fantasai: You don't have text that addresses this which is my problem
<dael> TabAtkins: Which we will fix in another issue.
<fantasai> Your text for this issue breaks other things.
<fantasai> Write text that doesn't break the other things, and then you can close this issue.
<dael> astearns: I don't think we are going to come to an agreement between the two of you on how we should track the remaining problems. I suggest we leave issue as is until we get something in the spec to address fantasai issue
<dael> astearns: And then we can close the issue. Acceptable TabAtkins?
<dael> TabAtkins: I can't do otherwise, so sure?
<dael> astearns: One remaining thing on this and we'll come back once there's a little more in the spec and then create a new issue for a better definition

jakearchibald pushed a commit to jakearchibald/csswg-drafts that referenced this issue Jan 16, 2023
tabatkins added a commit that referenced this issue Oct 27, 2023
…ee's IDs' for when we're looking for an element. Let other frags act like normal (but stay current-doc, still). #3320
@fantasai
Copy link
Collaborator

Agenda+ to review the latest spec text:
https://drafts.csswg.org/css-values-4/#local-urls

@css-meeting-bot
Copy link
Member

The CSS Working Group just discussed [css-values] Clarify fragment URLs resolve against the current tree, not document tree, and agreed to the following:

  • ACTION: fantasai ask ryosuke to review
  • RESOLVED: Accept edits
The full IRC log of that discussion <fantasai> -> https://drafts.csswg.org/css-values-4/#local-urls
<fantasai> TabAtkins: Awhile ago, we discussed how a fragment-only URL needs to be resolved
<fantasai> TabAtkins: both in general, in presence of base URL changes, or history API changing URL etc.
<fantasai> TabAtkins: wanted those to be stable
<fantasai> TabAtkins: also question of how that works in shadow DOM
<fantasai> TabAtkins: IDs are scoped to a particular shadow tree
<fantasai> TabAtkins: the resolution was that a fragment URL in a shadow tree resolves against IDs in that tree if possible
<fantasai> TabAtkins: if document-global, does page-local resolution
<fantasai> TabAtkins: not paying attention to absolutized URL still matches or not
<fantasai> TabAtkins: fantasai objected to the way I was writing because of future-compat with other types of fragment URLs (that are not IDs)
<fantasai> TabAtkins: I'm not 100% sure, because not familiar with other parts of the ecosystem
<fantasai> TabAtkins: but I think it gets the point across
<fantasai> TabAtkins: if your fragment is an ID reference, treat as ID reference relative to whatever shadow tree you're in
<fantasai> TabAtkins: otherwise, resolve against document e.g. as media fragment
<fantasai> TabAtkins: if other fragment types need to be shadow-sensitive, can adjust, but for now they're all globla
<fantasai> s/globla/global
<fantasai> TabAtkins: so requesting review from CSSWG, maybe take a resolution to accept text but can take time to review if wanted
<fantasai> astearns: has ryosuke reviewed?
<fantasai> ACTION: fantasai ask ryosuke to review
<fantasai> astearns: any comments?
<bkardell_> q+
<fantasai> astearns: proposed to accept edits and close the issue
<fantasai> bkardell_: does it take into account the base URL?
<fantasai> TabAtkins: no, very specifically not paying attention to URL before the fragment part
<fantasai> TabAtkins: if your URL is just a fragment, it's guaranteed local
<fantasai> TabAtkins: no matter what you do to page URL, or when you resolve URL
<fantasai> TabAtkins: we interpret as an ID reference
<fantasai> bkardell_: ok, I get it
<fantasai> astearns: objections?
<fantasai> RESOLVED: Accept edits
<fantasai> astearns: as people find more problems, open more issue
<fantasai> s

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
css-values-4 Current Work topic: urls Tracking issues that'll need edits when CSS URLs are defined on top of Fetch.
Projects
Agenda Scratchpad
Complex Discussions
November 30 2022
Agenda+ F2F
Development

No branches or pull requests

7 participants