---
title: Links
source: 'https://academia.sh/en/courses/web-fundamentals-and-html/links'
course: 'Web Fundamentals and HTML'
language: en
updated: '2026-08-17T18:09:31+00:00'
license: 'CC BY-SA 4.0'
---

# Links

Resolving relative and absolute addresses, determining the base address, the information link text carries, and link relationship declarations.

Lists grouped content, but the document is still closed in on itself. A link is the element
that connects a document to another resource, and it is what turns the web from a pile of
documents into a network.

The link element `a` declares its target with the `href` attribute. This lesson takes up how
that attribute's value is interpreted, what the text needs to carry, and the attributes that
declare the link's relationship to its target.

## Resolving the Address

The What the Browser Does lesson in the How the Internet Works course separated an address's
parts — scheme, host, port, path, query, fragment. The address written in a document most of
the time does not carry all of these parts; missing parts are completed from the **base
address**.

The base address is, by default, the document's own address. The resolution rule is defined
and gives the same result on every client.

```js
// links.mjs — resolving relative addresses against the base address
const base = "https://example.test/station/north-slope/measurements.html";

const candidates = [
  "log.html",
  "./log.html",
  "../summary.html",
  "../../index.html",
  "/about.html",
  "//other.test/data.json",
  "https://other.test/data.json",
  "?type=humidity",
  "#temperature",
  "data/2024.csv",
];

console.log("base:", base);
for (const candidate of candidates) {
  console.log(candidate.padEnd(28), "->", new URL(candidate, base).href);
}

console.log("--- the base element changes the base ---");
const newBase = new URL("/archive/", base).href;
console.log("new base:", newBase);
console.log("log.html".padEnd(28), "->", new URL("log.html", newBase).href);
```

```
base: https://example.test/station/north-slope/measurements.html
log.html                     -> https://example.test/station/north-slope/log.html
./log.html                   -> https://example.test/station/north-slope/log.html
../summary.html              -> https://example.test/station/summary.html
../../index.html             -> https://example.test/index.html
/about.html                  -> https://example.test/about.html
//other.test/data.json       -> https://other.test/data.json
https://other.test/data.json -> https://other.test/data.json
?type=humidity               -> https://example.test/station/north-slope/measurements.html?type=humidity
#temperature                 -> https://example.test/station/north-slope/measurements.html#temperature
data/2024.csv                -> https://example.test/station/north-slope/data/2024.csv
--- the base element changes the base ---
new base: https://example.test/archive/
log.html                     -> https://example.test/archive/log.html
```

The output distinguishes five separate forms.

**Same-directory relative**: `log.html` and `./log.html` give the same result; the directory
the document sits in is the base. Note that the document's own name is dropped in resolution —
`measurements.html` is not part of the result.

**Parent-directory relative**: `../` goes up one directory on every repetition.

**Root-relative**: an address starting with `/` writes the path from the root; the host and
scheme come from the base. When the document moves within the directory tree, these addresses
do not change; relative ones do.

**Scheme-relative**: an address starting with `//` takes only the scheme from the base. Tying
the scheme to the document is not preferred, because it allows moving from an insecure context
to an insecure target; the scheme is written explicitly.

**Same-document relative**: addresses that carry only a query or a fragment keep the
document's own path. Fragment addresses in the form `#temperature` never go out onto the
network at all; the target is the element in the document carrying that identifier.

## Changing the Base Address

The `base` element, written in the head section, changes the base for every relative address
in the document.

```html
<head>
  <base href="/archive/">
</head>
```

The output's last section shows the effect: the same `log.html` value resolves to a different
address. This element is found at most once in a document and affects addresses written after
it; that is the reason it is written early.

Because its effect spreads across the whole document, this element is used carefully. It is
not a decision affecting one section, it is one affecting every relative address — including
fragment addresses in the document.

## Characters in the Address

An address is written with a limited character set. Characters outside this set — Turkish
letters, spaces — are converted to bytes with **percent-encoding**.

```js
// encoding.mjs — non-ASCII characters and spaces in an address
const base = "https://example.test/station/";
for (const candidate of ["ölçüm raporu.pdf", "veri/2024 mart.csv", "arşiv/kuzey-yamaç"]) {
  console.log(JSON.stringify(candidate), "->", new URL(candidate, base).pathname);
}
console.log("--- the host name is encoded with a separate rule ---");
console.log(new URL("https://ölçüm.test/veri").href);
```

```
"ölçüm raporu.pdf" -> /station/%C3%B6l%C3%A7%C3%BCm%20raporu.pdf
"veri/2024 mart.csv" -> /station/veri/2024%20mart.csv
"arşiv/kuzey-yamaç" -> /station/ar%C5%9Fiv/kuzey-yama%C3%A7
--- the host name is encoded with a separate rule ---
https://xn--lm-4ia2d6a.test/veri
```

Every `%XX` pair is one byte, and the bytes are produced with the rule defined in the
Character Encodings lesson; because the letter `ö` takes two bytes, it converts to two pairs.
A space becomes `%20`.

The last line shows that the host name is handled with a separate rule: the path portion is
written with percent-encoding, the host name with the ASCII representation stated in the What
Is a Domain Name lesson. The same address's two parts go through two separate encodings.

Writing file names with ASCII characters makes this conversion unnecessary and keeps the
address readable; it is not mandatory, but it keeps the address short in the source text.

## Link Text

A link's text should declare what the target is. The criterion for this is not the sentence
around it: screen readers present the links inside a document as a list, and the user scans
that list by looking at their text.

```html
<!-- carries no information once taken out of context -->
<p>For daily measurement files, <a href="/data/log">click here</a>.</p>

<!-- understandable on its own -->
<p>Measurements are published <a href="/data/log">as daily files</a>.</p>
```

In the second way of writing, the link text defines the target. Two links in the same document
carrying the same text but going to different targets is also a situation to avoid.

A link is for going to a resource, not for an action that does not leave the document — deleting
a record, submitting a form. The button element is used for actions; the distinction will be
covered in this topic's form lessons.

## The Target's Type and Relationship

The `download` attribute requests that the target be downloaded instead of displayed, and
optionally gives a file name. The `type` attribute declares the target's content type; it is
a hint, not binding.

The `rel` attribute declares the link's **relationship** to its target. Its values are
space-separated keywords, and each one is defined.

```html
<p>Raw data: <a href="/data/2024-03.csv" download type="text/csv">March records</a></p>

<p>The method is defined in the <a href="https://other.test/standard" rel="noopener external">
   measurement standard</a>.</p>
```

The `target="_blank"` attribute opens the target in a new context. Everywhere this attribute is
written, `rel="noopener"` is also written: it prevents the opened document from reaching, via
script, the document that opened it. Opening in a new context is itself a decision that
deserves review; it breaks the user's expectation of going back, and whether the document
expects this behavior cannot be told from it.

The `rel` attribute is not specific to the `a` element. The `link` element in the head section
uses the same attribute and declares resources related to the document — a style file, an
icon, the same document's version in another language, a paginated index's previous and next
pages. On both elements, `rel` is the declaration "this address is in this relationship with
me."

## In the Station Document

```html
<h2>Data Access</h2>
<p>Records are published <a href="data/">as daily files</a>. The measurement method
   <a href="../method.html">is shared across the network</a>. Raw data files can be
   downloaded as <a href="data/2024-03.csv" download type="text/csv">March records</a>.</p>
```

All three links are written as relative and depend on the document's place in the directory
tree. If the document moves, the `../method.html` link breaks; root-relative writing prevents
this break but makes it harder to publish the document at another root. The choice between the
two forms of writing is a decision about where the document will be published.

## Summary

- Relative addresses are resolved against a base address; the base is, by default, the
  document's own address, and the document's file name is dropped in resolution.
- There are five relative forms: same-directory, parent-directory, root-relative,
  scheme-relative, and same-document; fragment addresses never go out onto the network.
- The `base` element changes the base for every relative address in the document and is found
  at most once in a document.
- Link text should define its target even when taken out of context; screen readers present
  links as a list.
- The `rel` attribute declares the link's relationship to its target; on links that open in a
  new context, the `noopener` relationship is also declared.

## Next Step

At this point the document can connect to other resources. What is left is this topic's last
structure: two-dimensional data. Measurement records are not a list, they are a table — every
row has more than one field, and every field has a heading. The next lesson takes up table
elements and shows how a data cell's associated headings are computed.
