Hi, I'm Yaakov Chaikin. I teach grad web development at Johns Hopkins University and on Coursera.org.
By day, I am a software developer.
thumbnail for article on Creating Internal & External HTML Links

Creating Internal & External HTML Links

8 min read |
| by Yaakov Chaikin

This article is part of the Beginner Web Developer Series. The series is targeted to people who’d like to start serious web development, as well as people who are already web developers and want to solidify their knowledge of fundamentals while possibly filling in some holes. If you find yourself tinkering with HTML, CSS, or Javascript until you sort of get it to work, this series is for you. The material in this series is closely tied to my top-rated Coursera course.

Links are pretty much what makes the web what it is: one thing connected to another.

Specifically, in the case of HTML, one piece of content connected to another piece of content.

Let’s start with fragment identifier links.

Traditionally, fragment identifier links are those clickable items in your page that do not require the browser to request anything new from the server. These links allow users to jump to certain targeted sections of your web page.

There are two steps to creating such links: marking something as a possible target of a link and creating the link to that target.

The modern HTML way of marking content as a possible target of a link is to assign an id attribute to the element that wraps that content.

As you know by now, the value of an id attribute of any element within a single HTML page must be unique. Therefore, assigning an id attribute to an element with a unique value creates a unique target name as well.

For example, <section id="area51">...</section> would create a unique target name, provided you don’t have any other element with the id equal to area51. If you have another element in the HTML page with the same id value, the HTML itself is already invalid.

Once we have a targetable element, we can create a link that, once clicked, will instruct the browser to scroll/jump the page to that element.

We do this with the help of the <a> tag and its href attribute. (href stands for hypertext reference.)

The value of the href attribute has to be the value of the target we specified in the previous step, prepended with a # character.

For example, to target <section id="area51">...</section>, our link will look like this:

<a href="#area51">Link to the secret Area 51</a>

Note that the browser will display the words Link to the secret Area 51 as the content the user can click.

Once the user clicks the link, the browser will scroll/jump the page and attempt to position the content wrapped with the target element at the top of the page.

Let’s take a look at a complete example below (links-same-page.html):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
<!doctype html>
<html>
<head>
  <meta charset="utf-8">
  <title>Links</title>
</head>
<body>
  <header>
      Lorem ipsum ...
  </header>
  <h1 id="top">Links to Sections of The Same Page</h1>
  <section>
    <ul>
      <!-- Link to every section in the page -->
      <li><a href="#section1">#section1</a></li>
      <li><a href="#section2">#section2</a></li>
      <li><a href="#section3">#section3</a></li>
      <li><a href="#section4">#section4</a></li>
      <li><a href="#section5">#section5</a></li>
    </ul>
  </section>

  <section id="section1">
    <h3>(#section1) Section 1</h3>
    <p>Lorem ipsum ...</p>
  </section>

  <section id="section2">
    <h3>(#section2) Section 2</h3>
    <p>Lorem ipsum ...</p>
  </section>
  <section id="section3">
    <h3>(#section3) Section 3</h3>
    <p>Lorem ipsum ...</p>
  </section>
  <section id="section4">
    <h2>(#section4) Section 4</h2>
    <p>Lorem ipsum ...</p>
  </section>
  <section id="section5">
    <h2>(#section5) Section 5</h2>
    <p>Lorem ipsum ...</p>
    <p>
      <a href="#top">Back to Page Heading</a> or
      <a href="#">Back to Top of Page</a>
    </p>
  </section>
</body>
</html>

(Obviously, I truncated some of the content with ..., assuming you don’t like reading lorem ipsum text. 😜)

Clicking on any of the links at the top of the page jumps the page to the targeted section, as shown below. Also, note that the browser tries to position the target section at the top of the window. However, if there is not enough content to fill the rest of the window below, the target section will not move up any further.

Animated gif showing jumping to section, one that scrolls it to the top of the window and one that doesn't have enough content to place it at the top of the window

At the very bottom of our page, we have 2 links: one with href="#top" and another with href="#".

The first one is no different than our section links. Its target is the <h1 id="top"> tag content, positioned somewhere closer to the top of the document.

The second one, with the attribute href="#", is called an empty fragment since there is no target specified after #. Clicking on the link with the empty fragment will scroll/jump the browser to the very top of the page, as shown below.

Animated gif showing jumping to h1 first and then jumping to the top of the document with empty fragment link

Let’s take a look at an example of an external link code below (links-external.html):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<!doctype html>
<html>
<head>
  <meta charset="utf-8">
  <title>Links</title>
</head>
<body>
  <h1 id="top">External Links</h1>
  <section>
    <p>
      Let's link to a Facebook Fan page I created
      for this course!
      <!-- link to Facebook page WITH TARGET-->
      <a href="http://www.facebook.com/CourseraWebDev" 
      target="_blank" title="Like Our Page!">
        Course Facebook Page
      </a>
    </p>
  </section>
</body>
</html>

There is really nothing special about external links, other than their href value usually starts with http://. This is because it’s usually the case that external links point to a web page that’s hosted on a different domain name than the page which hosts the pointing link.

(External links can also point to other web applications hosted using the same domain name. While those web applications use the same domain name, they are configured under a different context. I’ll explain the idea of web application context in a different article.)

The target Attribute

There is another attribute of the a element that’s important to be aware of and use in conjunction with external links. That’s the target attribute.

When the value of the target attribute is set to _blank, it forces the browser to open the link in another browser tab or another browser window.

Let’s see how that link behaves in the browser:

Animated gif showing clicking on external link and browser opening a new tab

As you can see, another tab is opened when the user clicks on the link.

The reason that your external links should have target="_blank", at least most of the time, is as follows.

Unfortunately, nowadays, people have a very short attention span.

Hold on, what was I talking about?

Oh, right. Links. 🤣

If you don’t force the browser to display the content external to your site in a new tab or window, the user may click on the link and never come back to your site.

Did you ever get on the computer to check on an upcoming snow storm and then wake up an hour later browsing video recording gear on Amazon?

Yeah, me neither. 🙄

However, if the browser is forced to open an external page in a new tab, even if the user forgets all about the site they came from, it will still be there as one of the remaining opened tabs. There is a much higher chance they will come back once they are done with the external site.

Unless your site exists solely as a convenience to point users to other sites, you should always code all your external links with target="_blank".

An HTML Comment!

Coincidentally, take a look at the line of code right above the link we are discussing that looks like this:

<!-- link to Facebook page WITH TARGET-->

That’s an HTML comment. While this line will still be loaded into your browser when you view the page, the browser never displays or takes into account anything in between the starting <!-- and ending -->.

HTML comments don’t affect the structure of the page in any way.

By the way, the link in the example is to the Facebook page that I use to reach any and all of my students. It’s called CourseraWebDev. Click the link. It’s external and will open up another tab. Please click and like 👍 the page!

See what I did there? 😊

Fragment identifier links are certainly not limited to pointing at targets within the same web page.

You can, just as easily, create an external link to a web page, adding the fragment identifier to the end of the external URL.

For example, take a look at the following link:

https://html.spec.whatwg.org/dev/links.html#links-created-by-a-and-area-elements

If you click on that link here, you will see that it opens up a new tab and takes you directly to the section of the page with the subtitle of “Links created by a and area elements”.

Of course, if you want other external sites to link to a section of your page, you’d better create some way for the users to get the URL with the fragment identifier.

In this case, the WHATWG page provided a convenient § symbol next to the title. That’s a very common symbol to indicate that it contains the link to the section it’s next to.

Obviously, you need to allow the user to easily navigate within your own site. You do that by providing internal links.

Internal links are those that point to other web pages (and other type of resources) that are part of the same web application.

Since the other pages that are part of the same web application are hosted using the same domain name, there is usually no need to use absolute URLs for the href attribute value.

I plan to devote another post on the absolute, relative, URI, URL, etc. topic. For now, just know that an absolute URL refers to a URL that includes the domain name and a relative URL does not.

For example, an absolute URL to the about page of this site would be the following:

<a href="https://clearlydecoded.com/about">...

While a relative link to the same page would look like this:

<a href="/about">...

Let’s take a look at the following example (links-internal.html):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<!doctype html>
<html>
<head>
  <meta charset="utf-8">
  <title>Internal Links</title>
</head>
<body>
  <h1>Internal Links</h1>
  <section>
    We can link to a file in the same directory
    as this HTML file like this:
    <a href="same-directory.html" title="same dir link">
       Linking to a file in the same directory
    </a>

    <a href="same-directory.html" title="same dir link">
      <div> 
        DIV Linking to a file in the same directory
      </div>
    </a>
  </section>
</body>
</html>

As you can see, all the links in the page are relative URL links. Since the href attribute value only includes the name of the file, without specifying a directory name in the path, the browser will assume that the same-directory.html file is located in the same directory as the containing page (links-internal.html).

It’s also a good idea to always specify the title attribute for the <a> tag as I did in this document. The value of the title attribute is used by programs, called screen readers. Screen readers help visually impaired people to get through the page by automatically reading the contents of the page out loud.

Is a Inline or Block-Level Element?

Note the second link in our example (links-internal.html). The content of the link, or the <a> tag, is a <div> tag.

As I explained previously, an inline element can not contain a block-level element as part of its content.

So, assuming my code is valid, does this tell us that the a element is a block-level one?

Let’s take a look at this HTML page in the browser.

The a tag behaves like an inline element, but can contain block-level elements

As previously discussed, a block-level element always insists on being displayed on its own line. Yet, we see that the first link is happily sharing the line with other surrounding content.

So, it gets rendered as an inline element, yet it’s ok for it to include a block-level element?

Yep. Why? Here is why:

WHATWG description of the type of content a element can contain

As you can see, the a element belongs to both: Flow content and Phrasing content models.

(See this article if you don’t know what that is.)

In the previous versions of HTML, the a element used to be a strictly inline element. This presented a problem because, very often, we’d want to wrap a whole block of content and make it a clickable link.

For example, users expect that clicking on the logo of the site (somewhere at the top) should take them to the home page. Very often, the logo of the site isn’t simply an image, but a somewhat complex structure of block-level elements.

Developers used to have to come up with all kinds of hacks in order to achieve that functionality. In modern HTML, this was fixed by including the a element as part of both the Flow content and Phrasing content models.

Summary

Let’s give a quick summary of what we’ve covered in this article:

  • Fragment identifier links allow users to jump to predefined targeted sections of the web page
  • Mark content as a target by giving a unique id to the element that wraps it
  • Link to marked target by specifying <a href="#value-of-targeted-id">...</a>
  • Links to external sites are hosted on a different domain and therefore usually start with http://
  • Use target="_blank" to force the browser to open external content in a separate tab
  • The a element belongs to both the Flow and Phrasing content models
  • By itself, the a element is rendered as an inline element, but it can still contain block-level elements

Resources

Questions?

If something is not clear about what I wrote in this article, please ask away in the comments below!