Support linking / hrefs on any element

It should be possible to turn any element into a link, either by giving it an href attribute or some other method.

Wrapping in an anchor is not sufficient for elements such as table rows that cannot be legally placed inside an anchor element.

Using JS is not sufficient as pseudo-links do not provide all necessary functionality, such as a context menu with “open in new tab / window” options. They also break if JS is disabled.


FWIW, the (discontinued) XHTML 2.0 allowed the href attribute to be global.

IIRC, the feature has also been proposed for HTML5 or even included in some of earliest HTML5-spec versions, but in the end it has been rejected on the ground of backward incompatibility.

It’s been almost 10 years since then, and browsers have adopted the rapid-release paradigm long ago, so backward compatibility is now probably not a critical issue (if really was at all), and this could probably reconsidered.


But placing display:block anchors inside table cells should work, no?

There are issues with links in tables:

  • There is no way to make an entire row a link.
  • Even for one-cell links, it’s typically problematic (probably easier with Flexbox) to make them occupy the entire cell’s height if different cells in the same row have different content heights.

The ship may have sailed on this one. Vendors have started implenting href without the xlink: namespace on SVG elements.

I don’t follow. How does SVG allowing hrefs affect HTML allowing them on non-anchor elements?

Nothing, technically. But if SVG’s proposed <video>, <canvas>, etc. elements come through, they already would use href instead of src. (Like how <image href> is already <img src>.)

If it’s still important enough, though, it’s machine-parseable. I would get confused, but I’m only one person.

Hm, I don’t know about table row links. It sounds like a cool feature, but I don’t think it’s really needed; having links and buttons inside table cells should be enough, IMHO.

Having created many, many such tables in web apps I can assure you it is needed.

First there is the table-cell layout nightmare that MT mentions. And then there is the performance question. Imagine I have a data-bound table in a web app with 1000 rows and 20 columns (it could easily be bigger). It’s the difference between adding an href attribute on 1000 rows, versus creating 20,000 data-bound anchor elements, with all the JS, parsing and layout work that involves in the browser.

To be honest, I don’t understand how there can be any objection to making linking easier and more powerful. Links and URLs are the web’s killer feature. They are the one thing that native apps cannot do. So why is the actual markup support for them so limited? We’re basically stuck with what we had in 1994.

IIRC, someone responsible to make decisions believed long ago that making the href attribute global would break the web because older user agents would be unable to recognize such links. This is probably not true anymore given that browsers are updated frequently and automatically today (except for ones made by MS).

I’m all about use cases; I’m not concerned with what “feels right” :sweat_smile:. Having three separate use cases for this proposal would be great.

To address your scenario, I meant that having one anchor per row (in the row’s primary cell) should be fine. I’m not even sure that having the entire row act as an anchor is a good UI pattern to begin with. Users expect to interact with links and form controls inside cells, I think.

I think we’d be better off having direct discussions on what to add href to instead of “just make it global”. It certainly doesn’t belong on, body, header, footer, aside, figure, figcaption, canvas, video, audio, ul, ol, dl, etc. There are numerous cases where allowing href against the whole thing would be maddening.

Personally, table rows as anchors is also a horrid pattern. It makes selecting/copying content within the table extremely difficult at times. However, there are places where this could be useful, so perhaps allowing href on tr to start would be a good start. Further cases on allowing it on other elements can be discussed on an as-needed basis around the use-cases relevant to that particular element.

It could be a BC concern. As your site would work in some browsers but not in others. And using JS to detect this and make things work in older engines wouldn’t be easy. You’d essentially rely on browser detection instead of feature detection which has been discouraged for a good time now.

Some examples of using entire table row as a link:

1 Like

The only element from your list that really does not make much sense as a link is probably BODY, though even it could probably be used on a splash page that opens a real website on click (whether such pages are desirable in general is out of the topic).

Usecases are obviously the same as for regular links. Anywhere we would put a link into an element to make it a link, we could just add the href attribute directly to the element with no nested extra A element.

Allowing href on any element is long past doable, not least because of the SVG issues @Tigt mentioned. However the table case in particular stands out as being an issue and I have to agree with @amtiskaw that some sort of fix is needed.

My ideal scenario would be that an a could wrap a tr, td or th but there’s no way to make such a major change to HTML parsing at this point. On that basis I would say there’s a good argument to allow href on those elements specifically.

There are several big problems that need to be solved though going in:

  1. Nesting. Currently it is impossible to nest a tags, browsers will close one a before the next one starts. What happens if there is an a in a tr with an href? Does the inner one get ignored? Pushed out after the row? Do we allow this, if so what impact will this have on usability and assistive technology?
  2. CSS styling. Do the :link and related psuedo-classes also now get to apply to tr and other allowed elements? If not how do we target linkable elements?
  3. How best can we future proof it so that if more elements are added to those allowed to use href as a link we don’t need to re-answer these questions

This is easily solvable if the change also comes with a property on navigator we can question so it is easy to feature detect. Eg navigator.allowLinkOn() where you can pass an element or tagname.

I can think of several where it doesn’t make sense. Anything with existing interaction semantics for a start. What happens when I click on <input type="checkbox" href="" name="example" /> does it navigate to Google or does it toggle the state of the checkbox? Questions like this are why it would have to be on an element by element basis.

This isn’t a usecase. A usecase is a specific example. Also considering that this is a huge change they should be compelling usecases where using an a in a well structured document would not provide a solution. The table case is currently the only one I can think of.

So, video and audio which provide controls to the player should actually link to external pages instead when clicked on? That is an extremely confusing user experience to allow for so trivially.

Why would figure and figcaption in any way be links themselves? That goes completely against their semantic reasons for existing.

Why would you have entire sectional elements (header, footer, article, aside, section, ol, ul) be links out to external content? These things should contain links within them, not be them.

The philosophy of having a loose experience for developers to build is very beneficial. However, I do think there is a line where vendors need to consider solid use-cases for changes that change how things have worked for a very long time. Allowing href on just “anything” could be extremely detrimental overall. Being open to individual element changes should absolutely be possible. But, saying there is one use-case in one element to have it therefore someone must have good use-cases for every other element that exists isn’t a good way to go about making change.

I would say add it to the element nodes instead of navigator since I am advocating we do individual changes over one global change. But, that is a good way to handle it.

I’m proposing a function that you can pass either an element for a one off test or a tagname to see if that tag supports linking. Eg navigator.allowLinkOn("a"), navigator.allowLinkOn("area") and in this case navigator.allowLinkOn("tr") would all return true, whereas navigator.allowLinkOn("footer") would be false. I’d also say it should allow navigator.allowLinkOn(element) for a one off test case too.

This supports individual changes just as well but would be simpler than creating an element just to test that. It also means testing for the single navigator function means you know if you’re in classic or brave-new-world linking.

1 Like

Indeed, interactive elements like INPUT could be excluded on the spec level from those the href attribute is allowed to use with.

Basically, we could disallow using the href attribute with elements that regular links cannot currently be placed inside while being functional (clickable), except for elements like LINK that already have href attribute allowed.

So are you asking for a usecase for links? Well, links are fundamental to the web, aren’t they? :wink:

There is no essential functional difference between A element itself and an href’ed element with no redundant nested A element.

That’s probably a question to those allowed A to contain block-level elements (incl. sectioning ones) in HTML5.

The usecase is to make a semantically marked-up block (e. g. corresponding to an item in an internet store) which is entirely a link to make it easier to click or tap it without the need for aiming precisely a small clickable part of the block. Before this has been standardized, those caring about validity have been forced to use a bunch of nested unsemantic SPAN elements instead of proper structural markup.

There could be many edgecases, each needs to be noted and considered for its impact. A breaking change to something as fundamental as links needs to be done carefully with as small a footprint as possible if you want any hope it gets looked at by the browsers. This proposal needs to be explicit about which elements get it added, not which get excluded. Each proposed additional element can then have the merits and problems discussed independently.

A test case and a use case are fundamentally different. Your previous “use case” was “Usecases are obviously the same as for regular links” in which case the response is going to be “well just use a regular link then”. Your usecase needs to be a concrete example of where the change would provide notable improvement to developers or the platform as a whole. Simply getting to drop an element on a document does not come close.

A usecase for allowing tr would be

It’s a bit long-winded but I wanted to clearly show the points you need to be making.