Chalk (JS) maintainer here. Never felt right about the hyperlink escapes as they feel like a kludge, and javascript: scheme should be deprecated and removed - constant source of XSS and has little to no benefit these days. This doesn’t surprise me at all. Great writeup!
I have not found a properly good replacement for javascript:void(0) (of all things, ironically). Every alternative has worse fallback behavior in one way or another.
Other than that, I would agree.
I guess I would – keeping backcompat in mind – be happy for that one value (and maybe some spelling variations) to continue to be supported as a special do-nothing link target without the javascript protocol as a whole being supported any more otherwise.
(It would be nice if that special case could then also be exempted from CSP, to make the fallback behavior even more robust.)
I don’t think a legitimate use case for <ahref=javascript:void(0)> exists (though I’m open to hear suggestions). If there’s a meaningful URL for it, it’s obviously wrong, and if there isn’t, it should be a button instead.
There are a couple places where I could use a <button> instead, I would just have to fight its defaults harder. Then there are other places that would be difficult to deal with because I’m generating a link in a template for a data structure, which may sometimes have a missing URL – and it would be difficult due to the layering of the code to make those cases switch outright from <ahref="{url}">{more-stuff-here}</a> to <span>{more-stuff-here}</span> instead of just outputting a special href value, and even after doing that it’d then require more effort to ensure the styling works the same both ways (which is important because what’s being generated is a table, and discrepancies in styling would cause very obvious misalignments).
There is probably no situation that’s impossible to handle without the ability to create a link that doesn’t go anywhere, but some situations are much simpler to deal with that way.
Wait, your second case is actually do nothing? I was assuming these were javascript:void(0) and then attach an event handler. If you’re actually doing nothing, I object even more. Consider if you can just omit the href attribute, rather than changing element name; it’s often tolerable.
And your first case… well, a button should be a button and a link a link. They behave differently and should look different.
A button should be a button and a link a link. They behave differently and should look different.
Well yeah. How is that an argument for using a <button> for something that is supposed to not look like a button?
Consider if you can just omit the href attribute, rather than changing element name; it’s often tolerable.
I have dealt with those things; let me just call “tolerable” a good way of describing them. They work worse than href="javascript:void(0)", so “UX” must rank lower than “markup quality” among your priorities in order to prefer that approach. But considering that it’ll usually be significantly more effort to go that route anyway, I don’t know when I’d pick that approach over either the cheap hack (just return javascript:void(0) for missing links) or the full monty (redesign all the interfaces through all the layers to bubble up the missing link signal).
I don’t like javascript:void(0). What I’m saying is that it’s a tool for the desperate: if you have the leisure to restructure the code in a more fundamental way then there are always better options – but in times of desperation, when you’re painted into a corner, the desperation would deepen without it available.
A button should be a button and a link a link. They behave differently and should look different.
Well yeah. How is that an argument for using a <button> for something that is supposed to not look like a button?
Why are you even asking about a thing that is somehow not supposed to look like a button, as opposed to not supposed to behave like a button?
I think if things are so bad, just using href="#" would not really stand out of the mess.
Now, for bookmarklets javascript: is still useful — but file:/// URLs work in bookmarks but not when inserted into HTML, so maybe we can separate the two cases?
Why are you even asking about a thing that is somehow not supposed to look like a button, as opposed to not supposed to behave like a button?
The preceding conversation context would explain that. I initially mentioned that javascript:void(0) specifically is useful in a way that the javascript: protocol as a whole is not, and was asked for use cases, and one of the two I replied with was that if something is supposed to not look like a button then <ahref="javascript:void(0)"> is a simpler starting point than (roughly) <button type="button" form="" style="appearance: none; display: inline"> – but the answer I got was that buttons should look like buttons and links should look like links, a statement whose connection to what I said I don’t understand. So I asked for clarification about how it relates back to the preceding conversation – which conversation was precisely about such “a thing that is somehow not supposed to look like a button, as opposed to not supposed to behave like a button”.
I think if things are so bad, just using href="#" would not really stand out of the mess.
That scrolls to the top of the page and also changes the location in the address bar (at the least). Particularly for the “I actually don’t have a link to output here nor any mechanism to signal that” case that would be a very bad replacement. For the “links don’t require fighting as many defaults” case it can be dealt with using preventDefault, which indeed is no big deal though nevertheless marginally less robust.
Now, for bookmarklets javascript: is still useful — but file:/// URLs work in bookmarks but not when inserted into HTML, so maybe we can separate the two cases?
There was discussion about that in some other subthread.
So I asked for clarification about how it relates back to the preceding conversation, which was precisely about such a thing that is not supposed to look like a button (as opposed to somehow not supposed to behave like a button).
I would say that the problem is not that it is not supposed to look like a button — if it behaves like it button, it should ideally look like it. The problem is that due to constraints it needs to be generated not like a button.
That scrolls to the top of the page and also changes the location in the address bar (at the least).
Location yes, but it is a mess anyway. #- (or other non-existent anchor) could be used to definitely not scroll.
Chalk (JS) maintainer here. Never felt right about the hyperlink escapes as they feel like a kludge, and
javascript:scheme should be deprecated and removed - constant source of XSS and has little to no benefit these days. This doesn’t surprise me at all. Great writeup!score 2 · canonical
I have not found a properly good replacement for
javascript:void(0)(of all things, ironically). Every alternative has worse fallback behavior in one way or another.Other than that, I would agree.
I guess I would – keeping backcompat in mind – be happy for that one value (and maybe some spelling variations) to continue to be supported as a special do-nothing link target without the
javascriptprotocol as a whole being supported any more otherwise.(It would be nice if that special case could then also be exempted from CSP, to make the fallback behavior even more robust.)
score 1 · canonical
I don’t think a legitimate use case for
<a href=javascript:void(0)>exists (though I’m open to hear suggestions). If there’s a meaningful URL for it, it’s obviously wrong, and if there isn’t, it should be a button instead.score 1 · canonical
There are a couple places where I could use a
<button>instead, I would just have to fight its defaults harder. Then there are other places that would be difficult to deal with because I’m generating a link in a template for a data structure, which may sometimes have a missing URL – and it would be difficult due to the layering of the code to make those cases switch outright from<a href="{url}">{more-stuff-here}</a>to<span>{more-stuff-here}</span>instead of just outputting a specialhrefvalue, and even after doing that it’d then require more effort to ensure the styling works the same both ways (which is important because what’s being generated is a table, and discrepancies in styling would cause very obvious misalignments).There is probably no situation that’s impossible to handle without the ability to create a link that doesn’t go anywhere, but some situations are much simpler to deal with that way.
score 1 · canonical
Wait, your second case is actually do nothing? I was assuming these were
javascript:void(0)and then attach an event handler. If you’re actually doing nothing, I object even more. Consider if you can just omit thehrefattribute, rather than changing element name; it’s often tolerable.And your first case… well, a button should be a button and a link a link. They behave differently and should look different.
score 2 · canonical
Well yeah. How is that an argument for using a
<button>for something that is supposed to not look like a button?I have dealt with those things; let me just call “tolerable” a good way of describing them. They work worse than
href="javascript:void(0)", so “UX” must rank lower than “markup quality” among your priorities in order to prefer that approach. But considering that it’ll usually be significantly more effort to go that route anyway, I don’t know when I’d pick that approach over either the cheap hack (just returnjavascript:void(0)for missing links) or the full monty (redesign all the interfaces through all the layers to bubble up the missing link signal).I don’t like
javascript:void(0). What I’m saying is that it’s a tool for the desperate: if you have the leisure to restructure the code in a more fundamental way then there are always better options – but in times of desperation, when you’re painted into a corner, the desperation would deepen without it available.score 1 · canonical
Why are you even asking about a thing that is somehow not supposed to look like a button, as opposed to not supposed to behave like a button?
I think if things are so bad, just using
href="#"would not really stand out of the mess.Now, for bookmarklets
javascript:is still useful — but file:/// URLs work in bookmarks but not when inserted into HTML, so maybe we can separate the two cases?score 1 · canonical
The preceding conversation context would explain that. I initially mentioned that
javascript:void(0)specifically is useful in a way that thejavascript:protocol as a whole is not, and was asked for use cases, and one of the two I replied with was that if something is supposed to not look like a button then<a href="javascript:void(0)">is a simpler starting point than (roughly)<button type="button" form="" style="appearance: none; display: inline">– but the answer I got was that buttons should look like buttons and links should look like links, a statement whose connection to what I said I don’t understand. So I asked for clarification about how it relates back to the preceding conversation – which conversation was precisely about such “a thing that is somehow not supposed to look like a button, as opposed to not supposed to behave like a button”.That scrolls to the top of the page and also changes the location in the address bar (at the least). Particularly for the “I actually don’t have a link to output here nor any mechanism to signal that” case that would be a very bad replacement. For the “links don’t require fighting as many defaults” case it can be dealt with using
preventDefault, which indeed is no big deal though nevertheless marginally less robust.There was discussion about that in some other subthread.
score 1 · canonical
I would say that the problem is not that it is not supposed to look like a button — if it behaves like it button, it should ideally look like it. The problem is that due to constraints it needs to be generated not like a button.
Location yes, but it is a mess anyway.
#-(or other non-existent anchor) could be used to definitely not scroll.score 1 · canonical