What does the HTML <base href="..."> element change on a page, and why must it appear before any other element carrying a URL?
answer
- relative URLs need something to resolve against
- one global switch for the whole document
- resolution happens as the parser reaches each element
- only the first one is honoured
- even #anchor links go through it
basics
~20 ssolid answer
~50 s`<base href="/app/">` in `<head>` replaces the document's own URL as the base for resolving *every* relative URL in the document: `href` on links, `src` on images and scripts, `action` on forms, `url()` inside an inline `<style>`. Only the **first** `<base>` element with an `href` in tree order has any effect; later ones are ignored. The ordering rule follows from how parsing works — a `<link href="app.css">` that the parser reaches *before* the `<base>` is resolved right there against the document URL, so a `<base>` placed after it silently applies to some resources and not others. Put it first, immediately after the encoding declaration. The attribute that bites people is fragments: with a base set, `href="#section"` resolves against the base URL, not the current page, so an in-page anchor can navigate away. `<base target="_blank">` separately sets the default target for links and forms.
code
html · 13 lines<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<base href="https://cdn.example.com/v2/">
<title>Guide</title>
<link rel="stylesheet" href="app.css">
</head>
<body>
<a href="intro.html">Intro</a>
<a href="#top">Back to top</a>
</body>
</html>go deeper
Know that <base href> sets the starting point for relative URLs in a page and that it lives at the top of <head>. Being able to trace one relative link to its absolute result is enough here.
Explain the reach — links, images, scripts, form actions, inline style url() — plus the first-element-wins rule and why parse order forces the tag to come before any element with a URL.
Recognise the failure it causes in the field: fragment links navigating away, assets split across two bases, a duplicate tag from a template partial. Be able to say why root-relative paths are the safer default.
Frame it as an API-surface decision: a global URL switch touches markup authored by every team in the codebase, so if it exists at all it belongs in one owned template with an explicit rationale, never as a per-page convenience.
## What a base URL is Every relative URL in a document has to be resolved against something. By default that something is the document's own URL: on `https://example.com/docs/guide.html`, `href="intro.html"` resolves to `https://example.com/docs/intro.html`. The `<base>` element replaces that reference point for the whole document. ```html <head> <meta charset="utf-8"> <base href="https://cdn.example.com/v2/"> <title>Guide</title> <link rel="stylesheet" href="app.css"> <!-- https://cdn.example.com/v2/app.css --> </head> ``` ## Its reach is total The base URL is not scoped to links. It governs every relative reference the document makes: `<a href>`, `<img src>` and `srcset`, `<script src>`, `<link href>`, `<form action>`, `<iframe src>`, and `url()` values inside an inline `<style>` block. (Relative URLs inside an *external* stylesheet are unaffected — those resolve against the stylesheet's own URL, not the document base.) That totality is the reason `<base>` is rare in modern code. It is a single global switch with no opt-out: you cannot mark one link as "resolve against the real page URL". Any URL that needs the original base must be written out in full. ## The fragment trap The most-reported surprise is in-page anchors: ```html <base href="https://example.com/app/"> ... <a href="#pricing">Pricing</a> ``` `#pricing` is a relative URL like any other, so it resolves to `https://example.com/app/#pricing`. If the user is currently on `https://example.com/app/settings`, clicking that link is a **navigation** to a different page, not a scroll within the current one. Skip-links, table-of-contents links and `aria-controls`-style anchor patterns all break this way, and the failure is easy to miss in testing because it looks correct on the one page whose URL happens to equal the base. ## Why position matters HTML is parsed top to bottom, and a URL is resolved when the element carrying it is processed. If `<base>` comes after a `<link rel="stylesheet" href="app.css">`, that stylesheet has already been resolved against the document URL and the request may already be in flight thanks to the pre-load scanner. The result is a document where some URLs used one base and some used another — a bug that is genuinely hard to read from the markup. The rule is simple: `<base>` goes at the top of `<head>`, after `<meta charset>` and before anything with an `href` or `src`. The spec reinforces this by ignoring all but the **first** `<base href>` in the document. A second one, perhaps injected by a template partial, does nothing at all — which is its own confusing debugging session. ## The target attribute `<base target="_blank">` sets the default browsing context for every link and form submission that does not specify its own `target`. As a blanket default this is almost always a poor idea: opening every link in a new tab takes navigation control away from the user, and each individual link is easier to reason about with its own explicit `target`. As with `href`, only the first `<base target>` counts. ## When it is actually useful The legitimate cases are narrow: a document that will be served or saved under several URLs and must keep resolving assets against one canonical location; an HTML email template or exported document opened from disk; some older client-side routers that wanted a fixed base path. In an ordinary application, expressing paths as root-relative (`/assets/app.css`) achieves the same predictability with none of the global side effects. ## What an interviewer is checking Whether you understand *URL resolution as a parse-time operation* rather than a magic setting. The ordering rule, the single-element rule and the fragment trap all fall out of that one idea, and a candidate who has it can derive all three on the spot.
- Does <base href> also affect relative url() values inside an external stylesheet?No. URLs in an external stylesheet resolve against that stylesheet's own URL, which is the behaviour you want — a CSS file stays portable regardless of which document loads it. The document base does apply to `url()` values inside an inline `<style>` block in the HTML, since those are part of the document.
- What happens if a page contains two <base> elements with href attributes?Only the first in tree order is used; the second is ignored entirely. That makes a duplicate injected by a template partial hard to spot, because the markup reads as though the later value wins and the browser behaves as though it does not exist.
- Why do teams usually prefer root-relative paths over setting a <base>?Root-relative paths like `/assets/app.css` are explicit and local: you can read one line and know what it resolves to. A `<base>` acts globally on every URL in the document with no per-element opt-out, so it changes the meaning of markup written elsewhere in the file — including fragment links, which is where it most often causes bugs.
saying these in an interview costs you the question
- Thinks base only affects <a> links
- Assumes a later <base> overrides an earlier one
- Does not realise #fragment links resolve against the base
- Places <base> after stylesheet and script links
- Confuses base href with the canonical link element