whatwg / html

HTML Standard
https://html.spec.whatwg.org/multipage/
Other
7.87k stars 2.58k forks source link

Preserve fragment links when <base> is defined #6568

Open jonathantneal opened 3 years ago

jonathantneal commented 3 years ago

Currently, links pointing to a fragment — e.g. <a href="#some-id"> — are resolved with the <base>, triggering a request to the base URL with the fragment attached. While this seems technically expected, this seems realistically unexpected.

My understanding is that a lone fragment is typically used to link to sections or content in the current document, or to act as a nil reference for JavaScript side effects. My understanding is that a <base> href typically defines a base URL applied to multiple pages or assets, and is often not the target document itself.

If that understanding is accepted, it seems incorrect to apply the base href to a fragment link.

Could this expectation be changed, or could some functionality be added to allow HTML authors the ability to prevent fragment links from inheriting the base URL?

Note: In testing, I noticed that internal fragments work as expected in Safari (v14.0 & v14.2), but only when the base href points to another origin.

domenic commented 3 years ago

I can pretty confidently state there's no way this could be changed; it's behaved this way since Netscape 1.0 introduced the base tag and there's tons of sites relying on it, even if people writing new sites sometimes find it surprising.

The best way for authors to opt-in to not getting this behavior is to provide an absolute URL, which is unaffected by base.

jonathantneal commented 3 years ago

@domenic, thanks for the quick response, and for effectively confirming that, for compatibility reasons, the current expectation could not be changed.

I am interested in knowing, would you or other folks agree that the current expectation is problematic for authors? If so, perhaps there are other ways to help.

Also, I want to ping the inspiration for this request, @matthewp, who wrote the following:

There's so many ways that <base> is really cool... and then you run into something weird it does like make hash links link to the base page and not the current one and then... table flip.

domenic commented 3 years ago

I personally think the way things work today makes a great deal of sense. All URLs are resolved relative to the base element. It doesn't matter what character they start with; they all go through the spec equivalent of new URL(urlString, baseURL). Creating a less-uniform behavior would be bad IMO.

matthewp commented 3 years ago

Yeah I think it makes sense to me as well upon reflection, I wouldn't want an inconsistent behavior of how URLs are resolved. It's unfortunate in that <base> is often used to make pages portable so you can't use absolute URLs in that case. But you can still use hashlinks in this case by linking to the page you're currently on from the base, <a href="path/to/this/page#section">Section</a>. Some tooling I'm using creates hashlinks from markdown headings and it doesn't provide a way for me to do this, but that's a problem with the tooling and not with browsers.

Thanks for raising the discussion @jonathantneal !

annevk commented 3 years ago

CSS does have this feature and it is somewhat nifty. I always wanted HTML to work the same way, but we cannot change it now. The best we can do is probably introduce something like <a idref=some-id> but that would have its own set of issues.

cc @tabatkins

tabatkins commented 3 years ago

Yeah, the CSS behavior is somewhat accidental, but useful: https://drafts.csswg.org/css-values/#local-urls. For HTML, it would indeed need to be handled by some different attribute, most likely.

vnc5 commented 3 years ago

What about introducing a new attribute for the <base> tag? For example <base fragment="."> which overwrites the base for fragment links.

The default behavior also threw me off.