• Stars
    star
    586
  • Rank 76,279 (Top 2 %)
  • Language
    HTML
  • License
    Other
  • Created almost 6 years ago
  • Updated 10 months ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Proposal to allow specifying a text snippet in a URL fragment

Text Fragments

Draft Spec
Web Platform Tests
ChromeStatus entry

Introduction

To enable users to easily link to specific content in a web page, we propose adding support for specifying a text snippet in the URL. When navigating to such a URL, the browser understands more precisely what the user is interested in on the destination page. It may then provide an improved experience, for example: visually emphasizing the text or automatically bringing it into view or allowing the user to jump directly to it.

Web standards currently specify support for scrolling to anchor elements with name attributes, as well as DOM elements with ids, when navigating to a fragment. While named anchors and elements with ids enable scrolling to limited specific parts of web pages, not all documents make use of these elements, and not all parts of pages are addressable by named anchors or elements with ids.

Current Status

This feature, as currently specified in this repo, is shipping to stable channel in Chrome M80.

Motivating Use Cases

When following a link to read a specific part of a web page, finding the relevant part of the document after navigating can be cumbersome. This is especially true on mobile devices, where it can be difficult to find specific content when scrolling through long pages or using the browser's "find in page" feature. Fewer than 1% of clients use the "Find in Page" feature in Chrome on Android.

To enable users to more quickly find the content they're interested in, we propose generalizing the existing support for scrolling to elements based on the fragment identifier. We believe this capability could be used by a variety of websites (e.g. search engine results pages, Wikipedia reference links), as well as by end users when sharing links from a browser.

Search Engines

Search engines, which link to pages that contain content relevant to user queries, would benefit from being able to scroll users directly to the part of the page most relevant to their query.

For example, Google Search currently links to named anchors and elements with ids when they are available. For the query "lincoln gettysburg address sources", Google Search provides a link to the named anchor #Lincolnโ€™s_sources for the wikipedia page for Gettysburg Address as a "Jump to" link:

Example "Jump to" link in search results

However, there are many pages with relevant passages with no named anchor or id, and search engines cannot provide a "Jump to" link in such cases.

Citations / Reference links

Links are sometimes used as citations in web pages where the author wishes to substantiate a claim by referencing another page (e.g. references in Wikipedia). These reference pages can often be large, so finding the exact passage that supports the claim can be very time consuming. By linking to the passage that supports their underlying claim, authors can make it more efficient for readers to follow their overall argument.

Sharing a specific passage in a web page

When referencing a specific section of a web page, for example as part of sharing that content via email or on social media, it is desirable to be able to link directly to the specific section. If a section is not linkable by a named anchor or element with id, it is not currently possible to share a link directly to a specific section.

Users may work around this by sharing screenshots of the relevant portion of the document (preventing the recipient of the content from engaging with the actual web page that hosts the content), or by including extra instructions to scroll to a specific part of the document (e.g. "skip to the sixth paragraph").

We would like to enable users to link to the relevant section of a document directly. Linking directly to the relevant section of a document preserves attribution, and allows the user following the URL to engage directly with the original publisher.

Proposed Solution

tl;dr

Allow specifying text as part of the URL fragment:

https://example.com#:~:text=prefix-,startText,endText,-suffix

Using this syntax

:~:text=[prefix-,]textStart[,textEnd][,-suffix]

         context  |-------match-----|  context

(Square brackets indicate an optional parameter)

Navigating to such a URL will cause the browser to indicate the first instance of the matched text. The exact details of what a browser should do once it finds a match are mostly beyond the scope of this proposal. Browsers are mostly free to choose what kind of UI to surface, whether or not to scroll the text into view on load, and how to visually emphasize it.

To restrict an attacker's ability to exfiltrate information across origins, several restrictions are applied on when such an anchor is activated. A user activation is required and consumed; text matching can only occur on word boundaries. Additionally, the fragment will activate only if the document is sufficiently isolated from other pages (is the only one in its browsing context group, e.g. no window.opener or iframes).

The text directive is delimited from the rest of the fragment using the :~: token to indicate that it is a fragment directive that the user agent should process and then remove from the URL fragment that is exposed to the page. The directive syntax solves the issue of compatibility with page that rely on the URL fragment for routing/state, see issue #15.

Background

We propose generalizing existing support for scrolling to elements as part of a navigation by adding support for specifying a text snippet in the URL. We modify the indicated part of the document processing model to allow using a text snippet as the indicated part. The user agent may then follow the existing logic for scrolling to the fragment identifier and/or apply other UI effects.

This extends the existing support for scrolling to anchor elements with name attributes, as well as DOM elements with ids, to scrolling to other textual content on a web page. Browsers first attempt to find an element that matches the fragment using the existing support for elements with id attributes and anchor elements with name attributes. If no matches are found, browsers then will process the text snippet specification.

Usability Goals

  • Users should be able to specify multiple, non-contiguous passages. There are two reasons this is important. The first is intrinsic; users sometimes want to emphasise multiple snippets of a larger text. Examples abound on Twitter.

    The second is to deal with complicated DOM cases where DOM order and text order doesn't align. A common example would be a column in a table, or a contiguous paragraph with an inline ad.

  • The user may wish to specify text that spans multiple paragraphs, list items, table entries, and other structures. Our proposal aims to allow users to target test crossing arbitrary DOM and visual boundaries.

  • The text the user wishes to target may not be unique on the page. The solution must account for this by providing ways to disambiguate multiple matches on a page.

  • Such links should be creatable for arbitrary pages across the web. This means they must be compatible with the vast majority of existing and future web sites.

Identifying a Text Snippet

Here's an example URL encoding some text to indicate on the destination page:

https://en.wikipedia.org/w/index.php?title=Cat&oldid=916388819#:~:text=Claws-,Like%20almost,the%20Felidae%2C,-cats

:~:text=[prefix-,]textStart[,textEnd][,-suffix]

         context  |-------match-----|  context

(Square brackets indicate an optional parameter)

Though existing HTML support for id and name attributes specifies the target element directly in the fragment, most other mime types make use of this x=y pattern in the fragment, such as Media Fragments (e.g. #track=audio&t=10,20), PDF (e.g. #page=12) or CSV (e.g. #row=4).

The text keyword will be used to identify a block of text that should be indicated. The provided text is percent-decoded before matching. Dash (-), ampersand (&), and comma (,) characters in text snippets must be percent-encoded to avoid being interpreted as part of the text fragment syntax.

The URL standard specifies that a fragment can contain URL code points, as well as UTF-8 percent encoded characters. Characters in the fragment percent encode set must be percent encoded.

There are two kinds of terms specified in the text directive: the match and the context. The match is the portion of text thatโ€™s to be indicated. The context is used only to disambiguate the match and is not highlighted.

Context is optional, it need not be provided. However, the text directive must always specify a match term.

Match

A match can be specified as either a single argument or as a pair.

If the match is provided using two arguments, the left argument is considered the starting snippet and the right argument is considered the ending snippet (e.g. text=_startText_,_endText_). In this case, the browser will perform a "range search" for a block of text that starts with startText and ends with endText. If multiple blocks match the first in DOM order is chosen (i.e. find the first occurrence of startText, from there find the first occurrence of endText). When a match is specified with two arguments, we allow highlighting text that spans multiple elements.

If the match is specified as a single argument, we consider it an "exact search" (e.g. text=_textSnippet_). The browser will highlight the first occurrence of exactly the textSnippet string. In this case, the specified text will be matched only if it is contained within a single node.

Range matches are useful when the desired text match is extremely long. For example, selecting multiple paragraphs of text using an exact match would result in a very long and cumbersome URL.

E.g. Given:
  • Text1
  • Text2
  • Text3
  • Text4

text=Text2,Text4 will highlight all items except the first:

  • Text1
  • Text2
  • Text3
  • Text4

text=Text2 will highlight just the second item:

  • Text1
  • Text2
  • Text3
  • Text4

Context

To disambiguate non-unique snippets of text on a page, arguments can specify optional prefix and suffix terms. If provided, the match term will only match text that is immediately preceded by the prefix text and/or immediately followed by the suffix text (allowing for an arbitrary amount of whitespace in between). Immediately preceded, in these cases, means there are no other text nodes between the match and the context term in DOM order. There may be arbitrary whitespace and the context text may be the child of a different element (i.e. searching for context crosses element boundaries).

If provided, the prefix must end (and suffix must begin) with a dash (-) character. This is to disambiguate the prefix and suffix in the presence of optional parameters. It also leaves open the possibility of extending the syntax in the future to allow multiple context terms, allowing more complicated context matching across elements.

If provided, the prefix must be the first argument to the text directive. Similarly, the suffix must be the last argument.

For example, suppose we want to perform the following highlight:

The highlighted text appears multiple times

Since the text โ€œUnited Statesโ€ is ambiguous, we must provide a suffix to disambiguate it:

text=United States,-Minnesota Timberwolves

Multiple Text Directives

Users can specify multiple snippets by providing additional text directives in the fragment directive, separated by the ampersand (&) character.

Each text= directive is considered independent in the sense that success or failure to match in one does not affect matching of any others. Each starts searching from the top of the document.

Only the left-most, successfully matched, directive will be the indicated part of the document (i.e. used as the CSS target, scrolled into view). That is, if โ€œfooโ€ did not appear anywhere on the page but โ€œbarโ€ does, we scroll โ€œbarโ€ into view. However, all matched directives will be visually indicated on the page.

For example:
example.com#:~:text=foo&text=bar&text=bas

will target each of โ€œfooโ€, โ€œbarโ€, and โ€œbazโ€ and use the โ€œfooโ€ result as the indicated part of the document, assuming all appear on the page.

Multiple terms can be useful when the desired text has unrelated inline elements like images, ads, tables, etc:

Highlighted text has an unrelated table inline

Users may also wish to emphasize multiple passages of a larger text. We've found many such examples online:

Example of an screenshot with multiple highlights

Fragment Directive

Some existing pages on the web use fragments for their own state/routing. These pages may break if an unexpected fragment is provided. See #15

Element-id based fragments also cause these pages to break; however, text fragments are much more likely to be user-generated and are thus more likely to cause unexpected breakage. Pages that rely on fragment routing are also unlikely to provide anchor points, whereas they are likely to have text.

Our solution to this is to introduce the concept of a fragment directive. The fragment directive is a specially-delimited part of the URL fragment that is meant for UA instructions only. It's stripped out from the URL during document loading so that it's completely invisible to the page.

This allows specifying UA instructions like a text fragment in a way that's guaranteed not to interfere with page script and ensures maximal compatibility with the existing web.

However, stripping arbitrary parts of a fragment may not be web compatible! We went through several ideas here:

The Double-Hash

We tried delimiting the fragment directive using ##. It's ergonomic and works well since, if the original URL doesn't have a fragment, the double-hash delimiter will already be parsed as a fragment!

However, # is not a valid code point in the URL spec. As was explained in a thread on the w3.org URI mailing list, some URL parsers parse from right to left. Having an additional # character will cause these parsers to break. Worse, we don't have a good way to measure the risk.

Use counters we added to Chrome in M77 showed that, on Windows, about 0.08% of page loads already have a # character in the fragment. While small, that's a non trivial percentage.

Enter :~:

A new delimiter would have to be both spec-compliant with the URL spec and have sufficiently low usage on the existing web such that this change would be web-compatible.

We assumed this would preclude any single or double character sequences and produced a list of candidates to consider:

  • !~!
  • !~~!
  • ~&~
  • :~:
  • ~@~
  • ~_~
  • _~_

We also considered using a more verbose delimiter:

  • &directive
  • @directive
  • $directive
  • /directive
  • -directive

Looking through links seen in the last 5 years by the Google Search crawler, we eliminated some of this list. None of the "verbose" list had been seen; however, given valid candidates in the first list, we prefered them for succinctness and to reduce English-centric keywords.

Of the above list, the following had never been seen in a URL fragment by the crawler:

  • ~&~ no hits
  • :~: no hits
  • ~@~ one hit

While this doesn't guarantee compatibility, it did give us some confidence. We chose :~: from this list somewhat arbitrarily. However, we've also added Chrome use-counters to M78 for all these delimiters. :~: is seen on fewer than 0.0000039% of page loads (or about 1 in 25 million) so we currently believe this is a safe choice.

Directives and Delimiters

When appending the :~: token to a URL, it must appear inside a fragment so a # must also be added:

https://example.com --> https://example.com#:~:text=foo

However, a URL with an existing fragment can simply be appended to:

https://example.com#fallback:~:text=foo

In this case, if the text match isn't found, the browser can fallback to scrolling the element-id specified in the fragment (e.g. id="fallback" in this case). Note that the text directive will always begin searching at the top of the document, even if a matching element-id fragment is provided.

Compatibility and Interop

User agents that haven't implemented this feature won't know how to process the fragment directive. Because it is part of the fragment, on most pages this will simply be processed as a non-existent fragment so the page will load scrolled to the top, as if a fragment weren't supplied. This is a graceful fallback.

A more risky scenario is apps that use the fragment for state and routing. In these cases, the page is using the fragment in an application-defined manner and adding any content to it impact how the page operates (this is one of the motivating cases for using the fragment delimiter for text=).

In the worst case, such a URL on an unimplementing UA may navigate to a broken page. However, most such pages we've seen handle this gracefully, e.g.:

https://groups.google.com/a/chromium.org/forum/#!topic/blink-dev/OOZIrtSPLeM:~:text=test

Is a Google Groups post with a directive appended. Loading it in an unimplementing UA displays an "The input is invalid." toast in the corner but the page otherwise loads as if without the directive. We expect many cases will behave similarly but the potential of more serious breakage does exist.

Note: the fragment directive behavior (stripping everything after and including the :~: delimiter from the fragment) can be implemented independently of the larger proposal.

Feature Detection and Future APIs

An author may wish to detect whether a UA has implemented support for text-fragments. This can be used by pages that generate such links to avoid generating fragment-directives for non-implementing UAs. It can also be used by libraries or authors to strip the fragment-directive from user or author generated links.

This proposal includes a new property on the document object:

document.fragmentDirective

Authors can check for the existence of this (currently empty) object to determine if a UA has implemented support for text-fragments.

This also serves as an extension point for future APIs. For example, we'd like to expose information about the text-fragments included in the URL so that authors can build functionality on it. See #128 for more details.

:target

For element-id based fragments (e.g. https://en.wikipedia.org/wiki/Cat#References), navigation causes the identified element to receive the :target CSS pseudo-class. This is a nice feature as it allows the page to add some customized highlighting or styling for an element thatโ€™s been targeted. For example, note that navigating to a citation on a Wikipedia page highlights the citation text: https://en.wikipedia.org/w/index.php?title=Cat&direction=prev&oldid=916388819#cite_note-Linaeus1758-1 The :target CSS pseudo-class can only apply to elements whereas a text snippet may only be a portion of the text in a node or span multiple nodes.

The :target pseudo-class is applied to the first common ancestor element that contains all the matching text, for the left-most matching text= directive.

Security Considerations

Some of the more detailed reasoning behind the security decisions is described in our security review doc

If an attacker can detect a side-effect of a successful match, this feature could be used to detect the presence of arbitrary text on the page. For example, if the UA scrolls to the targeted text on navigation, an attacker might be able to determine whether a scroll occurred by listening to network requests or using an IntersectionObserver from an attacker-controlled iframe embedded on the target page.

A related attack is possible if the existence of a match takes significantly more or less work than non-existence. An attacker can navigate to a text fragment directive and time how busy the JS thread is; a high load may imply the existence or non-existence of an arbitrary text snippet. This is a variation of a documented proof-of-concept.

UAs are free to determine how a successfully matched text fragment should be surfaced to the user based on their own assessment of how much risk certain actions present. For example, whether scrolling on navigation is likely to be detectable in enough cases.

To prevent brute force attacks from guessing important words on a page (e.g. passwords, pin codes), matches and prefix/suffix are only matched on word boundaries. E.g. โ€œrangeโ€ will match in โ€œmountain rangeโ€ but not in โ€œcolor orangeโ€ nor โ€œforest rangerโ€.

Word boundaries are simple in languages with spaces but can become more subtle in languages without breaks (e.g. Chinese). A library like ICU provides support for finding word boundaries across all supported languages based on the Unicode Text Segmentation standard. Some browsers already allow word-boundary matching for the window.find API which allows specifying wholeWord as an argument. We hope this existing usage can be leveraged in the same way.

Additionally, a text directive is invoked only if a user activation occurred and the loaded document is the only one in its browsing context group. The latter restriction is effectively requiring rel=noopener be specified on a navigation.

Visual emphasis is performed using a visual-only indicator (i.e. donโ€™t cause selection), styled by the UA and undetectable from script. This helps prevents drag-and-drop or copy-paste attacks.

Client-Side Redirects

Due to the prevelance of client-side redirects (i.e. loading a document that navigates via e.g. window.location), special care is taken to enable these scenarios, despite the fact they lack a user activation. See redirects.md for details.

Opting Out

For product reasons, or acute privacy restrictions, pages may wish to disallow scrolling to a text fragment (or regular fragment) on load, see #80. To allow websites to opt out of text fragments, we propose adding a Document Policy named force-load-at-top that ensures the page is loaded without any form of scrolling, including via text fragments, regular element fragments, and scroll restoration. Websites can use this document policy by serving the HTTP header:

Document-Policy: force-load-at-top

Alternatives Considered

Text Fragment Directive 0.1

A prior revision of this document contained a somewhat similar proposal. The main difference in the updated proposal is that it adds context terms to the text directive. This helps to allow disambiguating text on a page as well as brings this proposal more in-line with the Open Annotation's TextQuoteSelector. Many use cases and details were considered while iterating on the initial revision. The updated proposal is a sum of lessons learned and improved understanding as we experimented with and considered the initial version and its limitations

CSS Selector Fragments

Our initial idea, explored in some detail, was to allow encoding a CSS selector in the URL fragment. The selector would determine which element on the page should be the "indicated element" in the navigating to a fragment steps. In fact, this explainer is based on @bryanmcquade's original CSS Selector Fragment explainer.

The main drawback with this approach was making it secure. Allowing scroll on load to a CSS selector allows several ways an attacker could exfiltrate hidden information (e.g. CSRF tokens) from the page. One such attack is demonstrated here but others were quickly discovered as well.

Trying to pare down the allowable set of primitives to make selectors secure turned out to be quite complex. Text snippets, which can be searched asynchronously and are generally less security sensitive, became our preferred solution. As an additional bonus, we expect text snippets to be more stable and easier to understand by non-technical users.

Increase use of elements with named anchors / id attributes in existing web pages

As an alternative, we could ask web developers to include additional named anchor tags in their pages, and reference those new anchors. There are two issues that make this less appealing. First, legacy content on the web wonโ€™t get updated, but users consuming that legacy content could still benefit from this feature. Second, it is difficult for web developers to reason about all of the possible points other sites might want to scroll to in their pages. Thus, to be most useful, we prefer a solution that supports scrolling to any point in a web page.

JavaScript-based API (instead of URL fragment)

We also considered specifying the target element via a JavaScript-based navigation API, such as via a new parameter to location.assign(). It was concluded that such an API is less useful, as it can only be used in contexts where JavaScript is available. Sharing a link to a specific part of a document is one use case that would not be possible if the target element was specified via a JavaScript API. Using a JavaScript API is also less consistent than existing cases where a scroll target is specified in a URL, such as the existing support in HTML, as well as support for other document formats such as PDF and CSV.

Future Work

One important use case that's not covered by this proposal is being able to scroll to an image. A nearby text snippet can be used to scroll to the image but it depends on the page and is indirect. We'd eventually like to support this use case more directly.

A potential option is to consider this just one of many available Open Annotation selectors. Future specification and implementation work could allow using selectors other than TextQuote to allow targetting various kinds of content.

Another avenue of exploration is allowing users to specify highlighting in more detail. There are also cases where the user may wish to prevent highlights altogether, as in the image search case described above.

We've thought about these cases insofar as making sure our proposed solution doesn't preclude these enhancements in the future. However, the work of actually realizing them will be left for future iterations of this effort.

Additional Considerations

Constructing Arguments to Text Fragments

We imagine URLs with text fragment directives to primarily be machine-generated rather than crafted by hand by users. At the same time, we believe there's a benefit to keeping the URL relatively human-readable: in most cases, simply copying and pasting the desired passage should generate a text fragment directive that will scroll and highlight the desired passage.

The two systems that we believe will generate the bulk of such URLs are browsers and search engines. We forsee users selecting text from the browser, with an option to "share a link to here". These links can then be shared further as wikipedia reference links or over channels like social media or email.

Search engines can also generate text directive URLs as links to search results for user queries; these links may scroll to and highlight relevant passages to the user's query. Note that even though using the selected text as the textStart argument to the text directive may work reasonably well in practice as a heuristic, generating URLs targetting arbitrary text requires access to the full document text up to the desired text. Both browsers and search engines have access to the entire visible text of the page, so it is indeed possible for these systems to generate proper URLs with text directive arguments that scroll and highlight any arbitrary text.

Web and Browser Compatibility

As noted in issue #15, web pages could potentially be using the fragment to store parameters, e.g. http://example.com/#name=test. If sites don't handle unexpected tokens when processing the fragment, this feature could break those sites. In particular, some frameworks use the fragment for routing. This is solved by the user agent hiding the :~:text part of the fragment from the site, but browsers that do not have this feature implemented would still break such sites.

For pages that don't process the fragment, a browser that doesn't yet support this feature will attempt to process the fragment and fragment directive (i.e. :~:text) using the existing logic to find a potential indicated element. If a fragment exists in the URL alongside the fragment directive, the browser may not scroll to the desired fragment due to the confusion with parsing the fragment directive. If a fragment does not exist alongside the fragment directive, the browser will just load the page and won't initiate any scrolling. In either case, the browser will just fall back to the default behavior of not scrolling the document.

Relation to existing support for navigating to a fragment

Browsers currently support scrolling to elements with ids, as well as anchor elements with name attributes. This proposal is intended to extend this existing support, to allow navigating to additional parts of a document. As Shaun Inman notes (in support of CSS selector fragments), this feature is "not meant to replace more concise, author-designed urls" using id attributes, but rather "enables a siteโ€™s users to address specific sub-content that the siteโ€™s author may not have anticipated as being interesting".

Related Work / Additional Resources

Using CSS Selectors as Fragment Identifiers

Simon St. Laurent and Eric Meyer proposed using CSS Selectors as fragment identifiers (last updated in 2012). Their proposal differs only in syntax used: St. Laurent and Meyer proposed specifying the CSS selector using a #css(...) syntax, for example #css(.myclass). This syntax is based on the XML Pointer Language (XPointer) Framework, an "extensible system for XML addressing" ... "intended to be used as a basis for fragment identifiers". XPointer does not appear to be supported by commonly used browsers, so we have elected to not depend on it in this proposal.

Shaun Inman and others later implemented browser extensions using this #css() syntax for Firefox, Safari, Chrome, and Opera, which shows that it is possible to implement this feature across a variety of browsers.

The Open Annotation Community Group aims to allow annotating arbitrary content. There is significant overlap in our goal of specifying a snippet of text in a resource. In fact, they've already specified a TextQuoteSelector for similar purposes.

This proposal has been made similar to the TextQuoteSelector in hopes that we can extend and reuse that processing model rather than inventing a new one, albeit with a stripped down syntax for ease of use in a URL. Our work has been informed specifically by prior efforts at selecting arbitrary textual content for an annotation.

Scroll Anchoring

Scroll to text

Other

Acknowledgements

Many people have contributed greatly to the ideas and content in this repo, both through excellent work on linking to text as well as direct feedback and comments in issues on this repo which helped to improve this feature. In particular, we'd like to thank:

  • @BigBlueHat
  • Ivan Herman
  • Randall Leeds
  • Kevin Marks
  • Isiah Meadows
  • Wes Turner
  • Dan Whaley
  • Gerben
  • And many others who've provided comments, questions, examples, and opinions. Thank you!

More Repositories

1

webcomponents

Web Components specifications
HTML
4,360
star
2

import-maps

How to control the behavior of JavaScript imports
JavaScript
2,705
star
3

virtual-scroller

1,998
star
4

focus-visible

Polyfill for `:focus-visible`
JavaScript
1,607
star
5

webusb

Connecting hardware to the web.
Bikeshed
1,310
star
6

webpackage

Web packaging format
Go
1,231
star
7

EventListenerOptions

An extension to the DOM event pattern to allow authors to disable support for preventDefault
JavaScript
1,166
star
8

portals

A proposal for enabling seamless navigations between sites or pages
HTML
946
star
9

floc

This proposal has been replaced by the Topics API.
Makefile
934
star
10

inert

Polyfill for the inert attribute and property.
JavaScript
920
star
11

scheduling-apis

APIs for scheduling and controlling prioritized tasks.
HTML
909
star
12

view-transitions

811
star
13

file-system-access

Expose the file system on the userโ€™s device, so Web apps can interoperate with the userโ€™s native applications.
Bikeshed
658
star
14

background-sync

A design and spec for ServiceWorker-based background synchronization
HTML
639
star
15

ua-client-hints

Wouldn't it be nice if `User-Agent` was a (set of) client hints?
Bikeshed
590
star
16

observable

Observable API proposal
Bikeshed
582
star
17

aom

Accessibility Object Model
HTML
567
star
18

kv-storage

[On hold] A proposal for an async key/value storage API for the web
550
star
19

turtledove

TURTLEDOVE
Bikeshed
526
star
20

navigation-api

The new navigation API provides a new interface for navigations and session history, with a focus on single-page application navigations.
Makefile
486
star
21

webmonetization

Proposed Web Monetization standard
HTML
461
star
22

trust-token-api

Trust Token API
Bikeshed
421
star
23

attribution-reporting-api

Attribution Reporting API
Bikeshed
360
star
24

direct-sockets

Direct Sockets API for the web platform
HTML
329
star
25

shape-detection-api

Detection of shapes (faces, QR codes) in images
Bikeshed
304
star
26

display-locking

A repository for the Display Locking spec
HTML
297
star
27

dbsc

Bikeshed
297
star
28

background-fetch

API proposal for background downloading/uploading
Shell
281
star
29

first-party-sets

Bikeshed
280
star
30

serial

Serial ports API for the platform.
HTML
256
star
31

resize-observer

This repository is no longer active. ResizeObserver has moved out of WICG into
HTML
255
star
32

priority-hints

A browser API to enable developers signal the priorities of the resources they need to download.
Bikeshed
249
star
33

sanitizer-api

Bikeshed
227
star
34

is-input-pending

HTML
221
star
35

proposals

A home for well-formed proposed incubations for the web platform. All proposals welcome.
216
star
36

spatial-navigation

Directional focus navigation with arrow keys
JavaScript
212
star
37

js-self-profiling

Proposal for a programmable JS profiling API for collecting JS profiles from real end-user environments
HTML
197
star
38

cq-usecases

Use cases and requirements for standardizing element queries.
HTML
184
star
39

isolated-web-apps

Repository for explainers and other documents related to the Isolated Web Apps proposal.
Bikeshed
182
star
40

visual-viewport

A proposal to add explicit APIs to the Web for querying and setting the visual viewport
HTML
177
star
41

interventions

A place for browsers and web developers to collaborate on user agent interventions.
176
star
42

frame-timing

Frame Timing API
HTML
170
star
43

layout-instability

A proposal for a Layout Instability specification
Makefile
158
star
44

page-lifecycle

Lifecycle API to support system initiated discarding and freezing
HTML
154
star
45

nav-speculation

Proposal to enable privacy-enhanced preloading
HTML
154
star
46

speech-api

Web Speech API
Bikeshed
145
star
47

cookie-store

Asynchronous access to cookies from JavaScript
Bikeshed
143
star
48

construct-stylesheets

API for constructing CSS stylesheet objects
Bikeshed
137
star
49

webhid

Web API for accessing Human Interface Devices (HID)
HTML
137
star
50

color-api

A proposal and draft spec for a Color object for the Web Platform, loosely influenced by the Color.js work. Heavily WIP, if you landed here randomly, please move along.
HTML
132
star
51

fenced-frame

Proposal for a strong boundary between a page and its embedded content
Bikeshed
126
star
52

devtools-protocol

DevTools Protocol
JavaScript
120
star
53

sms-one-time-codes

A way to format SMS messages for use with browser autofill features such as HTMLโ€™s autocomplete=one-time-code.
Makefile
111
star
54

bundle-preloading

Bundles of multiple resources, to improve loading JS and the Web.
HTML
105
star
55

translation-api

A proposal for translator and language detector APIs
Bikeshed
104
star
56

privacy-preserving-ads

Privacy-Preserving Ads
HCL
100
star
57

manifest-incubations

Before install prompt API for installing web applications
HTML
99
star
58

window-controls-overlay

HTML
97
star
59

netinfo

HTML
95
star
60

compression-dictionary-transport

94
star
61

intrinsicsize-attribute

Proposal to add an intrinsicsize attribute to media elements
93
star
62

animation-worklet

๐Ÿšซ Old repository for AnimationWorklet specification โžก๏ธ New repository: https://github.com/w3c/css-houdini-drafts
Makefile
92
star
63

container-queries

HTML
91
star
64

local-peer-to-peer

โ†”๏ธ Proposal for local communication between browsers without the aid of a server.
Bikeshed
90
star
65

shared-storage

Explainer for proposed web platform Shared Storage API
Bikeshed
89
star
66

async-append

A way to create DOM and add it to the document without blocking the main thread.
HTML
87
star
67

indexed-db-observers

Prototyping and discussion around indexeddb observers.
WebIDL
84
star
68

canvas-formatted-text

HTML
82
star
69

file-handling

API for web applications to handle files
82
star
70

canvas-color-space

Proposed web platform feature to add color management, wide gamut and high bit-depth support to the <canvas> element.
79
star
71

local-font-access

Web API for enumerating fonts on the local system
Bikeshed
77
star
72

performance-measure-memory

performance.measureMemory API
HTML
77
star
73

digital-credentials

Digital Credentials, like driver's licenses
HTML
77
star
74

handwriting-recognition

Handwriting Recognition Web API Proposal
Bikeshed
75
star
75

web-app-launch

Web App Launch Handler
HTML
75
star
76

pwa-url-handler

72
star
77

ContentPerformancePolicy

A set of policies that a site guarantees to adhere to, browsers enforce, and embedders can count on.
HTML
72
star
78

starter-kit

A simple starter kit for incubations
JavaScript
72
star
79

css-parser-api

This is the repo where the CSS Houdini parser API will be worked on
HTML
71
star
80

close-watcher

A web API proposal for watching for close requests (e.g. Esc, Android back button, ...)
Makefile
71
star
81

eyedropper-api

HTML
69
star
82

idle-detection

A proposal for an idle detection and notification API for the web
Bikeshed
67
star
83

storage-foundation-api-explainer

Explainer showcasing a new web storage API, NativeIO
65
star
84

video-editing

65
star
85

uuid

UUID V4
63
star
86

client-hints-infrastructure

Specification for the Client Hints infrastructure - privacy preserving proactive content negotiation
Bikeshed
61
star
87

sparrow

60
star
88

private-network-access

HTML
58
star
89

element-timing

A proposal for an Element Timing specification.
Bikeshed
57
star
90

document-picture-in-picture

Bikeshed
56
star
91

video-rvfc

video.requestVideoFrameCallback() incubation
HTML
53
star
92

time-to-interactive

Repository for hosting TTI specification and discussions around it.
52
star
93

digital-goods

Bikeshed
50
star
94

soft-navigations

Heuristics to detect Single Page Apps soft navigations
Bikeshed
46
star
95

raw-clipboard-access

An explainer for the Raw Clipboard Access feature
44
star
96

storage-buckets

API proposal for managing multiple storage buckets
Bikeshed
43
star
97

pending-beacon

A better beaconing API
Bikeshed
43
star
98

admin

๐Ÿ‘‹ Ask your questions here! ๐Ÿ‘‹
HTML
42
star
99

web-smart-card

Repository for the Web Smart Card Explainer
HTML
42
star
100

web-preferences-api

The Web Preference API aims to provide a way for sites to override the value for a given user preference (e.g. color-scheme preference) in a way that fully integrates with existing Web APIs.
Bikeshed
41
star