Fragment lab

Follow the links in the bar and watch three things: where the page scrolls, which section turns yellow, and what the address shows. In the embedded window on the course page there is no real address bar, and text fragments do not work inside a frame, so open this lab in a new tab to see everything.

1. Any id is a target

This section has id="ids", so #ids at the end of this page's address scrolls here. No other markup is needed: every element with an id on every page is already a place a link can point to.

A fragment link to the same page sends no request. The browser compares the new address with the current one, sees that only the part after the # changed, and scrolls. The server never sees the fragment at all, even when the whole page loads fresh from a typed address.

A fragment link does add an entry to the tab's history. After following a few links in the bar, press the back button and the page scrolls back through them in reverse order.

Back to the top

2. The :target selector

The yellow background and the bar on the left come from one CSS rule, section:target, which matches the element the fragment names. Only one element is the target at a time.

The sticky bar at the top would hide the start of each section, so each section has scroll-margin-block-start. The browser stops scrolling that far short of the element, and the heading stays in view.

Back to the top

3. Scroll, and sometimes focus

When the target can take focus, the browser focuses it. This section has tabindex="-1", so following #focus focuses the whole section and draws an outline around it, and a screen reader starts reading from here.

When the target cannot take focus, such as an ordinary section, the browser still moves the starting point for the Tab key. Follow #ids, then press Tab: focus moves to the "Back to the top" link at the end of that section, not to the bar at the top of the page.

Ids are case-sensitive. #Focus, with a capital F, matches nothing here: the page stays where it is and nothing is highlighted.

Back to the top

4. The old way: a name on an a

Before every element could carry an id, the target of a fragment was an empty a element with a name attribute. Browsers still honor it, after looking for an id first, but the attribute is obsolete. #legacy lands on the empty anchor at the start of this heading. The section does not turn yellow, because the anchor, not the section, is the target.

Back to the top

5. Fragments that are not ids

#nowhere names nothing on this page. The address changes and a history entry is added, but the page does not move.

#top is special. When no element has id="top", it scrolls to the very top of the page, and so does an empty fragment, an href of just #.

The two text fragment links reload this page with a different query and scroll to a phrase instead of an id. The first finds the first "the server never sees" on the page, in section 1; matching ignores case. The second highlights everything from "The yellow background" to "stays in view" in section 2, across two paragraphs. Neither phrase has any markup around it. Look at the readout: location.hash is empty, because the browser removes the :~:text= directive before the page's scripts can read it. The address bar may still show the whole link, directive and all, so it can be copied and shared again.

Back to the top