Text fragments
==============

**Text fragments** allow linking directly to a specific portion of text in a web document, without requiring the author to annotate it with an ID, using particular syntax in the URL fragment. Supporting browsers are free to choose how to draw attention to the linked text, e.g. with a color highlight and/or scrolling to the content on the page. This is useful because it allows web content authors to deep-link to other content they don't control, without relying on the presence of IDs to make that possible. Building on top of that, it could be used to generate more effective content-sharing links for users to pass to one another.

Concepts and usage
------------------

Historically, one of the web's key features has always been its ability to provide links between different documents — it is what makes *the web*, a web:

* You can link to the top of a document by linking to its URL, for example:
    + https://developer.mozilla.org/en-US/docs/Web/HTML/Element/a.
* You can link to a specific section of a document by linking to its URL plus the *document fragment* (ID) of that section, for example:
    + https://developer.mozilla.org/en-US/docs/Web/HTML/Element/a#browser\_compatibility.

The issue with linking to specific document fragments is that the author of the linked page needs to put an anchor in place to *actually* link to. The second example above links to an h2 element with an ID of `browser_compatibility`:


```html
<h2 id="browser\_compatibility">
  <a href="#browser\_compatibility">Browser compatibility</a>
</h2>
```


If the ID is changed or removed, the document fragment is ignored, and the link just links through to the top of the page. This is reasonable in terms of graceful degradation, but it would arguably be better if the author of the link had full control over where they link to, without needing to rely on the page author.

**Text fragments** make this a reality — they allow link authors to specify text content to link to, rather than document fragments, in a flexible manner.

Syntax
------

In a similar manner to document fragments, text fragments are appended onto a URL after a hash symbol (`#`). The syntax however is a bit different:


```url
https://example.com#:~:text=[prefix-,]textStart[,textEnd][,-suffix]
```


The key parts to understand are as follows:

`:~:`

Otherwise known as *the fragment directive*, this sequence of characters tells the browser that what comes next is one or more user-agent instructions, which are stripped from the URL during loading so that author scripts cannot directly interact with them. User-agent instructions are also called directives.

`text=`

A text directive. This provides a text fragment to the browser, defining what text is to be linked to in the linked document.

`textStart`

A text string specifying the start of the linked text.

`textEnd` Optional

A text string specifying the end of the linked text.

`prefix-` Optional

A text string followed by a hyphen specifying what text should precede the linked text. This helps the browser to select the correct linked text, in cases where there are multiple matches.

`-suffix` Optional

A hyphen followed by a text string specifying what text should follow the linked text. This helps the browser to select the correct linked text, in cases where there are multiple matches.

Supporting browsers will scroll to and highlight the first text fragment in the linked document that matches the specified directive. Note that it is possible to specify multiple text fragments to highlight in the same URL by separating them with ampersand (`&`) characters.

### Usage notes

* Text strings used for the `textStart`, `textEnd`, `prefix-`, and `-suffix` values need to be percent-encoded.
* Matches are case-insensitive.
* Individual `textStart`, `textEnd`, `prefix-`, and `-suffix` strings need to reside wholly inside the same block-level element, but complete matches can span across multiple element boundaries.
* For security reasons, the feature requires links to be opened in a noopener context — you need to add `rel="noopener"` to your `<a>` elements, and add `noopener` to your `window.open()` calls when using this feature.
* Text fragments are invoked only on full (non-same-page), user-initiated navigations.
* Text fragments are only applied to the main frame; text will not be searched inside `<iframe>`s, and `iframe` navigation will not invoke a text fragment.
* For sites that wish to opt-out, Chromium-based browsers support a Document Policy header value that they can send so user agents will not process Text Fragments:

```http
Document-Policy: force-load-at-top
```


**Note:** If the provided text fragment does not match any text in the linked document, or if the browser does not support text fragments, the whole text fragment is ignored and the top of the document is linked.

Examples
--------

### Simple text fragment with textStart

* https://example.com#:~:text=for scrolls to and highlights the first instance of the text `for` in the document.
* https://developer.mozilla.org/en-US/docs/Web/HTML/Element/a#:~:text=human scrolls to and highlights the first instance of the text `human` in the document.
* https://developer.mozilla.org/en-US/docs/Web/HTML/Element/a#:~:text=linked%20URL scrolls to and highlights the first instance of the text `linked URL` in the document.
### textStart and textEnd

* https://developer.mozilla.org/en-US/docs/Web/HTML/Element/a#:~:text=human,URL scrolls to and highlights the first instance of a text string starting with `human` and ending with `URL`.
* https://developer.mozilla.org/en-US/docs/Web/HTML/Element/a#:~:text=linked%20URL,defining%20a%20value scrolls to and highlights the first instance of a text string starting with `linked URL` and ending with `defining a value`. Note how the highlighted text spans across multiple block-level elements.
### Examples with prefix- and/or -suffix

* https://example.com#:~:text=asking-,for scrolls to and highlights the second instance of the text `for` in the document.
* https://developer.mozilla.org/en-US/docs/Web/HTML/Element/a#:~:text=sent-,referrer scrolls to and highlights the first instance of the text `referrer` that has the text `sent` directly before it. This is the 5th instance of `referrer` in the document; without the prefix, the first instance would be highlighted.
* https://developer.mozilla.org/en-US/docs/Web/HTML/Element/a#:~:text=linked%20URL,-'s%20format scrolls to and highlights the first instance of the text `linked URL` that has the text `'s format` directly following it. This is the 5th instance of `linked URL` in the document; without the suffix, the first instance would be highlighted.
* https://developer.mozilla.org/en-US/docs/Web/HTML/Element/a#:~:text=downgrade:-,The%20Referer,be%20sent,-to%20origins scrolls to and highlights the instance of the text `The Referer ... be sent` that is prefixed by `downgrade:` and suffixed by `to origins`. This illustrates a more complex example where the prefix/suffix are used to home in on the specific text instance you want to link to. Try removing the prefix, for example, and seeing what is matched.
### URLs with multiple text fragments

You can specify multiple text fragments to highlight in the same URL by separating them with ampersand (`&`) characters. Let's look at a couple of examples:

* https://developer.mozilla.org/en-US/docs/Web/HTML/Element/a#:~:text=Causes&text=linked scrolls to and highlights the first instances of the text strings `Causes` and `linked`.
* https://developer.mozilla.org/en-US/docs/Web/HTML/Element/a#:~:text=linked%20URL,-'s%20format&text=Deprecated-,attributes,attribute scrolls to and highlights two text instances:
    + The first instance of the text `linked URL` that has the text `'s format` directly following it.
    + The first instance of a text string starting with `attributes` and ending with `attribute`, which is prefixed by `Deprecated`.

If you don't see one or more of your text fragments highlighted and you are sure you've got the syntax correct, you might just be highlighting a different instance than the one you expected. It might be highlighted, but offscreen.

### Styling matched text fragments

Browsers are free to style the highlighted text in whatever default way they choose. The CSS Pseudo-Elements Module Level 4 defines a pseudo-element, `::target-text`, which allows you to specifying custom styling.

For example, in our scroll-to-text demo we have the following CSS:


```css
::target-text {
  background-color: rebeccapurple;
  color: white;
}
```


Try following the above link in a supporting browser to see the effect this has.

### Feature Detectability

The `FragmentDirective` object, which is accessed via the `Document.fragmentDirective` property, can be used to test whether or not text fragments are supported in a browser.

Try running the following in a supporting browser's devtools, in a tab with one or more matched text fragments:


```js
document.fragmentDirective;
// returns an empty FragmentDirective object, if supported
// undefined otherwise
```


This functionality is mainly intended for feature detection at present. In the future, the `FragmentDirective` object could include additional information.

Reference
---------

### API

`FragmentDirective`

An object representing the text fragments. Currently empty and mainly intended for feature detection.

`Document.fragmentDirective`

Returns the `FragmentDirective` for the current document.

### CSS

`::target-text`

Represents the highlighted text fragments in the current document. It allows authors to customize the styling of text fragments.

Specifications
--------------

| Specification |
| --- |
| URL Fragment Text Directives # fragmentdirective |
| CSS Pseudo-Elements Module Level 4 # selectordef-target-text |

Browser compatibility
---------------------

### html.elements.a.text\_fragments

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

### api.FragmentDirective

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

### css.selectors.target-text

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

See also
--------

* Boldly link where no one has linked before: Text Fragments