476

On many websites I see links that have href="#". What does it mean? What is it used for?

user247702
  • 23,641
  • 15
  • 110
  • 157
Samir Ghobril
  • 4,953
  • 4
  • 18
  • 15

9 Answers9

466

About hyperlinks:

The main use of anchor tags - <a></a> - is as hyperlinks. That basically means that they take you somewhere. Hyperlinks require the href property, because it specifies a location.

Hash:

A hash - `#` within a hyperlink specifies an HTML element id to which the window should be scrolled.

href="#some-id" would scroll to an element on the current page such as <div id="some-id">.

href="//site.example/#some-id" would go to site.example and scroll to the id on that page.

Scroll to Top:

href="#" doesn't specify an id name, but does have a corresponding location - the top of the page. Clicking an anchor with href="#" will move the scroll position to the top.

See this demo.

This is the expected behavior according to the w3 documentation.

Hyperlink placeholders:

An example where a hyperlink placeholder makes sense is within template previews. On single page demos for templates, I have often seen <a href="#"> so that the anchor tag is a hyperlink, but doesn't go anywhere. Why not leave the href property blank? A blank href property is actually a hyperlink to the current page. In other words, it will cause a page refresh. As I discussed, href="#" is also a hyperlink, and causes scrolling. Therefore, the best solution for hyperlink placeholders is actually href="#!" The idea here is that there hopefully isn't an element on the page with id="!" (who does that!?) and the hyperlink therefore refers to nothing - so nothing happens.

About anchor tags:

Another question that you may be wondering is, "Why not just leave the href property off?". A common response I've heard is that the href property is required, so it "should" be present on anchors. This is FALSE! The href property is required only for an anchor to actually be a hyperlink! Read this from w3. So, why not just leave it off for placeholders? Browsers render default styles for elements and will change the default style of an anchor tag that doesn't have the href property. Instead, it will be considered like regular text. It even changes the browser's behavior regarding the element. The status bar (bottom of the screen) will not be displayed when hovering on an anchor without the href property. It is best to use a placeholder href value on an anchor to ensure it is treated as a hyperlink.

See this demo demonstrating style and behavior differences.

Stephen Ostermiller
  • 23,933
  • 14
  • 88
  • 109
m59
  • 43,214
  • 14
  • 119
  • 136
  • 5
    Complete answer. But, What is the meaning of term *template preview* in your answer? – overexchange Dec 10 '15 at 11:40
  • 5
    @overexchange For example, see this page and the links on it: http://ironsummitmedia.github.io/startbootstrap-creative/ Just html pages that are meant to demonstrate a set of CSS/HTML, WordPress themes, etc, but aren't real pages, so the links don't need to go anywhere. – m59 Dec 10 '15 at 11:55
  • 2
    @Yeung Changing the hash (that's the part of the url following the #) doesn't call the server. You would change the page with javascript. There is a lot to say on this subject and it is beyond the scope of this post. – m59 Jan 08 '16 at 18:19
  • 2
    Also, random tidbit, Android browsers (browser, chrome, etc) won't accept click events on anything but anchor tags. So say you want to use jQuery's `.click()` method on a `
    `, it won't work. Either has to be on an anchor or you have to use `touch` events.
    – Steely Feb 26 '16 at 17:25
  • I can't find in the [documentation link](https://www.w3.org/TR/html5/browsers.html#scroll-to-fragid) where it says _href="#" will move the scroll position to the top_ – QHarr May 17 '19 at 09:05
  • 1
    @QHarr I'm not positive, but it should be because an empty "#" doesn't refer to anything, so is the same as leaving it off, and leaving it off would refer to just the page, and pages start at the top unless told otherwise. In other words, maybe it doesn't mean "scroll to the top", it just means nothing i.e. "go to this page", which happens to mean going to the top of the page. – m59 May 17 '19 at 14:33
  • 1
    @QHarr The link you've shared says, "If fragment is the empty string, then the indicated part of the document is the top of the document". – user359996 Jul 12 '21 at 16:13
  • `href='#!'` is neat trick and one I just implemented. You can achieve something similar by also using `e.preventDefault()` on the `anchors` `onClick` event too Update: Including just `href='#!'` still updates the url in the browser (`e.preventDefault()` will prevent that from happening if desired) – user2402616 Jan 04 '22 at 21:02
93

Putting the "#" symbol as the href for something means that it points not to a different URL, but rather to another id or name tag on the same page. For example:

<a href="#bottomOfPage">Click to go to the bottom of the page</a>
blah blah
blah blah
...
<a id="bottomOfPage"></a>

However, if there is no id or name then it goes "no where."

Here's another similar question asked HTML Anchors with 'name' or 'id'?

Community
  • 1
  • 1
KJYe.Name
  • 16,969
  • 5
  • 48
  • 63
  • 1
    A element with the ID - it doesn't have to be a named anchor (and in fact named anchors have been deprecated for a while now). – Oded Jan 31 '11 at 19:39
  • 4
    I came here because `...` wasn't "going nowhere" it was leaving the page and loading `site.com/#`. How is that possible? – doug65536 Sep 29 '13 at 12:00
  • 7
    @doug65536 most likely it is because an `onclick` event handler was tied to that element, causing a javascript function to be called that redirected you to that page. – jtate Jan 07 '14 at 15:52
53

Unfortunately, the most common use of <a href="#"> is by lazy programmers who want clickable non-hyperlink javascript-coded elements that behave like anchors, but they can't be arsed to add cursor: pointer; or :hover styles to a class for their non-hyperlink elements, and are additionally too lazy to set href to javascript:void(0);.

The problem with this is that one <a href="#" onclick="some_function();"> or another inevitably ends up with a javascript error, and an anchor with an onclick javascript error always ends up following its href. Normally this ends up being an annoying jump to the top of the page, but in the case of sites using <base>, <a href="#"> is handled as <a href="[base href]/#">, resulting in an unexpected navigation. If any logable errors are being generated, you won't see them in the latter case unless you enable persistent logs.

If an anchor element is used as a non-anchor it should have its href set to javascript:void(0); for the sake of graceful degradation.

I just wasted two days debugging a random unexpected page redirect that should have simply refreshed the page, and finally tracked it down to a function raising the click event of an <a href="#">. Replacing the # with javascript:void(0); fixed it.

The first thing I'm doing Monday is purging the project of all instances of <a href="#">.

32

It's a link that links to nowhere essentially (it just adds "#" onto the URL). It's used for a number of different reasons. For instance, if you're using some sort of JavaScript/jQuery and don't want the actual HTML to link anywhere.

It's also used for page anchors, which is used to redirect to a different part of the page.

Tyler Treat
  • 14,640
  • 15
  • 80
  • 115
  • 44
    Just to add, it's not precisely a link to nowhere... on a scrolling page it will auto-scroll you to the top. – Misko Jan 31 '11 at 19:50
25

Unordered lists are often created with the intent of using them as a menu, but an li list item is text. Because the list li item is text, the mouse pointer will not be an arrow, but an "I cursor". Users are accustomed to seeing a pointing finger for a mouse pointer when something is clickable. Using an anchor tag a inside of the li tag causes the mouse pointer to change to a pointing finger. The pointing finger is a lot better for using the list as a menu.

<ul id="menu">
   <li><a href="#">Menu Item 1</a></li>
   <li><a href="#">Menu Item 2</a></li>
   <li><a href="#">Menu Item 3</a></li>
   <li><a href="#">Menu Item 4</a></li>
</ul>

If the list is being used for a menu, and doesn't need a link, then a URL doesn't need to be designated. But the problem is that if you leave out the href attribute, text in the <a> tag is seen as text, and therefore the mouse pointer is back to an I-cursor. The I-cursor might make the user think that the menu item is not clickable. Therefore, you still need an href, but you don't need a link to anywhere.

You could use lots of div or p tags for a menu list, but the mouse pointer would be an I-cursor for them also.

You could use lots of buttons stacked on top of each other for a menu list, but the list seems to be preferable. And that's probably why the href="#" that points to nowhere is used in anchor tags inside of list tags.

You can set the pointer style in CSS, so that is another option. The href="#" to nowhere might just be the lazy way to set some styling.

sideshowbarker
  • 81,827
  • 26
  • 193
  • 197
Alan Wells
  • 30,746
  • 15
  • 104
  • 152
19

The problem with using href="#" for an empty link is that it will take you to the top of the page which may not be the desired action. To avoid this, for older browsers or non-HTML5 doctypes, use

<a href="javascript:void(0)">Goes Nowhere</a>
RationalRabbit
  • 1,037
  • 13
  • 20
  • 2
    I found this solution is particular useful for one scenario: in my application, the href='"" is used to implement the logout (bring to login page) functionality. If I use the href="#" for other purpose, sometime it will take me back to the login page. After I change the href="#" to href="javascript:void(0)", the issue has been resolved. – Liang Feb 06 '19 at 19:57
14

As some of the other answers have pointed out, the a element requires an href attribute and the # is used as a placeholder, but it is also a historical artifact.

From Mozilla Developer Network:

href

This was the single required attribute for anchors defining a hypertext source link, but is no longer required in HTML5. Omitting this attribute creates a placeholder link. The href attribute indicates the link target, either a URL or a URL fragment. A URL fragment is a name preceded by a hash mark (#), which specifies an internal target location (an ID) within the current document.

Also, per the HTML5 spec:

If the a element has no href attribute, then the element represents a placeholder for where a link might otherwise have been placed, if it had been relevant, consisting of just the element's contents.

Doug Richardson
  • 10,483
  • 6
  • 51
  • 77
13

As far as I know it’s usually a placeholder for links that have some JavaScript attached to them. The main point of the link is served by executing the JavaScript code; browsers with JS support then ignore the real link target. If the browser does not support JS, the hash mark essentially turns the link into a no‑op. See also unobtrusive JavaScript.

Community
  • 1
  • 1
zoul
  • 102,279
  • 44
  • 260
  • 354
11

The href attribute defines the URL of the resource of a link. If the anchor tag does not have href tag then it will not become hyperlink. The href attribute have the following values:

1. Absolute path: move to another site like href="http://www.google.com"
2. Relative path: move to another page within the site like herf ="defaultpage.aspx"
3. Move to an element with a specified id within the page like href="#bottom"
4. href="javascript:void(0)", it does not move anywhere.
5. href="#" , it does not move anywhere but scroll on the top of the current page.
6. href= "" , it will load the current page but some browsers causes forbidden errors.

Note: When we do not need to specified any url inside a anchor tag then use 
<a href="javascript:void(0)">Test1</a>
Sheo Dayal Singh
  • 1,591
  • 19
  • 11