Cross-reference (named anchor) in markdown
Asked Answered
C

16

719

Is there markdown syntax for the equivalent of:

Take me to <a href="#pookie">pookie</a>

... 

<a name="pookie">this is pookie</a>
Convery answered 16/3, 2011 at 0:41 Comment(0)
E
946
Take me to [pookie](#pookie)

should be the correct markdown syntax to jump to the anchor point named pookie.

To insert an anchor point of that name use HTML:

<a name="pookie"></a>

Markdown doesn't seem to mind where you put the anchor point. A useful place to put it is in a header. For example:

### <a name="tith"></a>This is the Heading

works very well. (I'd demonstrate here but SO's renderer strips out the anchor.)

Note on self-closing tags and id= versus name=

An earlier version of this post suggested using <a id='tith' />, using the self-closing syntax for XHTML, and using the id attribute instead of name.

XHTML allows for any tag to be 'empty' and 'self-closed'. That is, <tag /> is short-hand for <tag></tag>, a matched pair of tags with an empty body. Most browsers will accept XHTML, but some do not. To avoid cross-browser problems, close the tag explicitly using <tag></tag>, as recommended above.

Finally, the attribute name= was deprecated in XHTML, so I originally used id=, which everyone recognises. However, HTML5 now creates a global variable in JavaScript when using id=, and this may not necessarily be what you want. So, using name= is now likely to be more friendly.

(Thanks to Slipp Douglas for explaining XHTML to me, and nailer for pointing out the HTML5 side-effect — see the comments and nailer's answer for more detail. name= appears to work everywhere, though it is deprecated in XHTML.)

Enkindle answered 7/9, 2011 at 14:7 Comment(30)
You can't see how to link to your heading demo after StackOverflow renders the HTML because their rendered is stripping out your <a> tag. That is, you can't in StackOverflow Markdown.Nonaligned
However, this will work in other, more-liberal Markdown renderers, but you'll need a closing <a> tag; the <a> tag doesn't allow self-closing. Also, I found my browser to skip past the header unless the <a> tag is before the header's contents. Corrections made to your examples.Nonaligned
Slipp: Thanks for the explanation. Self-closing <a> tags work fine for me. Can you give a reference?Enkindle
Well, in the browsers I tested (Chrome 18, Firefox 11, and Safari 5.1 on Mac OS X) it turns the rest of the page into a link. I'll see if I can dig up anything in the HTML spec.Nonaligned
Slipp: I'm using Chrome 18 and Safari 5.1 on the Mac too. What Markdown renderer did you use?Enkindle
In the SO question here (or rather its answers) it appears to say that all elements are self-closable in XHTML, and the browsers you mention should cope with it. Since this information also changes the note about id= vs name= I'm going to edit the answer again. Can I ask you not to directly modify the answer until your research is done?Enkindle
Oh, and the Markdown renderer (I use the rdiscount gem) isn't doing anything special; ### <a id="tith" />This is a Heading with a link becomes <h3><a id="tith" />This is a Heading with a link</h3>. Check it out for yourself: gist.github.com/2432787Nonaligned
There's a lot of argument on that post. I wouldn't trust it.Nonaligned
Slipp: test-xhtml11 seems to consist only of anchors (no links) and you have included text in the body of the <a element in all cases. I'm afraid I don't see what you are driving at. All of them render correctly. The second link you have specified the wrong way round in Markdown but I see it. Still looks like anchors all work correctly. But you are specifying <a id="tith">test</a> and not <a id="tith"/>test so what do you mean to demonstrate by it? Oh, and I'm not a cowboy.Enkindle
… You're not seeing this: cl.ly/391D2B0r2u41033n2N2N (rendering the rest of the page within the <a> anchor), with this raw source: cl.ly/3e0C2T0w1N0p1k3J1R1Z (just a <a id="tith" />), and this Markdown in the gist: cl.ly/3F243H3H3Z2m0p2X1q3l (still just a <a id="tith" />)? I'm seriously not making this tish up.Nonaligned
Slipp: What is your point? I see everything you say I should, but afaics it is all working correctly. When we talk self-closing tags we mean that they accept the syntax <a id=".." /> and do not require <a id=".."></a>, don't we? In which case, what do you mean by including lots of text between the <a> and </a> tags? I don't recommend it when this is an anchor (as opposed to a link).Enkindle
Hey Steve, We are in agreement as to what self-closing is, but disagreement as to whether the code sample works. The code samples I posted render incorrectly (as shown in the the screenshots I posted). If you're not getting this when clicking the same links, then the next step would be to compare the DOM trees our browsers are parsing out of the source. I'll be happy to post whatever for you if you're still curious, but if it's just for the sake of the argument I've lost interest.Nonaligned
Oh, also… I suspected earlier that your browser was also auto-closing the non-closed <a> tags at the end of the document (like mine), but your stylesheet was set up not to underline non-href-ed, so you weren't seeing any difference in the rendered HTML (but the DOM still would've differed). However, if my code samples look fine to you, then this is a moot point.Nonaligned
@Slipp: OK I think I understand, now. You coded <a id="hi"/> rest of doc, but it was treated like <a id="hi"> rest of doc</a>. (And the element analysis of the page shows this, too.) My mistake: I looked at the elements displayed not the raw source. Do you think the answer should be modified, in light of this observation?Enkindle
I have updated the answer in light of nailer's answer (which ought to have been a comment, then I would have noticed this earlier).Enkindle
I don't think you understand how SO works. This isn't a wiki.Nonaligned
XML’s self-closing syntax <a/> is valid only if the document is read by the browser as XML (for example, by setting Content-Type: application/xhtml+xml; charset=utf-8) or otherwise if the element is in HTML’s void element list in which case the HTML parser will ignore the slash (older ones by seeing it as a syntax error to be recovered from) and also automatically close the element (because it’s unable to have any content, it’s void).Class
Forget about XHTML - it is invented to steal people's lives.Blastomere
It isn't the browser that handles <a name="Foo"/> improperly, it's the markdown parser/renderer. I use <a name="Foo"/> all the time in pure HTML without any problems, but Markdown is not. Edit: oops, I just checked, turns out my "pure HTML" was being transformed by some software into <a name="Foo"></a> behind my back. I still think the browser could parse it... why not, it definitely handles <br/>.Kurgan
As a sidenote, if you check the markdown project page and its md source you'll see both full closing tags and self-closing tags for anchors on headers. In the rendered HTML, only the full tags work well (eg: Configuration), the self closing one (eg: Dicussion List) end up creating 3 different anchors, with the third one being closed by the first link in the following paragraph. Madness.Machine
The name attribute also creates global variables (see #3434778), so you might as well use the id attribute as the target of fragment identifier URLs, as intended.Hoeg
name attribute of <a> element appears to be obsolete according to mdnNickerson
This works for me when posted to a GitLab Wiki page, but not in VS Code 1.29.1. I have the Markdown All in One extension installed which may or may not matter.Hoodmanblind
I always use <a name="pookie"><!-- --></a> because having an empty element didn't work, but maybe that's a relic of HTML3 or 4?Dramatization
Is it possible to use anchor from another note in the same notebook?Bookcraft
I came here for an answer and left without the best answer to this question. I found an elegant solution here without the need for redundant anchor tags. Please update the accepted answer as this is a highly active questionCatalog
@Catalog the original question concerns Markdown and your referenced link is a feature of GitHub markdown. The answer given is true for pure markdown (and for GitHub markdown). Incidentally, the trick in GitHub only works for headings and doesn’t work if there are more than one heading that produce the same link. I think this is still the ‘best’ answer to the problem.Enkindle
using "name" attribute instead of "id" won't work in VSCode side preview.Nicky
name attribute does NOT work. Id doesUnbeatable
Some markdown parsers (looking at you, BitBucket Server) seem to insist on inserting an href attribute when the <a name="..."> tag doesn't include one. What's unfortunate about that is that it inserts href="null"; So to cater to that particular misbehavior, always include an href="" with your anchors. Alternatively, just repeat the #<anchor-name> so it becomes a link to itself.Lo
H
148

On bitbucket.org the voted solution wouldn't work. Instead, when using headers (with ##), it is possible to reference them as anchors by prefixing them as #markdown-header-my-header-name, where #markdown-header- is an implicit prefix generated by the renderer, and the rest is the lower-cased header title with dashes replacing spaces.

Example

## My paragraph title

will produce an implicit anchor like this

#markdown-header-my-paragraph-title

The whole URL before each anchor reference is optional, i.e.

[Some text](#markdown-header-my-paragraph-title)

is equivalent of

[Some text](https://bitbucket.org/some_project/some_page#markdown-header-my-paragraph-title) 

provided that they are in the same page.

Source: https://bitbucket.org/tutorials/markdowndemo/overview (edit source of this .md file and look at how anchors are made).

Housebroken answered 26/8, 2014 at 9:29 Comment(8)
This may do as well. According to this: confluence.atlassian.com/bitbucket/…, bitbucket supports the Table of Contents extension which can auto-generate links and anchors based on the document headers. The TOC extension is documented here: pythonhosted.org/Markdown/extensions/toc.html Add the text "[TOC]" to the beginning of the document for it to be generated.Hypsometry
In Github, ## My paragraph title will produce the following anchor user-content-my-paragraph-title, so you can reference it with [Some text](#user-content-my-paragraph-title). However, I haven't found official documentation for this.Sciamachy
This helped me on Bitbucket as well - works like a charm.Ettaettari
This is useful information; thank you. However, markdown renderers without the extensions won't generate these anchors for you, and clashing heading names will result in clashing anchor ids (or some unhelpful distinguishing trick, like number suffices). Explicit anchor ids are better, more controllable, not subject to random changes due to text updates (see trick above) and useful for anchoring more than just headers. Both techniques are needed in general.Enkindle
On stackedit.io [linky](#header) was a sufficient anchor, and worked when published to Gist, too.Kenric
The accepted answer works for bitbucket now and this doesn't.Rely
You can track changes here: jira.atlassian.com/browse/BSERV-4532Linsk
Doesn't work for Bitbucket Server.Lo
D
77

Use a name. Using an id isn't necessary in HTML 5 and will create global variables in your JavaScript

See the HTML 5 specification, 5.9.8 Navigating to a fragment identifier - both id and name are used.

It's important to know that most browsers still turn IDs into global variables. Here's a quick test. Using a name avoids creating globals and any conflicts that may result.

Example using a name:

Take me to [pookie](#pookie)

And the destination anchor:

### <a name="pookie"></a>Some heading
Deluna answered 10/6, 2013 at 16:20 Comment(17)
Downvoting. The global variable argument is weak since you shouldn't be (directly) defining global variables in your JS anyway, so no conflict will happen. Also, the semantics of name and id are different.Pentagrid
@MarnenLaibow-Koser Nobody is discussing defining global variables in JS. Making an ID in HTML creates a global window.someid in most browsers.Deluna
I know. But unless your own JS defines global variables, the window.someID variables won't hurt anything.Pentagrid
@MarnenLaibow-Koser Many libraries (i.e., not your own JS, but someone else's) use a single global - for example, fineuploader. If you make an element with an ID of fineuploader, you will be unable to use the fineuploader module. Avoiding creating unnecessary globals helps avoid those conflicts.Deluna
I would be interested to run some tests of that case and find out which one takes precedence. I appreciate the theoretical issue, but in years of client-side development, I've never had an ID break any client-side JS (provided the HTML was otherwise valid). I'll continue to use them when they're semantically appropriate until I run into actual problems.Pentagrid
@MarnenLaibow-Koser I (and many others) have had HTML IDs break real JavaScript - there's one very practical example in the comment you're replying to! There's many styleguides and companies that always use classes, even for singletons, and this is why.Deluna
I'm utterly amazed. Then again, I never use global variables in JavaScript. Also, a JavaScript library that creates a global variable with a name that's also legal for an ID (i.e. not $ or _) should be considered broken: it's very poor form for a library to pollute the global namespace that much.Pentagrid
@MarnenLaibow-Koser TBH globals are dead for folk that use browserify or similar, but for libraries that use globals (eg, people that use <script> tags for each lib), lowercase names are far more common than specially prefixed names.Deluna
No one should be doing libraries that way now that decent module systems and build tools exist for JavaScript.Pentagrid
@MarnenLaibow-Koser Yep. 100% agreed everyone should be using module systems now. However there's still quite a few companies that, even in 2016, publish JS libs with "Just drop this <script> tag onto your page" and don't publish things on npm. I wish we could force them to modularise their libs. But we can't, so it's still worth being cautious and programming defensively - hence avoiding HTML ID globals.Deluna
Programming defensively is only useful where you don't have full control of the environment. That is not the case here, as I understand it. In other words, the onus for programming defensively is on the library authors, not the ultimate user of those libraries. Also, 'drop this <script> in' is still useful for things like Google Analytics—but things like that don't need to pollute the global namespace, and generally don't.Pentagrid
"'drop this <script> in' generally doesn't pollute the global namespace" Testing popular libraries shows they do - see window.Stripe window.olark, and window.twttr. Read more at 2ality.com/2012/08/ids-are-global.htmlDeluna
Although I still maintain that those libraries are poorly written for doing that, the fact is that you're not going to use more than about 3 on any page, so there won't be more than about 3 reserved IDs to worry about. If you can't get a better modularized library, just avoid the reserved IDs -- don't throw the baby out with the bath water by claiming that IDs are dangerous. (Also: "popular" libraries? I can't find any info on twttr, and had never heard of Olark before. window.Stripe normally won't be an issue: who the heck uses capital letters for element IDs?)Pentagrid
Also, the whole argument is silly for the following reason: if there's a conflict between an ID and something else, the something else takes precedence. See jsfiddle.net/pcj1pgnk: window.Stripe still refers to the Stripe object, even though there's a <div> with ID Stripe (at least in Chrome). So as long as you don't rely on the divs-as-globals behavior (which no one does), it won't break anything because it will always yield.Pentagrid
@MarnenLaibow-Koser Agree. In addition, the very syntax of a HTML id allows id values containing hyphen, colon and dot, the use of which will make impossible the translation of an ID into a variable name, global or not.Vantage
@AdrianColomitchi colon and hyphen and dot can all be used as variable names in JavaScript. However that's still beside the point: n global variables (where n is the amount of IDs in use) isn't a good idea.Deluna
@Deluna They won't hurt anything if your own JS uses proper practice, so you can safely ignore them.Pentagrid
G
31

Markdown Anchor supports the hashmark, so a link to an anchor in the page would simply be [Pookie](#pookie)

Generating the anchor is not actually supported in Gruber Markdown, but is in other implementations, such as Markdown Extra.

In Markdown Extra, the anchor ID is appended to a header or subhead with {#pookie}.

Github Flavored Markdown in Git repository pages (but not in Gists) automatically generates anchors with several markup tags on all headers (h1, h2, h3, etc.), including:

  • id="user-content-HEADERTEXT"
  • class="anchor"
  • href="#HEADERTEXT"
  • aria-hidden="true" (this is for an svg link icon that displays on mouseover)

Excluding the aria/svg icon, when one writes:

  • # Header Title

Github generates:

  • <h1><a id="user-content-header-title" class="anchor" href="#header-title">Header Title</a></h1>

Therefore, one need do nothing to create the header links, and can always link to them with:

  • Link to the [Header Title](#header-title)
Groove answered 24/8, 2017 at 11:41 Comment(3)
This is the one that works for me. [Header Title](#header-title)Electroplate
This works on Azure Devops too. Also the ### Header Title header can have uppercase characters, but the (#header-title) markdown is all lowercase. And had a comma which was encoded as %2C which I used in markdown like this (#header-title%2C-etc)Aberration
Worth noting, it's supported in Doxygen Markdown as wellVasileior
S
26

For anyone who is looking for a solution to this problem in GitBook. This is how I made it work (in GitBook). You need to tag your header explicitly, like this:

# My Anchored Heading {#my-anchor}

Then link to this anchor like this

[link to my anchored heading](#my-anchor)

Solution, and additional examples, may be found here: https://seadude.gitbooks.io/learn-gitbook/

Stepparent answered 23/1, 2019 at 21:14 Comment(1)
Works like a charm, but as i just found out the anchor should be lower case only, otherwise it won't workWhich
M
17

There's no readily available syntax to do this in the original Markdown syntax, but Markdown Extra provides a means to at least assign IDs to headers — which you can then link to easily. Note also that you can use regular HTML in both Markdown and Markdown Extra, and that the name attribute has been superseded by the id attribute in more recent versions of HTML.

Madge answered 16/3, 2011 at 0:50 Comment(0)
S
12

Late to the party, but I think this addition might be useful for people working with rmarkdown. In rmarkdown there is built-in support for references to headers in your document.

Any header defined by

# Header

can be referenced by

get me back to that [header](#header)

The following is a minimal standalone .rmd file that shows this behavior. It can be knitted to .pdf and .html.

---
title: "references in rmarkdown"
output:
  html_document: default
  pdf_document: default
---

# Header

Write some more text. Write some more text. Write some more text. Write some more text. Write some more text. Write some more text. Write some more text. Write some more text. Write some more text. Write some more text. Write some more text. 

Go back to that [header](#header).
Sloth answered 27/10, 2016 at 7:32 Comment(0)
D
9

As we see (from the answers), there is no standard way for this; and different markdown processors would differ in their markdown extensions that offer this kind of possibilities.

With pandoc, you can get what you asked for like this:

Take me to [pookie](#pookie)

...

[this is pookie]{#pookie}

This gives (with pandoc-2.9.2.1):

<p>Take me to <a href="#pookie">pookie</a></p>
<p>…</p>
<p><span id="pookie">this is pookie</span></p>

One can also make an empty span with an anchor id:

Take me to [pookie](#pookie)

...

this is pookie []{#pookie}

which would produce:

<p>Take me to <a href="#pookie">pookie</a></p>
<p>…</p>
<p>this is pookie <span id="pookie"></span></p>

Apart from this, for pandoc and for most common markdown generators, you have a simple self generated anchor in each header. (See that and other answers here for convenient ways to (auto)generate and refernce such anchors.)

Dannielledannon answered 10/11, 2020 at 20:59 Comment(0)
A
7

For most common markdown generators. You have a simple self generated anchor in each header. For instance with pandoc, the generated anchor will be a kebab case slug of your header.

 echo "# Hello, world\!" | pandoc
 # => <h1 id="hello-world">Hello, world!</h1>

Depending on which markdown parser you use, the anchor can change (take the exemple of symbolrush and La muerte Peluda answers, they are different!). See this babelmark where you can see generated anchors depending on your markdown implementation.

Androcles answered 26/11, 2016 at 18:24 Comment(2)
@imz -- Ivan Zakharyaschev, I've rolled back your edit. It was a really different writing and hard for me to understand the point. The goal of this answer is mostly to link to babelmark and hint that there are plenty solution and answer should not focus on a specific implementation... Maybe commeting your point is a good idea though :)Androcles
Yes, that's OK. Maybe I'll write it down separately.Dannielledannon
F
7

Using the latest Markdown, you should be able to use the following syntax:

[](){:name='anchorName'}

This should create the following HTML:

<a name="anchorName"></a>

If you wanted the anchor to have text, simply add the anchor text within the square brackets:

[Some Text](){:name='anchorName'}

Fiscal answered 22/6, 2017 at 21:57 Comment(4)
It seems like only Maruku knows about this syntax. See the babelmark.Androcles
Does not work in VS CodeLourielouse
There is no such thing as "the latest markdown". There are various implementations/dialects of it.Cherub
Inspired by this and michelf.ca/projects/php-markdown/extra/#spe-attr, I have this working in VSCode by adding {#anchor_name} at the EOL where I want to create it, then reference it with [link name](#anchor_name). Note that I have, among others, the Markdown extended extension installed.Cacomistle
A
5

For anyone who likes to use headers with different levels, it's useful to note that the link to the header should only ever use a single #, regardless of the header's level:

# This is an H1
## This is an H2
### This is an H3
...
[Take me to H3](#this-is-an-H3)
[Take me to H1](#this-is-an-H1)
[This won't work](##-this-is-an-H2)
Amosamount answered 11/11, 2022 at 9:42 Comment(0)
R
3

I will quickly complement for cases where the header contains emojis, in that case it is simpler to just remove the emoji in the link of the reference. For example

# ⭐ Title 2
....
[Take me to title 2](#-title-2)

There are some cases where this does not work for a weird reason, for example here in setup. The solution in that case is to include the whole code for the emoji as well.

Rooker answered 13/7, 2020 at 5:53 Comment(0)
S
2

Special case not covered in the other answers:

If your heading has parentheses, just ignore them from your hyphen-separated key.

Example:

## My paragraph title (MpT)


[Some text](#my-paragraph-title-mpt)

At least, this works in Visual Studio Code rendered.

Socialite answered 2/4, 2023 at 21:54 Comment(0)
M
1

This example of a table of contents final view

https://i.stack.imgur.com/zUcXt.png

This code to how to produce the table of contents above

https://i.stack.imgur.com/yCxId.png

cell

## Table of Contents
<ul>
<li><a href="#intro">Introduction</a></li>
<li><a href="#wrangling">Data Wrangling</a></li>
<li><a href="#eda">Exploratory Data Analysis</a></li>
<li><a href="#conclusions">Conclusions</a></li>
</ul>

cell

<a id='intro'></a>
### Introduction

cell

<a id='wrangling'></a>
### Data Wrangling

cell

<a id='eda'></a>
### Exploratory Data Analysis

cell

<a id='conclusions'></a>
### Conclusions
Mississippian answered 19/3, 2023 at 10:48 Comment(0)
F
0

About special characters

Not sure it applies to all MarkDown processors, but special characters (including accented letters) as well as suites of special characters may be replaced by a single hyphen :

# L’insoutenable légèreté de l’Être

will give

#l-insoutenable-l-g-ret-de-l-tre

Suffixing

Some processors will add a suffix to prevent conflicts :

# Foobar
## Foobar
### Baz
### Foobar
# Foobar

will give

#foobar-1
#foobar-2
#baz-1
#foobar-3
#foobar-4
Fetishist answered 18/7, 2023 at 12:16 Comment(0)
T
0

The name attribute fails for me. Using id works in Markdown.

Jump to [Header Below](#apples).
...
<a id="apples"></a>Blah blah blah...
Techno answered 31/12, 2023 at 6:44 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.