WasiLearn Code
HTML · Links, lists and images

Links: how one page reaches another

A page on its own is a document. Links are what turn a pile of documents into a web, and the element that does it is two letters long.

<a href="/menu.html">See the menu</a>

<a> is the anchor element. href — hypertext reference — is where it goes. The text between the tags is what the reader sees and clicks.

Leave out the href and you get something that still looks like an <a> in your markup but is not a link at all: it cannot be clicked, cannot be tabbed to, and announces nothing to a screen reader. An anchor without an href is just text.

Three kinds of destination

<a href="https://developer.mozilla.org/">MDN</a>
<a href="/about.html">About us</a>
<a href="menu.html">Menu</a>

Absolute URLs carry the whole address, protocol and all. Use them for other people's sites. Writing them for your own pages works, but bakes your domain into every link — painful the day you move to a new one, and irritating when you want to test on localhost.

Root-relative paths start with / and are resolved from the top of the site, so /about.html is correct from every page regardless of how deep it sits.

Relative paths are resolved from the folder holding the current page. menu.html means "the file called menu.html next to this one".

The counting rules — ../ to climb a level, and the case-sensitivity bug that only shows up after you deploy — are the whole of the paths lesson. Everything there applies to href exactly as it applies to src.

Jumping to a section on the same page

An href beginning with # points at an id on the current page:

<a href="#opening-hours">Opening hours</a>

<h2 id="opening-hours">Opening hours</h2>

Click it and the browser scrolls to that heading and puts it near the top. The #opening-hours also appears in the address bar, so the reader can copy a link that lands directly on that section.

Three things worth knowing:

  • The id must be unique on the page. Two elements with the same id and the browser jumps to the first, which may not be the one you meant.
  • href="#top" scrolls to the top of the document even without an element with that id. So does a bare href="#", which is why you see it used as a placeholder — and why a placeholder link is a bad idea, since it silently jumps the reader to the top when they click it.
  • You can link into another page's section by combining the two: href="/menu.html#drinks".

If the target heading ends up hidden behind a fixed site header after the jump, that is a CSS problem with a one-line CSS fix (scroll-margin-top), not something to solve in the markup.

Links that do something other than navigate

<a href="mailto:hello@example.com">Email us</a>
<a href="tel:+922112345678">Call the shop</a>
<a href="/menu.pdf" download>Download the menu</a>

mailto: opens the reader's mail client; tel: starts a call on a phone and usually does nothing useful on a desktop. Neither is spam-proof — a mailto: address in your HTML is readable by anything that reads your HTML.

download asks the browser to save the file rather than display it. It is a request, not a guarantee, and it only applies to files on your own origin.

target="_blank" and the attribute that has to come with it

target="_blank" opens the link in a new tab:

<a href="https://example.com" target="_blank" rel="noopener noreferrer">
  Example
</a>

That rel is not decoration. Historically, a page opened with target="_blank" received a JavaScript handle back to the page that opened it — window.opener — and could use it to navigate your tab somewhere else while the reader was looking at the new one. That is the "tabnabbing" trick, and it worked because the two pages did not need to be related in any way.

Modern browsers set rel="noopener" implicitly for target="_blank", so the hole is closed by default in anything current. Write it anyway: it costs nine characters, it documents the intent, and it still matters for older browsers. noreferrer additionally stops the destination learning which page sent the visitor.

Be sparing with _blank in the first place. It takes the back button away from the reader, and a new tab arriving unannounced is disorienting for someone using a screen reader or a magnifier. The defensible cases are a link away from a form someone is halfway through filling in, and documentation someone is meant to read alongside your page. "It keeps them on my site" is not one — it just leaves them with two tabs they did not ask for.

Link text is read out of context

This is the habit that separates a usable site from an exhausting one.

Screen reader users often navigate by pulling up a list of every link on the page and reading through it. That list has no surrounding sentences in it. So a page with six links reading "click here", "click here", "read more", "read more", "here", "link" is a page with no navigation at all.

<!-- says nothing on its own -->
<p>To see our opening times, <a href="/hours.html">click here</a>.</p>

<!-- says exactly what it is -->
<p>Our <a href="/hours.html">opening times</a> are on a separate page.</p>

The second version is shorter, reads better in the sentence, and survives being pulled out of it. That is the test: would this link text still make sense as a single line in a list?

The same applies to "read more" at the end of an article summary. If the design demands those words, put the meaning in the link and let CSS handle the rest: <a href="/post">Read more about the new route</a>.

While you are here: do not write "Link to" or "Click" in the text either. A screen reader already announces the element as a link, so "Link to opening times" is read as "link, link to opening times".

What a link should look like

Browsers underline links and colour them blue for a reason. That combination has meant "clickable" for thirty years, and it is the only styling that communicates it without any other cue.

If you remove the underline, you are relying on colour alone — and colour alone is invisible to a reader with colour blindness, and washes out on a phone in sunlight. Inside a block of prose, keep the underline. In a navigation bar, where position and grouping already say "these are links", removing it is fine.

Never make something look like a link when it is not, and never make a link look like plain text.

A small page, linked up

<nav>
  <a href="/">Home</a>
  <a href="/menu.html">Menu</a>
  <a href="/contact.html">Contact</a>
</nav>

<main>
  <h1>Chai Corner</h1>
  <p>
    We open at seven every morning. The full
    <a href="/menu.html">menu is here</a>, and the
    <a href="/menu.html#drinks">drinks section</a> lists everything by size.
  </p>
  <p>
    Recipes come from
    <a href="https://example.com/recipes" target="_blank" rel="noopener noreferrer">
      an old family collection
    </a>.
  </p>
</main>

Every link says what it is. Internal links are root-relative, so they survive a folder reshuffle. The one external link opens in a new tab and carries its rel.

Next: lists, which is where navigation like the above usually ends up, and where there is a nesting rule almost everyone gets wrong the first time. If a link is 404ing rather than reading badly, paths is the lesson you want.

Prefer learning with a teacher?

WasiLearn Academy runs small-group classes covering this material, online and in Karachi.

See the classes