# AbortController Baseline Widely available This feature is well established and works across many devices and browser versions. It’s been available across browsers since March 2019. * Learn more * See full compatibility * Report feedback **Note:** This feature is available in Web Workers. The `AbortController` interface represents a controller object that allows you to abort one or more Web requests as and when desired. You can create a new `AbortController` object using the `AbortController()` constructor. Communicating with an asynchronous operation is done using an `AbortSignal` object. ## Constructor `AbortController()` Creates a new `AbortController` object instance. ## Instance properties `AbortController.signal` Read only Returns an `AbortSignal` object instance, which can be used to communicate with, or to abort, an asynchronous operation. ## Instance methods `AbortController.abort()` Aborts an asynchronous operation before it has completed. This is able to abort fetch requests, consumption of any response bodies, and streams. ## Examples **Note:** There are additional examples in the `AbortSignal` reference. In the following snippet, we aim to download a video using the Fetch API. We first create a controller using the `AbortController()` constructor, then grab a reference to its associated `AbortSignal` object using the `AbortController.signal` property. When the fetch request is initiated, we pass in the `AbortSignal` as an option inside the request's options object (the `{signal}` below). This associates the signal and controller with the fetch request and allows us to abort it by calling `AbortController.abort()`, as seen below in the second event listener. When `abort()` is called, the `fetch()` promise rejects with a `DOMException` named `AbortError`. let controller; const url = "video.mp4"; const downloadBtn = document.querySelector(".download"); const abortBtn = document.querySelector(".abort"); downloadBtn.addEventListener("click", fetchVideo); abortBtn.addEventListener("click", () => { if (controller) { controller.abort(); console.log("Download aborted"); } }); async function fetchVideo() { controller = new AbortController(); const signal = controller.signal; try { const response = await fetch(url, { signal }); console.log("Download complete", response); // process response further } catch (err) { console.error(`Download error: ${err.message}`); } } If the request is aborted after the `fetch()` call has been fulfilled but before the response body has been read, then attempting to read the response body will reject with an `AbortError` exception. async function get() { const controller = new AbortController(); const request = new Request("https://example.org/get", { signal: controller.signal, }); const response = await fetch(request); controller.abort(); // The next line will throw `AbortError` const text = await response.text(); console.log(text); } You can find a full working example on GitHub; you can also see it running live. ## Specifications ## Browser compatibility | Desktop | Mobile ---|---|--- | Chrome | Edge | Firefox | Opera | Safari | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet | WebView Android `AbortController` | 66 | 16 | 57 | 53 | 12.111.1–12.1Even though `window.AbortController` is defined, it doesn't really abort `fetch` requests. See bug 174980. | 66 | 57 | 47 | 12.211.3–12.2Even though `window.AbortController` is defined, it doesn't really abort `fetch` requests. See bug 174980. | 9.0 | 66 `AbortController` | 66 | 16 | 57 | 53 | 12.111.1–12.1Even though `window.AbortController` is defined, it doesn't really abort `fetch` requests. See bug 174980. | 66 | 57 | 47 | 12.211.3–12.2Even though `window.AbortController` is defined, it doesn't really abort `fetch` requests. See bug 174980. | 9.0 | 66 `abort` | 66 | 16 | 57 | 53 | 12.111.1–12.1Even though `window.AbortController` is defined, it doesn't really abort `fetch` requests. See bug 174980. | 66 | 57 | 47 | 12.211.3–12.2Even though `window.AbortController` is defined, it doesn't really abort `fetch` requests. See bug 174980. | 9.0 | 66 `signal` | 66 | 16 | 57 | 53 | 12.111.1–12.1Even though `window.AbortController` is defined, it doesn't really abort `fetch` requests. See bug 174980. | 66 | 57 | 47 | 12.211.3–12.2Even though `window.AbortController` is defined, it doesn't really abort `fetch` requests. See bug 174980. | 9.0 | 66 ## See also * Fetch API * Abortable Fetch by Jake Archibald # AbortController: abort() method Baseline Widely available This feature is well established and works across many devices and browser versions. It’s been available across browsers since March 2019. * Learn more * See full compatibility * Report feedback **Note:** This feature is available in Web Workers. The `abort()` method of the `AbortController` interface aborts an asynchronous operation before it has completed. This is able to abort fetch requests, the consumption of any response bodies, or streams. ## Syntax abort() abort(reason) ### Parameters `reason` Optional The reason why the operation was aborted, which can be any JavaScript value. If not specified, the reason is set to "AbortError" `DOMException`. ### Return value None (`undefined`). ## Examples In the following snippet, we aim to download a video using the Fetch API. We first create a controller using the `AbortController()` constructor, then grab a reference to its associated `AbortSignal` object using the `AbortController.signal` property. When the fetch request is initiated, we pass in the `AbortSignal` as an option inside the request's options object (the `{signal}` below). This associates the signal and controller with the fetch request and allows us to abort it by calling `AbortController.abort()`, as seen below in the second event listener. const controller = new AbortController(); const signal = controller.signal; const url = "video.mp4"; const downloadBtn = document.querySelector(".download"); const abortBtn = document.querySelector(".abort"); downloadBtn.addEventListener("click", fetchVideo); abortBtn.addEventListener("click", () => { controller.abort(); console.log("Download aborted"); }); function fetchVideo() { fetch(url, { signal }) .then((response) => { console.log("Download complete", response); }) .catch((err) => { console.error(`Download error: ${err.message}`); }); } **Note:** When `abort()` is called, the `fetch()` promise rejects with an `Error` of type `DOMException`, with name `AbortError`. You can find a full working example on GitHub; you can also see it running live. ## Specifications ## Browser compatibility | Desktop | Mobile ---|---|--- | Chrome | Edge | Firefox | Opera | Safari | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet | WebView Android `abort` | 66 | 16 | 57 | 53 | 12.111.1–12.1Even though `window.AbortController` is defined, it doesn't really abort `fetch` requests. See bug 174980. | 66 | 57 | 47 | 12.211.3–12.2Even though `window.AbortController` is defined, it doesn't really abort `fetch` requests. See bug 174980. | 9.0 | 66 `reason_parameter` | 98 | 98 | 97 | 84 | 15.4 | 98 | 97 | 68 | 15.4 | 18.0 | 98 ## See also * Fetch API # AbortController: AbortController() constructor Baseline Widely available This feature is well established and works across many devices and browser versions. It’s been available across browsers since March 2019. * Learn more * See full compatibility * Report feedback **Note:** This feature is available in Web Workers. The `AbortController()` constructor creates a new `AbortController` object instance. ## Syntax new AbortController() ### Parameters None. ## Examples In the following snippet, we aim to download a video using the Fetch API. We first create a controller using the `AbortController()` constructor, then grab a reference to its associated `AbortSignal` object using the `AbortController.signal` property. When the fetch request is initiated, we pass in the `AbortSignal` as an option inside the request's options object (the `{ signal }` below). This associates the signal and controller with the fetch request and allows us to abort it by calling `AbortController.abort()`, as seen below in the second event listener. const controller = new AbortController(); const signal = controller.signal; const url = "video.mp4"; const downloadBtn = document.querySelector(".download"); const abortBtn = document.querySelector(".abort"); downloadBtn.addEventListener("click", fetchVideo); abortBtn.addEventListener("click", () => { controller.abort(); console.log("Download aborted"); }); function fetchVideo() { fetch(url, { signal }) .then((response) => { console.log("Download complete", response); }) .catch((err) => { console.error(`Download error: ${err.message}`); }); } **Note:** When `abort()` is called, the `fetch()` promise rejects with an `AbortError`. You can find a full working example on GitHub; you can also see it running live. ## Specifications ## Browser compatibility | Desktop | Mobile ---|---|--- | Chrome | Edge | Firefox | Opera | Safari | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet | WebView Android `AbortController` | 66 | 16 | 57 | 53 | 12.111.1–12.1Even though `window.AbortController` is defined, it doesn't really abort `fetch` requests. See bug 174980. | 66 | 57 | 47 | 12.211.3–12.2Even though `window.AbortController` is defined, it doesn't really abort `fetch` requests. See bug 174980. | 9.0 | 66 ## See also * Fetch API # AbortController: signal property Baseline Widely available This feature is well established and works across many devices and browser versions. It’s been available across browsers since March 2019. * Learn more * See full compatibility * Report feedback **Note:** This feature is available in Web Workers. The `signal` read-only property of the `AbortController` interface returns an `AbortSignal` object instance, which can be used to communicate with/abort an asynchronous operation as desired. ## Value An `AbortSignal` object instance. ## Examples In the following snippet, we aim to download a video using the Fetch API. We first create a controller using the `AbortController()` constructor, then grab a reference to its associated `AbortSignal` object using the `AbortController.signal` property. When the fetch request is initiated, we pass in the `AbortSignal` as an option inside the request's options object (the `{signal}` below). This associates the signal and controller with the fetch request and allows us to abort it by calling `AbortController.abort()`, as seen below in the second event listener. const controller = new AbortController(); const signal = controller.signal; const url = "video.mp4"; const downloadBtn = document.querySelector(".download"); const abortBtn = document.querySelector(".abort"); downloadBtn.addEventListener("click", fetchVideo); abortBtn.addEventListener("click", () => { controller.abort(); console.log("Download aborted"); }); function fetchVideo() { fetch(url, { signal }) .then((response) => { console.log("Download complete", response); }) .catch((err) => { console.error(`Download error: ${err.message}`); }); } **Note:** When `abort()` is called, the `fetch()` promise rejects with an `AbortError`. You can find a full working example on GitHub; you can also see it running live. ## Specifications ## Browser compatibility | Desktop | Mobile ---|---|--- | Chrome | Edge | Firefox | Opera | Safari | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet | WebView Android `signal` | 66 | 16 | 57 | 53 | 12.111.1–12.1Even though `window.AbortController` is defined, it doesn't really abort `fetch` requests. See bug 174980. | 66 | 57 | 47 | 12.211.3–12.2Even though `window.AbortController` is defined, it doesn't really abort `fetch` requests. See bug 174980. | 9.0 | 66 ## See also * Fetch API # AbortSignal Baseline Widely available * This feature is well established and works across many devices and browser versions. It’s been available across browsers since April 2018. * Some parts of this feature may have varying levels of support. * Learn more * See full compatibility * Report feedback **Note:** This feature is available in Web Workers. The `AbortSignal` interface represents a signal object that allows you to communicate with an asynchronous operation (such as a fetch request) and abort it if required via an `AbortController` object. EventTarget AbortSignal ## Instance properties _Also inherits properties from its parent interface,`EventTarget`._ `AbortSignal.aborted` Read only A Boolean that indicates whether the request(s) the signal is communicating with is/are aborted (`true`) or not (`false`). `AbortSignal.reason` Read only A JavaScript value providing the abort reason, once the signal has aborted. ## Static methods _Also inherits methods from its parent interface,`EventTarget`._ `AbortSignal.abort()` Returns an `AbortSignal` instance that is already set as aborted. `AbortSignal.any()` Returns an `AbortSignal` that aborts when any of the given abort signals abort. `AbortSignal.timeout()` Returns an `AbortSignal` instance that will automatically abort after a specified time. ## Instance methods _Also inherits methods from its parent interface,`EventTarget`._ `AbortSignal.throwIfAborted()` Throws the signal's abort `reason` if the signal has been aborted; otherwise it does nothing. ## Events _Also inherits events from its parent interface,`EventTarget`._ Listen to this event using `addEventListener()` or by assigning an event listener to the `oneventname` property of this interface. `abort` Invoked when the asynchronous operations the signal is communicating with is/are aborted. Also available via the `onabort` property. ## Examples ### Aborting a fetch operation using an explicit signal The following snippet shows how we might use a signal to abort downloading a video using the Fetch API. We first create an abort controller using the `AbortController()` constructor, then grab a reference to its associated `AbortSignal` object using the `AbortController.signal` property. When the fetch request is initiated, we pass in the `AbortSignal` as an option inside the request's options object (the `{signal}` below). This associates the signal and controller with the fetch request, and allows us to abort it by calling `AbortController.abort()`. Below you can see that the fetch operation is aborted in the second event listener, which triggered when the abort button (`abortBtn`) is clicked. When `abort()` is called, the `fetch()` promise rejects with a `DOMException` named `AbortError`. let controller; const url = "video.mp4"; const downloadBtn = document.querySelector(".download"); const abortBtn = document.querySelector(".abort"); downloadBtn.addEventListener("click", fetchVideo); abortBtn.addEventListener("click", () => { if (controller) { controller.abort(); console.log("Download aborted"); } }); async function fetchVideo() { controller = new AbortController(); const signal = controller.signal; try { const response = await fetch(url, { signal }); console.log("Download complete", response); // process response further } catch (err) { console.error(`Download error: ${err.message}`); } } If the request is aborted after the `fetch()` call has been fulfilled but before the response body has been read, then attempting to read the response body will reject with an `AbortError` exception. async function get() { const controller = new AbortController(); const request = new Request("https://example.org/get", { signal: controller.signal, }); const response = await fetch(request); controller.abort(); // The next line will throw `AbortError` const text = await response.text(); console.log(text); } You can find a full working example on GitHub; you can also see it running live. ### Aborting a fetch operation with a timeout If you need to abort the operation on timeout then you can use the static `AbortSignal.timeout()` method. This returns an `AbortSignal` that will automatically timeout after a certain number of milliseconds. The code snippet below shows how you would either succeed in downloading a file, or handle a timeout error after 5 seconds. Note that when there is a timeout the `fetch()` promise rejects with a `TimeoutError` `DOMException`. This allows code to differentiate between timeouts (for which user notification is probably required), and user aborts. const url = "video.mp4"; try { const res = await fetch(url, { signal: AbortSignal.timeout(5000) }); const result = await res.blob(); // … } catch (err) { if (err.name === "TimeoutError") { console.error("Timeout: It took more than 5 seconds to get the result!"); } else if (err.name === "AbortError") { console.error( "Fetch aborted by user action (browser stop button, closing tab, etc.", ); } else { // A network error, or some other problem. console.error(`Error: type: ${err.name}, message: ${err.message}`); } } ### Aborting a fetch with timeout or explicit abort If you want to abort from multiple signals, you can use `AbortSignal.any()` to combine them into a single signal. The following example shows this using `fetch`: try { const controller = new AbortController(); const timeoutSignal = AbortSignal.timeout(5000); const res = await fetch(url, { // This will abort the fetch when either signal is aborted signal: AbortSignal.any([controller.signal, timeoutSignal]), }); const body = await res.json(); } catch (e) { if (e.name === "AbortError") { // Notify the user of abort. } else if (e.name === "TimeoutError") { // Notify the user of timeout } else { // A network error, or some other problem. console.log(`Type: ${e.name}, Message: ${e.message}`); } } **Note:** Unlike when using `AbortSignal.timeout()`, there is no way to tell whether the final abort was caused by a timeout. ### Implementing an abortable API An API that needs to support aborting can accept an `AbortSignal` object, and use its state to trigger abort signal handling when needed. A `Promise`-based API should respond to the abort signal by rejecting any unsettled promise with the `AbortSignal` abort `reason`. For example, consider the following `myCoolPromiseAPI`, which takes a signal and returns a promise. The promise is rejected immediately if the signal is already aborted, or if the abort event is detected. Otherwise it completes normally and then resolves the promise. function myCoolPromiseAPI(/* …, */ { signal }) { return new Promise((resolve, reject) => { // If the signal is already aborted, immediately throw in order to reject the promise. if (signal.aborted) { reject(signal.reason); return; } // Perform the main purpose of the API // Call resolve(result) when done. // Watch for 'abort' signals signal.addEventListener("abort", () => { // Stop the main operation // Reject the promise with the abort reason. reject(signal.reason); }); }); } The API might then be used as shown. Note that `AbortController.abort()` is called to abort the operation. const controller = new AbortController(); const signal = controller.signal; startSpinner(); myCoolPromiseAPI({ /* …, */ signal }) .then((result) => {}) .catch((err) => { if (err.name === "AbortError") return; showUserErrorMessage(); }) .then(() => stopSpinner()); controller.abort(); APIs that do not return promises might react in a similar manner. In some cases it may make sense to absorb the signal. ## Specifications ## Browser compatibility | Desktop | Mobile ---|---|--- | Chrome | Edge | Firefox | Opera | Safari | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet | WebView Android `AbortSignal` | 66 | 16 | 57 | 53 | 11.1 | 66 | 57 | 47 | 11.3 | 9.0 | 66 `abort_event` | 66 | 16 | 57 | 53 | 11.1 | 66 | 57 | 47 | 11.3 | 9.0 | 66 `abort_static` | 93 | 93 | 88 | 79 | 15 | 93 | 88 | 66 | 15 | 17.0 | 93 `aborted` | 66 | 16 | 57 | 53 | 11.1 | 66 | 57 | 47 | 11.3 | 9.0 | 66 `any_static` | 116 | 116 | 124 | 102 | 17.4 | 116 | 124 | 78 | 17.4 | 24.0 | 116 `reason` | 98 | 98 | 97 | 84 | 15.4 | 98 | 97 | 68 | 15.4 | 18.0 | 98 `throwIfAborted` | 100 | 100 | 97 | 86 | 15.4 | 100 | 97 | 69 | 15.4 | 19.0 | 100 `timeout_static` | 124103–124Always aborts with an `AbortError` on timeout, not a `TimeoutError`. | 124103–124Always aborts with an `AbortError` on timeout, not a `TimeoutError`. | 100 | 11089–110Always aborts with an `AbortError` on timeout, not a `TimeoutError`. | 16 | 124103–124Always aborts with an `AbortError` on timeout, not a `TimeoutError`. | 100 | 8271–82Always aborts with an `AbortError` on timeout, not a `TimeoutError`. | 16 | 27.020.0–27.0Always aborts with an `AbortError` on timeout, not a `TimeoutError`. | 124103–124Always aborts with an `AbortError` on timeout, not a `TimeoutError`. ## See also * Fetch API * Abortable Fetch by Jake Archibald # AbortSignal: abort event Baseline Widely available This feature is well established and works across many devices and browser versions. It’s been available across browsers since April 2018. * Learn more * See full compatibility * Report feedback **Note:** This feature is available in Web Workers. The `abort` event of the `AbortSignal` is fired when the associated request is aborted, i.e., using `AbortController.abort()`. ## Syntax Use the event name in methods like `addEventListener()`, or set an event handler property. addEventListener("abort", (event) => { }) onabort = (event) => { } ## Event type A generic `Event` with no added properties. ## Examples In the following snippets, we create a new `AbortController` object, and get its `AbortSignal` (available using the `signal` property). Later on we check whether or not the signal has been aborted using an event handler property, You can detect the `abort` event using an `addEventListener` method: const controller = new AbortController(); const signal = controller.signal; signal.addEventListener("abort", () => { console.log("Request aborted"); }); Or use the `onabort` event handler property: const controller = new AbortController(); const signal = controller.signal; signal.onabort = () => { console.log("Request aborted"); }; ## Specifications ## Browser compatibility | Desktop | Mobile ---|---|--- | Chrome | Edge | Firefox | Opera | Safari | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet | WebView Android `abort_event` | 66 | 16 | 57 | 53 | 11.1 | 66 | 57 | 47 | 11.3 | 9.0 | 66 # AbortSignal: abort() static method Baseline Widely available This feature is well established and works across many devices and browser versions. It’s been available across browsers since September 2021. * Learn more * See full compatibility * Report feedback **Note:** This feature is available in Web Workers. The `AbortSignal.abort()` static method returns an `AbortSignal` that is already set as aborted (and which does not trigger an `abort` event). This is shorthand for the following code: const controller = new AbortController(); controller.abort(); return controller.signal; This could, for example, be passed to a fetch method in order to run its abort logic (i.e., it may be that code is organized such that the abort logic should be run even if the intended fetch operation has not been started). **Note:** The method is similar in purpose to `Promise.reject`. ## Syntax AbortSignal.abort() AbortSignal.abort(reason) ### Parameters `reason` The reason why the operation was aborted, which can be any JavaScript value. If not specified, the reason is set to "AbortError" `DOMException`. ### Return value An `AbortSignal` instance with the `AbortSignal.aborted` property set to `true`, and `AbortSignal.reason` set to the specified or default reason value. ## Specifications ## Browser compatibility | Desktop | Mobile ---|---|--- | Chrome | Edge | Firefox | Opera | Safari | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet | WebView Android `abort_static` | 93 | 93 | 88 | 79 | 15 | 93 | 88 | 66 | 15 | 17.0 | 93 `reason_parameter` | 98 | 98 | 97 | 84 | 15.4 | 98 | 97 | 68 | 15.4 | 18.0 | 98 # AbortSignal: aborted property Baseline Widely available This feature is well established and works across many devices and browser versions. It’s been available across browsers since April 2018. * Learn more * See full compatibility * Report feedback **Note:** This feature is available in Web Workers. The `aborted` read-only property returns a value that indicates whether the asynchronous operations the signal is communicating with are aborted (`true`) or not (`false`). ## Value `true` (aborted) or `false` ## Examples In the following snippet, we create a new `AbortController` object, and get its `AbortSignal` (available using the `signal` property). Later on, using the `aborted` property, we check whether or not the signal has been aborted, and send an appropriate log to the console. const controller = new AbortController(); const signal = controller.signal; // … if (signal.aborted) { console.log("Request has been aborted"); } else { console.log("Request not aborted"); } ## Specifications ## Browser compatibility | Desktop | Mobile ---|---|--- | Chrome | Edge | Firefox | Opera | Safari | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet | WebView Android `aborted` | 66 | 16 | 57 | 53 | 11.1 | 66 | 57 | 47 | 11.3 | 9.0 | 66 ## See also * Fetch API # AbortSignal: any() static method Baseline 2024 Newly available Since March 2024, this feature works across the latest devices and browser versions. This feature might not work in older devices or browsers. * Learn more * See full compatibility * Report feedback **Note:** This feature is available in Web Workers. The `AbortSignal.any()` static method takes an iterable of abort signals and returns an `AbortSignal`. The returned abort signal is aborted when any of the input iterable abort signals are aborted. The abort reason will be set to the reason of the first signal that is aborted. If any of the given abort signals are already aborted then so will be the returned `AbortSignal`. ## Syntax AbortSignal.any(iterable) ### Parameters `iterable` An iterable (such as an `Array`) of abort signals. ### Return value A `AbortSignal` that is: * **Already aborted** , if any of the abort signals given is already aborted. The returned `AbortSignal`'s reason will be already set to the `reason` of the first abort signal that was already aborted. * **Asynchronously aborted** , when any abort signal in `iterable` aborts. The `reason` will be set to the reason of the first abort signal that is aborted. ## Examples ### Using `AbortSignal.any()` This example demonstrates combining both a signal from an `AbortController`, and a timeout signal from `AbortSignal.timeout`. const cancelDownloadButton = document.getElementById("cancelDownloadButton"); const userCancelController = new AbortController(); cancelDownloadButton.addEventListener("click", () => { userCancelController.abort(); }); // Timeout after 5 minutes const timeoutSignal = AbortSignal.timeout(1_000 * 60 * 5); // This signal will abort when either the user clicks the cancel button or 5 minutes is up // whichever is sooner const combinedSignal = AbortSignal.any([ userCancelController.signal, timeoutSignal, ]); try { const res = await fetch(someUrlToDownload, { // Stop the fetch when any of the signals aborts signal: combinedSignal, }); const body = await res.blob(); // Do something with downloaded content: // … } catch (e) { if (e.name === "AbortError") { // Cancelled by the user } else if (e.name === "TimeoutError") { // Show user that download timed out } else { // Other error, e.g. network error } } ## Specifications ## Browser compatibility | Desktop | Mobile ---|---|--- | Chrome | Edge | Firefox | Opera | Safari | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet | WebView Android `any_static` | 116 | 116 | 124 | 102 | 17.4 | 116 | 124 | 78 | 17.4 | 24.0 | 116 # AbortSignal: reason property Baseline Widely available This feature is well established and works across many devices and browser versions. It’s been available across browsers since March 2022. * Learn more * See full compatibility * Report feedback **Note:** This feature is available in Web Workers. The `reason` read-only property returns a JavaScript value that indicates the abort reason. The property is `undefined` when the signal has not been aborted. It can be set to a specific value when the signal is aborted, using `AbortController.abort()` or `AbortSignal.abort()`. If not explicitly set in those methods, it defaults to "AbortError" `DOMException`. ## Value A JavaScript value that indicates the abort reason, or `undefined`, if not aborted. ## Examples In the following snippet, we create a new `AbortController` object, and get its `AbortSignal` (available using the `signal` property). Later on, using the `aborted` property, we check whether or not the signal has been aborted, and log the abort status and reason to the console. const controller = new AbortController(); const signal = controller.signal; // … if (signal.aborted) { if (signal.reason) { console.log(`Request aborted with reason: ${signal.reason}`); } else { console.log("Request aborted but no reason was given."); } } else { console.log("Request not aborted"); } ## Specifications ## Browser compatibility | Desktop | Mobile ---|---|--- | Chrome | Edge | Firefox | Opera | Safari | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet | WebView Android `reason` | 98 | 98 | 97 | 84 | 15.4 | 98 | 97 | 68 | 15.4 | 18.0 | 98 ## See also * Fetch API # AbortSignal: throwIfAborted() method Baseline Widely available This feature is well established and works across many devices and browser versions. It’s been available across browsers since April 2022. * Learn more * See full compatibility * Report feedback **Note:** This feature is available in Web Workers. The `throwIfAborted()` method throws the signal's abort `reason` if the signal has been aborted; otherwise it does nothing. An API that needs to support aborting can accept an `AbortSignal` object and use `throwIfAborted()` to test and throw when the `abort` event is signalled. This method can also be used to abort operations at particular points in code, rather than passing to functions that take a signal. ## Syntax throwIfAborted() ### Parameters None. ### Return value None (`undefined`). ## Examples The examples below come from the specification. ### Aborting a polling operation This example demonstrates how you can use `throwIfAborted()` to abort a polling operation. Consider an asynchronous `waitForCondition()` function that is called with another asynchronous function `func`, a target value `targetValue`, and an `AbortSignal`. The method compares the result of `func` with `targetValue` in a loop, returning when they match. async function waitForCondition(func, targetValue, { signal } = {}) { while (true) { signal?.throwIfAborted(); const result = await func(); if (result === targetValue) { return; } } } On each iteration of the loop, we use `throwIfAborted()` to throw the signal's `reason` if the operation has been aborted (and otherwise do nothing). If the signal is aborted, this will cause the `waitForCondition()` promise to be rejected. ## Specifications ## Browser compatibility | Desktop | Mobile ---|---|--- | Chrome | Edge | Firefox | Opera | Safari | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet | WebView Android `throwIfAborted` | 100 | 100 | 97 | 86 | 15.4 | 100 | 97 | 69 | 15.4 | 19.0 | 100 ## See also * Fetch API # AbortSignal: timeout() static method Baseline 2024 Newly available Since April 2024, this feature works across the latest devices and browser versions. This feature might not work in older devices or browsers. * Learn more * See full compatibility * Report feedback **Note:** This feature is available in Web Workers. The `AbortSignal.timeout()` static method returns an `AbortSignal` that will automatically abort after a specified time. The signal aborts with a `TimeoutError` `DOMException` on timeout. The timeout is based on active rather than elapsed time, and will effectively be paused if the code is running in a suspended worker, or while the document is in a back-forward cache ("bfcache"). To combine multiple signals, you can use `AbortSignal.any()`, for example, to directly abort a download using either a timeout signal or by calling `AbortController.abort()`. ## Syntax AbortSignal.timeout(time) ### Parameters `time` The "active" time in milliseconds before the returned `AbortSignal` will abort. The value must be within range of 0 and `Number.MAX_SAFE_INTEGER`. ### Return value An `AbortSignal`. The signal will abort with its `AbortSignal.reason` property set to a `TimeoutError` `DOMException` on timeout, or an `AbortError` `DOMException` if the operation was user-triggered. ## Examples Below is an example showing a fetch operation that will timeout if unsuccessful after 5 seconds. Note that this may also fail if the method is not supported, if a browser "stop" button is pressed, or for another reason. const url = "https://path_to_large_file.mp4"; try { const res = await fetch(url, { signal: AbortSignal.timeout(5000) }); const result = await res.blob(); // … } catch (err) { if (err.name === "TimeoutError") { // This exception is from the abort signal console.error("Timeout: It took more than 5 seconds to get the result!"); } else if (err.name === "AbortError") { // This exception is from the fetch itself console.error( "Fetch aborted by user action (browser stop button, closing tab, etc.", ); } else if (err.name === "TypeError") { console.error("AbortSignal.timeout() method is not supported"); } else { // A network error, or some other problem. console.error(`Error: type: ${err.name}, message: ${err.message}`); } } ## Specifications ## Browser compatibility | Desktop | Mobile ---|---|--- | Chrome | Edge | Firefox | Opera | Safari | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet | WebView Android `timeout_static` | 124103–124Always aborts with an `AbortError` on timeout, not a `TimeoutError`. | 124103–124Always aborts with an `AbortError` on timeout, not a `TimeoutError`. | 100 | 11089–110Always aborts with an `AbortError` on timeout, not a `TimeoutError`. | 16 | 124103–124Always aborts with an `AbortError` on timeout, not a `TimeoutError`. | 100 | 8271–82Always aborts with an `AbortError` on timeout, not a `TimeoutError`. | 16 | 27.020.0–27.0Always aborts with an `AbortError` on timeout, not a `TimeoutError`. | 124103–124Always aborts with an `AbortError` on timeout, not a `TimeoutError`. # AbsoluteOrientationSensor Limited availability This feature is not Baseline because it does not work in some of the most widely-used browsers. * Learn more * See full compatibility * Report feedback **Secure context:** This feature is available only in secure contexts (HTTPS), in some or all supporting browsers. The `AbsoluteOrientationSensor` interface of the Sensor APIs describes the device's physical orientation in relation to the Earth's reference coordinate system. To use this sensor, the user must grant permission to the `'accelerometer'`, `'gyroscope'`, and `'magnetometer'` device sensors through the Permissions API. This feature may be blocked by a Permissions Policy set on your server. EventTarget Sensor OrientationSensor AbsoluteOrientationSensor ## Constructor `AbsoluteOrientationSensor()` Creates a new `AbsoluteOrientationSensor` object. ## Instance properties _No specific properties; inherits properties from its ancestors`OrientationSensor` and `Sensor`._ ## Instance methods _No specific methods; inherits methods from its ancestors`OrientationSensor` and `Sensor`._ ## Events _No specific events; inherits methods from its ancestor,`Sensor`._ ## Examples ### Basic Example The following example, which is loosely based on Intel's Orientation Phone demo, instantiates an `AbsoluteOrientationSensor` with a frequency of 60 times a second. On each reading it uses `OrientationSensor.quaternion` to rotate a visual model of a phone. const options = { frequency: 60, referenceFrame: "device" }; const sensor = new AbsoluteOrientationSensor(options); sensor.addEventListener("reading", () => { // model is a Three.js object instantiated elsewhere. model.quaternion.fromArray(sensor.quaternion).inverse(); }); sensor.addEventListener("error", (event) => { if (event.error.name === "NotReadableError") { console.log("Sensor is not available."); } }); sensor.start(); ### Permissions Example Using orientation sensors requires requesting permissions for multiple device sensors. Because the `Permissions` interface uses promises, a good way to request permissions is to use `Promise.all`. const sensor = new AbsoluteOrientationSensor(); Promise.all([ navigator.permissions.query({ name: "accelerometer" }), navigator.permissions.query({ name: "magnetometer" }), navigator.permissions.query({ name: "gyroscope" }), ]).then((results) => { if (results.every((result) => result.state === "granted")) { sensor.start(); // … } else { console.log("No permissions to use AbsoluteOrientationSensor."); } }); ## Specifications ## Browser compatibility | Desktop | Mobile ---|---|--- | Chrome | Edge | Firefox | Opera | Safari | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet | WebView Android `AbsoluteOrientationSensor` | 67 | 79 | No | 54 | No | 67 | No | 48 | No | 9.0 | 67 `AbsoluteOrientationSensor` | 67 | 79 | No | 54 | No | 67 | No | 48 | No | 9.0 | 67 # AbsoluteOrientationSensor: AbsoluteOrientationSensor() constructor Limited availability This feature is not Baseline because it does not work in some of the most widely-used browsers. * Learn more * See full compatibility * Report feedback **Secure context:** This feature is available only in secure contexts (HTTPS), in some or all supporting browsers. The `AbsoluteOrientationSensor()` constructor creates a new `AbsoluteOrientationSensor` object which describes the device's physical orientation in relation to the Earth's reference coordinate system. ## Syntax new AbsoluteOrientationSensor() new AbsoluteOrientationSensor(options) ### Parameters `options` Optional Options are as follows: `frequency` Optional The desired number of times per second a sample should be taken, meaning the number of times per second that the `reading` event will be called. A whole number or decimal may be used, the latter for frequencies less than a second. The actual reading frequency depends on the device hardware and consequently may be less than requested. `referenceFrame` Optional Either `'device'` or `'screen'`. The default is `'device'`. ## Specifications ## Browser compatibility | Desktop | Mobile ---|---|--- | Chrome | Edge | Firefox | Opera | Safari | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet | WebView Android `AbsoluteOrientationSensor` | 67 | 79 | No | 54 | No | 67 | No | 48 | No | 9.0 | 67 ## See also * `reading` event # AbstractRange Baseline Widely available This feature is well established and works across many devices and browser versions. It’s been available across browsers since April 2021. * Learn more * See full compatibility * Report feedback The `AbstractRange` abstract interface is the base class upon which all DOM range types are defined. A **range** is an object that indicates the start and end points of a section of content within the document. **Note:** As an abstract interface, you will not directly instantiate an object of type `AbstractRange`. Instead, you will use the `Range` or `StaticRange` interfaces. To understand the difference between those two interfaces, and how to choose which is appropriate for your needs, consult each interface's documentation. ## Instance properties `collapsed` Read only A Boolean value which is `true` if the range is _collapsed_. A collapsed range is a range whose start position and end position are the same, resulting in a zero-character-long range. `endContainer` Read only The `Node` object in which the end of the range, as specified by the `endOffset` property, is located. `endOffset` Read only An integer value indicating the offset, in characters, from the beginning of the node's contents to the last character of the range represented by the range object. This value must be less than the length of the `endContainer` node. `startContainer` Read only The DOM `Node` in which the beginning of the range, as specified by the `startOffset` property, is located. `startOffset` Read only An integer value indicating the offset, in characters, from the beginning of the node's contents to the first character of the contents referred to by the range object. This value must be less than the length of the node indicated in `startContainer`. ## Instance methods _The`AbstractRange` interface doesn't provide any methods._ ## Usage notes ### Range types All ranges of content within a `document` are described using instances of interfaces based on `AbstractRange`. There are two such interfaces: `Range` The `Range` interface has been around for a long time and has only recently been redefined to be based upon `AbstractRange` as the need arose to define other forms of range data. `Range` provides methods that allow you to alter the range's endpoints, as well as methods to compare ranges, detect intersections between ranges, and so forth. `StaticRange` A `StaticRange` is a basic range which cannot be changed once it's been created. Specifically, as the node tree mutates and changes, the range does not. This is useful when you need to specify a range that will only be used once, since it avoids the performance and resource impact of the more complex `Range` interface. ### Contents of elements When trying to access the contents of an element, keep in mind that the element itself is a node, but so is any text inside it. In order to set a range endpoint within the text of an element, be sure to find the text node inside the element: const startElem = document.querySelector("p"); const endElem = startElem.querySelector("span"); const range = document.createRange(); range.setStart(startElem, 0); range.setEnd(endElem, endElem.childNodes[0].length / 2); const contents = range.cloneContents(); document.body.appendChild(contents); This example creates a new range, `range`, and sets its starting point to the third child node of the first element. The end point is set to be the middle of the first child of the span, and then the range is used to copy the contents of the range. ### Ranges and the hierarchy of the DOM In order to define a range of characters within a document in a way that is able to span across zero or more node boundaries, and which is as resilient as possible to changes to the DOM, you can't specify the offset to the first and last characters in the HTML. There are a few good reasons for that. First, after your page is loaded, the browser isn't thinking in terms of HTML. Once it's been loaded, the page is a tree of DOM `Node` objects, so you need to specify the beginning and ending locations of a range in terms of nodes and positions within nodes. Second, in order to support the mutability of the DOM tree as much as possible, you need a way to represent positions relative to nodes in the tree, rather than global positions within the entire document. By defining points within the document as offsets within a given node, those positions remain consistent with the content even as nodes are added to, removed from, or moved around within the DOM tree—within reason. There are fairly obvious limitations (such as if a node is moved to be after the endpoint of a range, or if the content of a node is heavily altered), but it's far better than nothing. Third, using node-relative positions to define the start and end positions will generally be easier to make perform well. Rather than having to negotiate the DOM figuring out what your global offset refers to, the user agent (browser) can instead go directly to the node indicated by the starting position and start from there, working its way forward until it reaches the given offset into the ending node. To illustrate this, consider the HTML below:

The Ultimate Website

Section 1: An interesting thing…

A very interesting thing happened on the way to the forum…


    
After loading the HTML and constructing the DOM representation of the document, the resulting DOM tree looks like this: In this diagram, the nodes representing HTML elements are shown in green. Each row beneath them shows the next layer of depth into the DOM tree. Blue nodes are text nodes, containing the text that gets shown onscreen. Each element's contents are linked below it in the tree, potentially spawning a series of branches below as elements include other elements and text nodes. If you want to create a range that incorporates the contents of the `

` element whose contents are `"A very interesting thing happened on the way to the forum…"`, you can do so like this: const pRange = document.createRange(); pRange.selectNodeContents(document.querySelector("#entry1 p")); Since we wish to select the entire contents of the `

` element, including its descendants, this works perfectly. If we wish to instead copy the text "An interesting thing…" from the `

`'s heading (an h2 element) through the end of the letters "ve" in the `` within the paragraph below it, the following code would work: const range = document.createRange(); const startNode = document.querySelector("section h2").childNodes[0]; range.setStart(startNode, 11); const endNode = document.querySelector("#entry1 p em").childNodes[0]; range.setEnd(endNode, 2); const fragment = range.cloneContents(); Here an interesting problem arises—we are capturing content from multiple nodes located at different levels of the DOM hierarchy, and then only part of one of them. What should the result look like? As it turns out, the DOM specification fortunately addresses this exact issue. For example, in this case, we're calling `cloneContents()` on the range to create a new `DocumentFragment` object providing a DOM subtree which replicates the contents of the specified range. To do this, `cloneContents()` constructs all the nodes needed to preserve the structure of the indicated range, but no more than necessary. In this example, the start of the specified range is found within the text node below the section's heading, which means that the new `DocumentFragment` will need to contain an h2 and, below it, a text node. The range's end is located below the `

` element, so that will be needed within the new fragment. So will the text node containing the word "A", since that's included in the range. Finally, an `` and a text node below it will be added below the `

` as well. The contents of the text nodes are then determined by the offsets into those text nodes given when calling `setStart()` and `setEnd()`. Given the offset of 11 into the heading's text, that node will contain "An interesting thing…". Similarly, the last text node will contain "ve", given the request for the first two characters of the ending node. The resulting document fragment looks like this: Notice especially that the contents of this fragment are all _below_ the shared common parent of the topmost nodes within it. The parent `

` is not needed to replicate the cloned content, so it isn't included. ## Example Consider this simple HTML fragment of HTML.

This is a paragraph.

Imagine using a `Range` to extract the word "paragraph" from this. The code to do that looks like the following: const paraNode = document.querySelector("p"); const paraTextNode = paraNode.childNodes[1]; const range = document.createRange(); range.setStart(paraTextNode, 6); range.setEnd(paraTextNode, paraTextNode.length - 1); const fragment = range.cloneContents(); document.body.appendChild(fragment); First we get references to the paragraph node itself as well as to the _second_ child node within the paragraph. The first child is the `` element. The second child is the text node " is a paragraph.". With the text node reference in hand, we create a new `Range` object by calling `createRange()` on the `Document` itself. We set the starting position of the range to the sixth character of the text node's string, and the end position to the length of the text node's string minus one. This sets the range to encompass the word "paragraph". We then finish up by calling `cloneContents()` on the `Range` to create a new `DocumentFragment` object which contains the portion of the document encompassed by the range. After that, we use `appendChild()` to add that fragment at the end of the document's body, as obtained from `document.body`. The result looks like this: ## Specifications ## Browser compatibility | Desktop | Mobile ---|---|--- | Chrome | Edge | Firefox | Opera | Safari | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet | WebView Android `AbstractRange` | 90 | 9018–79 | 69 | 76 | 14.1 | 90 | 79 | 64 | 14.5 | 15.0 | 90 `collapsed` | 90 | 9018–79 | 69 | 76 | 14.1 | 90 | 79 | 64 | 14.5 | 15.0 | 90 `endContainer` | 90 | 9018–79 | 69 | 76 | 14.1 | 90 | 79 | 64 | 14.5 | 15.0 | 90 `endOffset` | 90 | 9018–79 | 69 | 76 | 14.1 | 90 | 79 | 64 | 14.5 | 15.0 | 90 `startContainer` | 90 | 9018–79 | 69 | 76 | 14.1 | 90 | 79 | 64 | 14.5 | 15.0 | 90 `startOffset` | 90 | 9018–79 | 69 | 76 | 14.1 | 90 | 79 | 64 | 14.5 | 15.0 | 90 # AbstractRange: collapsed property Baseline Widely available This feature is well established and works across many devices and browser versions. It’s been available across browsers since April 2021. * Learn more * See full compatibility * Report feedback The read-only `collapsed` property of the `AbstractRange` interface returns `true` if the range's start position and end position are the same. ## Value A boolean value which is `true` if the range is _collapsed_. A collapsed range is one in which the start and end positions are the same, resulting in a zero- character-long range. ## Example let isCollapsed = range.collapsed; ## Specifications ## Browser compatibility | Desktop | Mobile ---|---|--- | Chrome | Edge | Firefox | Opera | Safari | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet | WebView Android `collapsed` | 90 | 9018–79 | 69 | 76 | 14.1 | 90 | 79 | 64 | 14.5 | 15.0 | 90 # AbstractRange: endContainer property Baseline Widely available This feature is well established and works across many devices and browser versions. It’s been available across browsers since April 2021. * Learn more * See full compatibility * Report feedback The read-only `endContainer` property of the `AbstractRange` interface returns the `Node` in which the end of the range is located. ## Value The `Node` which contains the last character of the range. ## Example let endNode = range.endContainer; ## Specifications ## Browser compatibility | Desktop | Mobile ---|---|--- | Chrome | Edge | Firefox | Opera | Safari | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet | WebView Android `endContainer` | 90 | 9018–79 | 69 | 76 | 14.1 | 90 | 79 | 64 | 14.5 | 15.0 | 90 # AbstractRange: endOffset property Baseline Widely available This feature is well established and works across many devices and browser versions. It’s been available across browsers since April 2021. * Learn more * See full compatibility * Report feedback The `endOffset` property of the `AbstractRange` interface returns the offset into the end node of the range's end position. ## Value An integer value indicating the number of characters into the `Node` indicated by `endContainer` at which the final character of the range is located. ## Example let endOffset = range.endOffset; ## Specifications ## Browser compatibility | Desktop | Mobile ---|---|--- | Chrome | Edge | Firefox | Opera | Safari | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet | WebView Android `endOffset` | 90 | 9018–79 | 69 | 76 | 14.1 | 90 | 79 | 64 | 14.5 | 15.0 | 90 # AbstractRange: startContainer property Baseline Widely available This feature is well established and works across many devices and browser versions. It’s been available across browsers since April 2021. * Learn more * See full compatibility * Report feedback The read-only `startContainer` property of the `AbstractRange` interface returns the start `Node` for the range. ## Value The `Node` inside which the start position of the range is found. ## Example let startNode = range.startContainer; ## Specifications ## Browser compatibility | Desktop | Mobile ---|---|--- | Chrome | Edge | Firefox | Opera | Safari | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet | WebView Android `startContainer` | 90 | 9018–79 | 69 | 76 | 14.1 | 90 | 79 | 64 | 14.5 | 15.0 | 90 # AbstractRange: startOffset property Baseline Widely available This feature is well established and works across many devices and browser versions. It’s been available across browsers since April 2021. * Learn more * See full compatibility * Report feedback The read-only `startOffset` property of the `AbstractRange` interface returns the offset into the start node of the range's start position. ## Value An integer value indicating the number of characters into the `Node` indicated by `startContainer` at which the first character of the range is located. ## Example let startOffset = range.startOffset; ## Specifications ## Browser compatibility | Desktop | Mobile ---|---|--- | Chrome | Edge | Firefox | Opera | Safari | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet | WebView Android `startOffset` | 90 | 9018–79 | 69 | 76 | 14.1 | 90 | 79 | 64 | 14.5 | 15.0 | 90 # Accelerometer Limited availability This feature is not Baseline because it does not work in some of the most widely-used browsers. * Learn more * See full compatibility * Report feedback **Secure context:** This feature is available only in secure contexts (HTTPS), in some or all supporting browsers. **Experimental:** **This is an experimental technology** Check the Browser compatibility table carefully before using this in production. The `Accelerometer` interface of the Sensor APIs provides on each reading the acceleration applied to the device along all three axes. To use this sensor, the user must grant permission to the `'accelerometer'`, device sensor through the Permissions API. This feature may be blocked by a Permissions Policy set on your server. EventTarget Sensor Accelerometer ## Constructor `Accelerometer()` Experimental Creates a new `Accelerometer` object. ## Instance properties _In addition to the properties listed below,`Accelerometer` inherits properties from its parent interfaces, `Sensor` and `EventTarget`._ `Accelerometer.x` Read only Experimental Returns a double containing the acceleration of the device along the device's x axis. `Accelerometer.y` Read only Experimental Returns a double containing the acceleration of the device along the device's y axis. `Accelerometer.z` Read only Experimental Returns a double containing the acceleration of the device along the device's z axis. ## Instance methods _`Accelerometer` doesn't have own methods. However, it inherits methods from its parent interfaces, `Sensor` and `EventTarget`._ ## Events _`Accelerometer` doesn't have own events. However, it inherits events from its parent interface, `Sensor`._ ## Example Acceleration is typically read in the `reading` event callback. In the example below this occurs sixty times a second. const acl = new Accelerometer({ frequency: 60 }); acl.addEventListener("reading", () => { console.log(`Acceleration along the X-axis ${acl.x}`); console.log(`Acceleration along the Y-axis ${acl.y}`); console.log(`Acceleration along the Z-axis ${acl.z}`); }); acl.start(); ## Specifications ## Browser compatibility | Desktop | Mobile ---|---|--- | Chrome | Edge | Firefox | Opera | Safari | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet | WebView Android `Accelerometer` | 67 | 79 | No | 54 | No | 67 | No | 48 | No | 9.0 | 67 `Accelerometer` | 67 | 79 | No | 54 | No | 67 | No | 48 | No | 9.0 | 67 `x` | 67 | 79 | No | 54 | No | 67 | No | 48 | No | 9.0 | 67 `y` | 67 | 79 | No | 54 | No | 67 | No | 48 | No | 9.0 | 67 `z` | 67 | 79 | No | 54 | No | 67 | No | 48 | No | 9.0 | 67 # Accelerometer: Accelerometer() constructor Limited availability This feature is not Baseline because it does not work in some of the most widely-used browsers. * Learn more * See full compatibility * Report feedback **Secure context:** This feature is available only in secure contexts (HTTPS), in some or all supporting browsers. **Experimental:** **This is an experimental technology** Check the Browser compatibility table carefully before using this in production. The `Accelerometer()` constructor creates a new `Accelerometer` object which returns the acceleration of the device along all three axes at the time it is read. ## Syntax new Accelerometer() new Accelerometer(options) ### Parameters `options` Optional Options are as follows: `frequency` Optional The desired number of times per second a sample should be taken, meaning the number of times per second the `reading` event will be called. A whole number or decimal may be used, the latter for frequencies less than a second. The actual reading frequency depends on the device hardware and consequently may be less than requested. `referenceFrame` Optional Either `'device'` or `'screen'`. The default is `'device'`. ### Exceptions `SecurityError` `DOMException` Use of this feature was blocked by a Permissions Policy. ## Specifications ## Browser compatibility | Desktop | Mobile ---|---|--- | Chrome | Edge | Firefox | Opera | Safari | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet | WebView Android `Accelerometer` | 67 | 79 | No | 54 | No | 67 | No | 48 | No | 9.0 | 67 ## See also * `reading` event # Accelerometer: x property Limited availability This feature is not Baseline because it does not work in some of the most widely-used browsers. * Learn more * See full compatibility * Report feedback **Secure context:** This feature is available only in secure contexts (HTTPS), in some or all supporting browsers. **Experimental:** **This is an experimental technology** Check the Browser compatibility table carefully before using this in production. The `x` read-only property of the `Accelerometer` interface returns a number specifying the acceleration of the device along its x-axis. ## Value A `Number`. ## Examples Acceleration is typically read in the `reading` event callback. In the example below this occurs sixty times a second. const accelerometer = new Accelerometer({ frequency: 60 }); accelerometer.addEventListener("reading", (e) => { console.log(`Acceleration along the X-axis ${accelerometer.x}`); console.log(`Acceleration along the Y-axis ${accelerometer.y}`); console.log(`Acceleration along the Z-axis ${accelerometer.z}`); }); accelerometer.start(); ## Specifications ## Browser compatibility | Desktop | Mobile ---|---|--- | Chrome | Edge | Firefox | Opera | Safari | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet | WebView Android `x` | 67 | 79 | No | 54 | No | 67 | No | 48 | No | 9.0 | 67 # Accelerometer: y property Limited availability This feature is not Baseline because it does not work in some of the most widely-used browsers. * Learn more * See full compatibility * Report feedback **Secure context:** This feature is available only in secure contexts (HTTPS), in some or all supporting browsers. **Experimental:** **This is an experimental technology** Check the Browser compatibility table carefully before using this in production. The `y` read-only property of the `Accelerometer` interface returns a number specifying the acceleration of the device along its y-axis. ## Value A `Number`. ## Examples Acceleration is typically read in the `reading` event callback. In the example below this occurs sixty times a second. const accelerometer = new Accelerometer({ frequency: 60 }); accelerometer.addEventListener("reading", (e) => { console.log(`Acceleration along the X-axis ${accelerometer.x}`); console.log(`Acceleration along the Y-axis ${accelerometer.y}`); console.log(`Acceleration along the Z-axis ${accelerometer.z}`); }); accelerometer.start(); ## Specifications ## Browser compatibility | Desktop | Mobile ---|---|--- | Chrome | Edge | Firefox | Opera | Safari | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet | WebView Android `y` | 67 | 79 | No | 54 | No | 67 | No | 48 | No | 9.0 | 67 # Accelerometer: z property Limited availability This feature is not Baseline because it does not work in some of the most widely-used browsers. * Learn more * See full compatibility * Report feedback **Secure context:** This feature is available only in secure contexts (HTTPS), in some or all supporting browsers. **Experimental:** **This is an experimental technology** Check the Browser compatibility table carefully before using this in production. The `z` read-only property of the `Accelerometer` interface returns a number specifying the acceleration of the device along its z-axis. ## Value A `Number`. ## Examples Acceleration is typically read in the `reading` event callback. In the example below this occurs sixty times a second. const accelerometer = new Accelerometer({ frequency: 60 }); accelerometer.addEventListener("reading", (e) => { console.log(`Acceleration along the X-axis ${accelerometer.x}`); console.log(`Acceleration along the Y-axis ${accelerometer.y}`); console.log(`Acceleration along the Z-axis ${accelerometer.z}`); }); accelerometer.start(); ## Specifications ## Browser compatibility | Desktop | Mobile ---|---|--- | Chrome | Edge | Firefox | Opera | Safari | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet | WebView Android `z` | 67 | 79 | No | 54 | No | 67 | No | 48 | No | 9.0 | 67 # AesCbcParams The `AesCbcParams` dictionary of the Web Crypto API represents the object that should be passed as the `algorithm` parameter into `SubtleCrypto.encrypt()`, `SubtleCrypto.decrypt()`, `SubtleCrypto.wrapKey()`, or `SubtleCrypto.unwrapKey()`, when using the AES-CBC algorithm. ## Instance properties `name` A string. This should be set to `AES-CBC`. `iv` An `ArrayBuffer`, a `TypedArray`, or a `DataView`. The initialization vector. Must be 16 bytes, unpredictable, and preferably cryptographically random. However, it need not be secret (for example, it may be transmitted unencrypted along with the ciphertext). ## Examples See the examples for `SubtleCrypto.encrypt()` and `SubtleCrypto.decrypt()`. ## Specifications ## Browser compatibility ## See also * CBC mode is defined in section 6.2 of the NIST SP800-38A standard. * `SubtleCrypto.encrypt()`. * `SubtleCrypto.decrypt()`. * `SubtleCrypto.wrapKey()`. * `SubtleCrypto.unwrapKey()`. # AesCtrParams The `AesCtrParams` dictionary of the Web Crypto API represents the object that should be passed as the `algorithm` parameter into `SubtleCrypto.encrypt()`, `SubtleCrypto.decrypt()`, `SubtleCrypto.wrapKey()`, or `SubtleCrypto.unwrapKey()`, when using the AES-CTR algorithm. AES is a block cipher, meaning that it splits the message into blocks and encrypts it a block at a time. In CTR mode, every time a block of the message is encrypted, an extra block of data is mixed in. This extra block is called the "counter block". A given counter block value must never be used more than once with the same key: * Given a message _n_ blocks long, a different counter block must be used for every block. * If the same key is used to encrypt more than one message, a different counter block must be used for all blocks across all messages. Typically this is achieved by splitting the initial counter block value into two concatenated parts: * A nonce (that is, a number that may only be used once). The nonce part of the block stays the same for every block in the message. Each time a new message is to be encrypted, a new nonce is chosen. Nonces don't have to be secret, but they must not be reused with the same key. * A counter. This part of the block gets incremented each time a block is encrypted. Essentially: the nonce should ensure that counter blocks are not reused from one message to the next, while the counter should ensure that counter blocks are not reused within a single message. **Note:** See Appendix B of the NIST SP800-38A standard for more information. ## Instance properties `name` A string. This should be set to `AES-CTR`. `counter` An `ArrayBuffer`, a `TypedArray`, or a `DataView` — the initial value of the counter block. This must be 16 bytes long (the AES block size). The rightmost `length` bits of this block are used for the counter, and the rest is used for the nonce. For example, if `length` is set to 64, then the first half of `counter` is the nonce and the second half is used for the counter. `length` A `Number` — the number of bits in the counter block that are used for the actual counter. The counter must be big enough that it doesn't wrap: if the message is `n` blocks and the counter is `m` bits long, then the following must be true: `n <= 2^m`. The NIST SP800-38A standard, which defines CTR, suggests that the counter should occupy half of the counter block (see Appendix B.2), so for AES it would be 64. ## Examples See the examples for `SubtleCrypto.encrypt()` and `SubtleCrypto.decrypt()`. ## Specifications ## Browser compatibility ## See also * CTR mode is defined in section 6.5 of the NIST SP800-38A standard. * `SubtleCrypto.encrypt()`. * `SubtleCrypto.decrypt()`. * `SubtleCrypto.wrapKey()`. * `SubtleCrypto.unwrapKey()`. # AesGcmParams The `AesGcmParams` dictionary of the Web Crypto API represents the object that should be passed as the `algorithm` parameter into `SubtleCrypto.encrypt()`, `SubtleCrypto.decrypt()`, `SubtleCrypto.wrapKey()`, or `SubtleCrypto.unwrapKey()`, when using the AES-GCM algorithm. For details of how to supply appropriate values for this parameter, see the specification for AES-GCM: NIST SP800-38D, in particular section 5.2.1.1 on Input Data. ## Instance properties `name` A string. This should be set to `AES-GCM`. `iv` An `ArrayBuffer`, a `TypedArray`, or a `DataView` with the initialization vector. This must be unique for every encryption operation carried out with a given key. Put another way: never reuse an IV with the same key. The AES-GCM specification recommends that the IV should be 96 bits long, and typically contains bits from a random number generator. Section 8.2 of the specification outlines methods for constructing IVs. Note that the IV does not have to be secret, just unique: so it is OK, for example, to transmit it in the clear alongside the encrypted message. `additionalData` Optional An `ArrayBuffer`, a `TypedArray`, or a `DataView`. This contains additional data that will not be encrypted but will be authenticated along with the encrypted data. If `additionalData` is given here then the same data must be given in the corresponding call to `decrypt()`: if the data given to the `decrypt()` call does not match the original data, the decryption will throw an exception. This gives you a way to authenticate associated data without having to encrypt it. The bit length of `additionalData` must be smaller than `2^64 - 1`. The `additionalData` property is optional and may be omitted without compromising the security of the encryption operation. `tagLength` Optional A `Number`. This determines the size in bits of the authentication tag generated in the encryption operation and used for authentication in the corresponding decryption. The Web Crypto API specification requires this to have one of the following values: 32, 64, 96, 104, 112, 120, or 128. On the other hand, the AES-GCM specification recommends that it should be 96, 104, 112, 120, or 128, although 32 or 64 bits may be acceptable in some applications. For additional guidance, see Appendix C of the NIST Publication on "Recommendation for Block Cipher Modes of Operation". `tagLength` is optional and defaults to 128 if it is not specified. ## Examples See the examples for `SubtleCrypto.encrypt()` and `SubtleCrypto.decrypt()`. ## Specifications ## Browser compatibility ## See also * `SubtleCrypto.encrypt()`. * `SubtleCrypto.decrypt()`. * `SubtleCrypto.wrapKey()`. * `SubtleCrypto.unwrapKey()`. # AesKeyGenParams The `AesKeyGenParams` dictionary of the Web Crypto API represents the object that should be passed as the `algorithm` parameter into `SubtleCrypto.generateKey()`, when generating an AES key: that is, when the algorithm is identified as any of AES-CBC, AES-CTR, AES-GCM, or AES-KW. ## Instance properties `name` A string. This should be set to `AES-CBC`, `AES-CTR`, `AES-GCM`, or `AES-KW`, depending on the algorithm you want to use. `length` A `Number` — the length in bits of the key to generate. This must be one of: 128, 192, or 256. ## Examples See the examples for `SubtleCrypto.generateKey()`. ## Specifications ## Browser compatibility ## See also * `SubtleCrypto.generateKey()`. # AmbientLightSensor Limited availability This feature is not Baseline because it does not work in some of the most widely-used browsers. * Learn more * See full compatibility * Report feedback **Secure context:** This feature is available only in secure contexts (HTTPS), in some or all supporting browsers. **Experimental:** **This is an experimental technology** Check the Browser compatibility table carefully before using this in production. The `AmbientLightSensor` interface of the Sensor APIs returns the current light level or illuminance of the ambient light around the hosting device. To use this sensor, the user must grant permission to the `'ambient-light- sensor'` device sensor through the Permissions API. This feature may be blocked by a Permissions Policy set on your server. EventTarget Sensor AmbientLightSensor ## Constructor `AmbientLightSensor()` Experimental Creates a new `AmbientLightSensor` object. ## Instance properties `AmbientLightSensor.illuminance` Read only Experimental Returns the current light level in lux of the ambient light level around the hosting device. ## Instance methods _`AmbientLightSensor` doesn't have own methods. However, it inherits methods from its parent interfaces, `Sensor` and `EventTarget`._ ## Events _`AmbientLightSensor` doesn't have own events. However, it inherits events from its parent interface, `Sensor`._ ## Example if ("AmbientLightSensor" in window) { const sensor = new AmbientLightSensor(); sensor.addEventListener("reading", (event) => { console.log("Current light level:", sensor.illuminance); }); sensor.addEventListener("error", (event) => { console.log(event.error.name, event.error.message); }); sensor.start(); } ## Specifications ## Browser compatibility | Desktop | Mobile ---|---|--- | Chrome | Edge | Firefox | Opera | Safari | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet | WebView Android `AmbientLightSensor` | 6756 | 7979 | No | 5443 | No | 6756 | No | No | No | No | No `AmbientLightSensor` | 6756 | 7979 | No | 5443 | No | 6756 | No | No | No | No | No `illuminance` | 67In Chrome 79, this method stopped returning floats and returned integers to avoid fingerprinting.56In Chrome 79, this method stopped returning floats and returned integers to avoid fingerprinting. | 79In Edge 79, this method stopped returning floats and returned integers to avoid fingerprinting.79In Edge 79, this method stopped returning floats and returned integers to avoid fingerprinting. | No | 54In Opera 66, this method stopped returning floats and returned integers to avoid fingerprinting.43In Opera 66, this method stopped returning floats and returned integers to avoid fingerprinting. | No | 67In Chrome Android 79, this method stopped returning floats and returned integers to avoid fingerprinting.56In Chrome Android 79, this method stopped returning floats and returned integers to avoid fingerprinting. | No | No | No | No | No # AmbientLightSensor: AmbientLightSensor() constructor Limited availability This feature is not Baseline because it does not work in some of the most widely-used browsers. * Learn more * See full compatibility * Report feedback **Secure context:** This feature is available only in secure contexts (HTTPS), in some or all supporting browsers. **Experimental:** **This is an experimental technology** Check the Browser compatibility table carefully before using this in production. The `AmbientLightSensor()` constructor creates a new `AmbientLightSensor` object, which returns the current light level or illuminance of the ambient light around the hosting device. ## Syntax new AmbientLightSensor() new AmbientLightSensor(options) ### Parameters `options` Optional Currently only one option is supported: `frequency` Optional The desired number of times per second a sample should be taken, meaning the number of times per second that `reading` event will be called. A whole number or decimal may be used, the latter for frequencies less than a second. The actual reading frequency depends on the device hardware and consequently may be less than requested. ### Exceptions `SecurityError` `DOMException` Use of this feature was blocked by a Permissions Policy. ## Specifications ## Browser compatibility | Desktop | Mobile ---|---|--- | Chrome | Edge | Firefox | Opera | Safari | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet | WebView Android `AmbientLightSensor` | 6756 | 7979 | No | 5443 | No | 6756 | No | No | No | No | No ## See also * `reading` event # AmbientLightSensor: illuminance property Limited availability This feature is not Baseline because it does not work in some of the most widely-used browsers. * Learn more * See full compatibility * Report feedback **Secure context:** This feature is available only in secure contexts (HTTPS), in some or all supporting browsers. **Experimental:** **This is an experimental technology** Check the Browser compatibility table carefully before using this in production. The `illuminance` read-only property of the `AmbientLightSensor` interface returns the current light level in lux of the ambient light level around the hosting device. ## Value A `Number` indicating the current light level in lux. ## Examples if ("AmbientLightSensor" in window) { const sensor = new AmbientLightSensor(); sensor.addEventListener("reading", (event) => { console.log("Current light level:", sensor.illuminance); }); sensor.addEventListener("error", (event) => { console.log(event.error.name, event.error.message); }); sensor.start(); } ## Specifications ## Browser compatibility | Desktop | Mobile ---|---|--- | Chrome | Edge | Firefox | Opera | Safari | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet | WebView Android `illuminance` | 67In Chrome 79, this method stopped returning floats and returned integers to avoid fingerprinting.56In Chrome 79, this method stopped returning floats and returned integers to avoid fingerprinting. | 79In Edge 79, this method stopped returning floats and returned integers to avoid fingerprinting.79In Edge 79, this method stopped returning floats and returned integers to avoid fingerprinting. | No | 54In Opera 66, this method stopped returning floats and returned integers to avoid fingerprinting.43In Opera 66, this method stopped returning floats and returned integers to avoid fingerprinting. | No | 67In Chrome Android 79, this method stopped returning floats and returned integers to avoid fingerprinting.56In Chrome Android 79, this method stopped returning floats and returned integers to avoid fingerprinting. | No | No | No | No | No # AnalyserNode Baseline Widely available This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015. * Learn more * See full compatibility * Report feedback The `AnalyserNode` interface represents a node able to provide real-time frequency and time-domain analysis information. It is an `AudioNode` that passes the audio stream unchanged from the input to the output, but allows you to take the generated data, process it, and create audio visualizations. An `AnalyserNode` has exactly one input and one output. The node works even if the output is not connected. EventTarget AudioNode AnalyserNode Number of inputs | `1` ---|--- Number of outputs | `1` (but may be left unconnected) Channel count mode | `"max"` Channel count | `2` Channel interpretation | `"speakers"` ## Constructor `AnalyserNode()` Creates a new instance of an `AnalyserNode` object. ## Instance properties _Inherits properties from its parent,`AudioNode`_. `AnalyserNode.fftSize` An unsigned long value representing the size of the FFT (Fast Fourier Transform) to be used to determine the frequency domain. `AnalyserNode.frequencyBinCount` Read only An unsigned long value half that of the FFT size. This generally equates to the number of data values you will have to play with for the visualization. `AnalyserNode.minDecibels` A double value representing the minimum power value in the scaling range for the FFT analysis data, for conversion to unsigned byte values — basically, this specifies the minimum value for the range of results when using `getByteFrequencyData()`. `AnalyserNode.maxDecibels` A double value representing the maximum power value in the scaling range for the FFT analysis data, for conversion to unsigned byte values — basically, this specifies the maximum value for the range of results when using `getByteFrequencyData()`. `AnalyserNode.smoothingTimeConstant` A double value representing the averaging constant with the last analysis frame — basically, it makes the transition between values over time smoother. ## Instance methods _Inherits methods from its parent,`AudioNode`_. `AnalyserNode.getFloatFrequencyData()` Copies the current frequency data into a `Float32Array` array passed into it. `AnalyserNode.getByteFrequencyData()` Copies the current frequency data into a `Uint8Array` (unsigned byte array) passed into it. `AnalyserNode.getFloatTimeDomainData()` Copies the current waveform, or time-domain, data into a `Float32Array` array passed into it. `AnalyserNode.getByteTimeDomainData()` Copies the current waveform, or time-domain, data into a `Uint8Array` (unsigned byte array) passed into it. ## Examples **Note:** See the guide Visualizations with Web Audio API for more information on creating audio visualizations. ### Basic usage The following example shows basic usage of an `AudioContext` to create an `AnalyserNode`, then `requestAnimationFrame` and `` to collect time domain data repeatedly and draw an "oscilloscope style" output of the current audio input. For more complete applied examples/information, check out our Voice-change-O-matic demo (see app.js lines 108-193 for relevant code). const audioCtx = new AudioContext(); // … const analyser = audioCtx.createAnalyser(); analyser.fftSize = 2048; const bufferLength = analyser.frequencyBinCount; const dataArray = new Uint8Array(bufferLength); analyser.getByteTimeDomainData(dataArray); // Connect the source to be analyzed source.connect(analyser); // Get a canvas defined with ID "oscilloscope" const canvas = document.getElementById("oscilloscope"); const canvasCtx = canvas.getContext("2d"); // draw an oscilloscope of the current audio source function draw() { requestAnimationFrame(draw); analyser.getByteTimeDomainData(dataArray); canvasCtx.fillStyle = "rgb(200 200 200)"; canvasCtx.fillRect(0, 0, canvas.width, canvas.height); canvasCtx.lineWidth = 2; canvasCtx.strokeStyle = "rgb(0 0 0)"; canvasCtx.beginPath(); const sliceWidth = (canvas.width * 1.0) / bufferLength; let x = 0; for (let i = 0; i < bufferLength; i++) { const v = dataArray[i] / 128.0; const y = (v * canvas.height) / 2; if (i === 0) { canvasCtx.moveTo(x, y); } else { canvasCtx.lineTo(x, y); } x += sliceWidth; } canvasCtx.lineTo(canvas.width, canvas.height / 2); canvasCtx.stroke(); } draw(); ## Specifications ## Browser compatibility | Desktop | Mobile ---|---|--- | Chrome | Edge | Firefox | Opera | Safari | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet | WebView Android `AnalyserNode` | 55 | 79 | 53 | 42 | 14.1 | 55 | 53 | 42 | 14.5 | 6.0 | 55 `AnalyserNode` | 14 | 12 | 25 | 15 | 6 | 18 | 25 | 14 | 6 | 1.0 | 4.4.3 `fftSize` | 14 | 12 | 25 | 15 | 6 | 18 | 25 | 14 | 6 | 1.0 | 4.4.3 `frequencyBinCount` | 14 | 12 | 25 | 15 | 6 | 18 | 25 | 14 | 6 | 1.0 | 4.4.3 `getByteFrequencyData` | 14 | 12 | 25 | 15 | 6 | 18 | 25 | 14 | 6 | 1.0 | 4.4.3 `getByteTimeDomainData` | 14 | 12 | 25 | 15 | 6 | 18 | 25 | 14 | 6 | 1.0 | 4.4.3 `getFloatFrequencyData` | 14 | 12 | 25 | 15 | 6 | 18 | 25 | 14 | 6 | 1.0 | 4.4.3 `getFloatTimeDomainData` | 35 | 12 | 30 | 22 | 14.1 | 35 | 30 | 22 | 14.5 | 3.0 | 37 `maxDecibels` | 14 | 12 | 25 | 15 | 6 | 18 | 25 | 14 | 6 | 1.0 | 4.4.3 `minDecibels` | 14 | 12 | 25 | 15 | 6 | 18 | 25 | 14 | 6 | 1.0 | 4.4.3 `smoothingTimeConstant` | 14 | 12 | 25 | 15 | 6 | 18 | 25 | 14 | 6 | 1.0 | 4.4.3 ## See also * Using the Web Audio API # AnalyserNode: AnalyserNode() constructor Baseline Widely available This feature is well established and works across many devices and browser versions. It’s been available across browsers since April 2021. * Learn more * See full compatibility * Report feedback The `AnalyserNode()` constructor of the Web Audio API creates a new `AnalyserNode` object instance. ## Syntax new AnalyserNode(context) new AnalyserNode(context, options) ### Parameters `context` A reference to an `AudioContext` or `OfflineAudioContext`. `options` Optional An object with the following properties, all optional: `fftSize` The desired initial size of the FFT for frequency-domain analysis. The default is `2048`. `maxDecibels` The desired initial maximum power in dB for FFT analysis. The default is `-30`. `minDecibels` The desired initial minimum power in dB for FFT analysis. The default is `-100`. `smoothingTimeConstant` The desired initial smoothing constant for the FFT analysis. The default is `0.8`. `channelCount` Represents an integer used to determine how many channels are used when up- mixing and down-mixing connections to any inputs to the node. (See `AudioNode.channelCount` for more information.) Its usage and precise definition depend on the value of `channelCountMode`. `channelCountMode` Represents an enumerated value describing the way channels must be matched between the node's inputs and outputs. (See `AudioNode.channelCountMode` for more information including default values.) `channelInterpretation` Represents an enumerated value describing the meaning of the channels. This interpretation will define how audio up-mixing and down-mixing will happen. The possible values are `"speakers"` or `"discrete"`. (See `AudioNode.channelCountMode` for more information including default values.) ## Specifications ## Browser compatibility | Desktop | Mobile ---|---|--- | Chrome | Edge | Firefox | Opera | Safari | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet | WebView Android `AnalyserNode` | 55 | 79 | 53 | 42 | 14.1 | 55 | 53 | 42 | 14.5 | 6.0 | 55 ## See also * `BaseAudioContext.createAnalyser()`, the equivalent factory method # AnalyserNode: fftSize property Baseline Widely available This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015. * Learn more * See full compatibility * Report feedback The `fftSize` property of the `AnalyserNode` interface is an unsigned long value and represents the window size in samples that is used when performing a Fast Fourier Transform (FFT) to get frequency domain data. ## Value An unsigned integer, representing the window size of the FFT, given in number of samples. A higher value will result in more details in the frequency domain but fewer details in the amplitude domain. Must be a power of 2 between 2^5 and 2^15, so one of: `32`, `64`, `128`, `256`, `512`, `1024`, `2048`, `4096`, `8192`, `16384`, and `32768`. Defaults to `2048`. ### Exceptions `IndexSizeError` `DOMException` Thrown if the value set is not a power of 2, or is outside the allowed range. ## Examples The following example shows basic usage of an `AudioContext` to create an `AnalyserNode`, then `requestAnimationFrame` and `` to collect time domain data repeatedly and draw an "oscilloscope style" output of the current audio input. For more complete applied examples/information, check out our Voice-change-O-matic demo (see app.js lines 108–193 for relevant code). const audioCtx = new AudioContext(); const analyser = audioCtx.createAnalyser(); // … analyser.fftSize = 2048; const bufferLength = analyser.frequencyBinCount; const dataArray = new Uint8Array(bufferLength); analyser.getByteTimeDomainData(dataArray); // draw an oscilloscope of the current audio source function draw() { drawVisual = requestAnimationFrame(draw); analyser.getByteTimeDomainData(dataArray); canvasCtx.fillStyle = "rgb(200 200 200)"; canvasCtx.fillRect(0, 0, WIDTH, HEIGHT); canvasCtx.lineWidth = 2; canvasCtx.strokeStyle = "rgb(0 0 0)"; canvasCtx.beginPath(); const sliceWidth = (WIDTH * 1.0) / bufferLength; let x = 0; for (let i = 0; i < bufferLength; i++) { const v = dataArray[i] / 128.0; const y = (v * HEIGHT) / 2; if (i === 0) { canvasCtx.moveTo(x, y); } else { canvasCtx.lineTo(x, y); } x += sliceWidth; } canvasCtx.lineTo(canvas.width, canvas.height / 2); canvasCtx.stroke(); } draw(); ## Specifications ## Browser compatibility | Desktop | Mobile ---|---|--- | Chrome | Edge | Firefox | Opera | Safari | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet | WebView Android `fftSize` | 14 | 12 | 25 | 15 | 6 | 18 | 25 | 14 | 6 | 1.0 | 4.4.3 ## See also * Using the Web Audio API # AnalyserNode: frequencyBinCount property Baseline Widely available This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015. * Learn more * See full compatibility * Report feedback The `frequencyBinCount` read-only property of the `AnalyserNode` interface contains the total number of data points available to `AudioContext` `sampleRate`. This is half of the `value` of the `AnalyserNode.fftSize`. The two methods' indices have a linear relationship with the frequencies they represent, between 0 and the Nyquist frequency. ## Value An unsigned integer, equal to the number of values that `AnalyserNode.getByteFrequencyData()` and `AnalyserNode.getFloatFrequencyData()` copy into the provided `TypedArray`. For technical reasons related to how the Fast Fourier transform is defined, it is always half the value of `AnalyserNode.fftSize`. Therefore, it will be one of `16`, `32`, `64`, `128`, `256`, `512`, `1024`, `2048`, `4096`, `8192`, and `16384`. ## Examples The following example shows basic usage of an `AudioContext` to create an `AnalyserNode`, then `requestAnimationFrame` and `` to collect frequency data repeatedly and draw a "winamp bar graph style" output of the current audio input. For more complete applied examples/information, check out our Voice-change-O-matic demo. const audioCtx = new AudioContext(); const analyser = audioCtx.createAnalyser(); analyser.minDecibels = -90; analyser.maxDecibels = -10; // … analyser.fftSize = 256; const bufferLength = analyser.frequencyBinCount; console.log(bufferLength); const dataArray = new Uint8Array(bufferLength); canvasCtx.clearRect(0, 0, WIDTH, HEIGHT); function draw() { drawVisual = requestAnimationFrame(draw); analyser.getByteFrequencyData(dataArray); canvasCtx.fillStyle = "rgb(0 0 0)"; canvasCtx.fillRect(0, 0, WIDTH, HEIGHT); const barWidth = (WIDTH / bufferLength) * 2.5 - 1; let barHeight; let x = 0; for (let i = 0; i < bufferLength; i++) { barHeight = dataArray[i]; canvasCtx.fillStyle = `rgb(${barHeight + 100} 50 50)`; canvasCtx.fillRect(x, HEIGHT - barHeight / 2, barWidth, barHeight / 2); x += barWidth; } } draw(); ## Specifications ## Browser compatibility | Desktop | Mobile ---|---|--- | Chrome | Edge | Firefox | Opera | Safari | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet | WebView Android `frequencyBinCount` | 14 | 12 | 25 | 15 | 6 | 18 | 25 | 14 | 6 | 1.0 | 4.4.3 ## See also * Using the Web Audio API # AnalyserNode: getByteFrequencyData() method Baseline Widely available This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015. * Learn more * See full compatibility * Report feedback The `getByteFrequencyData()` method of the `AnalyserNode` interface copies the current frequency data into a `Uint8Array` (unsigned byte array) passed into it. The frequency data is composed of integers on a scale from 0 to 255. Each item in the array represents the decibel value for a specific frequency. The frequencies are spread linearly from 0 to 1/2 of the sample rate. For example, for `48000` sample rate, the last item of the array will represent the decibel value for `24000` Hz. If the array has fewer elements than the `AnalyserNode.frequencyBinCount`, excess elements are dropped. If it has more elements than needed, excess elements are ignored. ## Syntax getByteFrequencyData(array) ### Parameters `array` The `Uint8Array` that the frequency domain data will be copied to. If the array has fewer elements than the `AnalyserNode.frequencyBinCount`, excess elements are dropped. If it has more elements than needed, excess elements are ignored. ### Return value None (`undefined`). ## Examples The following example shows basic usage of an `AudioContext` to create an `AnalyserNode`, then `requestAnimationFrame` and `` to collect frequency data repeatedly and draw a "winamp bar graph style" output of the current audio input. For more complete applied examples/information, check out our Voice-change-O-matic demo (see app.js lines 108–193 for relevant code). const audioCtx = new AudioContext(); const analyser = audioCtx.createAnalyser(); // … analyser.fftSize = 256; const bufferLength = analyser.frequencyBinCount; console.log(bufferLength); const dataArray = new Uint8Array(bufferLength); canvasCtx.clearRect(0, 0, WIDTH, HEIGHT); function draw() { drawVisual = requestAnimationFrame(draw); analyser.getByteFrequencyData(dataArray); canvasCtx.fillStyle = "rgb(0 0 0)"; canvasCtx.fillRect(0, 0, WIDTH, HEIGHT); const barWidth = (WIDTH / bufferLength) * 2.5; let barHeight; let x = 0; for (let i = 0; i < bufferLength; i++) { barHeight = dataArray[i]; canvasCtx.fillStyle = `rgb(${barHeight + 100} 50 50)`; canvasCtx.fillRect(x, HEIGHT - barHeight / 2, barWidth, barHeight / 2); x += barWidth + 1; } } draw(); ## Specifications ## Browser compatibility | Desktop | Mobile ---|---|--- | Chrome | Edge | Firefox | Opera | Safari | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet | WebView Android `getByteFrequencyData` | 14 | 12 | 25 | 15 | 6 | 18 | 25 | 14 | 6 | 1.0 | 4.4.3 ## See also * Using the Web Audio API # AnalyserNode: getByteTimeDomainData() method Baseline Widely available This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015. * Learn more * See full compatibility * Report feedback The `getByteTimeDomainData()` method of the `AnalyserNode` Interface copies the current waveform, or time-domain, data into a `Uint8Array` (unsigned byte array) passed into it. If the array has fewer elements than the `AnalyserNode.fftSize`, excess elements are dropped. If it has more elements than needed, excess elements are ignored. ## Syntax getByteTimeDomainData(array) ### Parameters `array` The `Uint8Array` that the time domain data will be copied to. If the array has fewer elements than the `AnalyserNode.fftSize`, excess elements are dropped. If it has more elements than needed, excess elements are ignored. ### Return value None (`undefined`). ## Examples The following example shows basic usage of an `AudioContext` to create an `AnalyserNode`, then `requestAnimationFrame` and `` to collect time domain data repeatedly and draw an "oscilloscope style" output of the current audio input. For more complete applied examples/information, check out our Voice-change-O-matic demo (see app.js lines 108–193 for relevant code). const audioCtx = new AudioContext(); const analyser = audioCtx.createAnalyser(); // … analyser.fftSize = 2048; const bufferLength = analyser.fftSize; const dataArray = new Uint8Array(bufferLength); analyser.getByteTimeDomainData(dataArray); // draw an oscilloscope of the current audio source function draw() { drawVisual = requestAnimationFrame(draw); analyser.getByteTimeDomainData(dataArray); canvasCtx.fillStyle = "rgb(200 200 200)"; canvasCtx.fillRect(0, 0, WIDTH, HEIGHT); canvasCtx.lineWidth = 2; canvasCtx.strokeStyle = "rgb(0 0 0)"; const sliceWidth = (WIDTH * 1.0) / bufferLength; let x = 0; canvasCtx.beginPath(); for (let i = 0; i < bufferLength; i++) { const v = dataArray[i] / 128.0; const y = (v * HEIGHT) / 2; if (i === 0) { canvasCtx.moveTo(x, y); } else { canvasCtx.lineTo(x, y); } x += sliceWidth; } canvasCtx.lineTo(WIDTH, HEIGHT / 2); canvasCtx.stroke(); } draw(); ## Specifications ## Browser compatibility | Desktop | Mobile ---|---|--- | Chrome | Edge | Firefox | Opera | Safari | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet | WebView Android `getByteTimeDomainData` | 14 | 12 | 25 | 15 | 6 | 18 | 25 | 14 | 6 | 1.0 | 4.4.3 ## See also * Using the Web Audio API # AnalyserNode: getFloatFrequencyData() method Baseline Widely available This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015. * Learn more * See full compatibility * Report feedback The `getFloatFrequencyData()` method of the `AnalyserNode` Interface copies the current frequency data into a `Float32Array` array passed into it. Each item in the array represents the decibel value for a specific frequency. The frequencies are spread linearly from 0 to 1/2 of the sample rate. For example, for a `48000` Hz sample rate, the last item of the array will represent the decibel value for `24000` Hz. If you need higher performance and don't care about precision, you can use `AnalyserNode.getByteFrequencyData()` instead, which works on a `Uint8Array`. ## Syntax getFloatFrequencyData(array) ### Parameters `array` The `Float32Array` that the frequency domain data will be copied to. For any sample which is silent, the value is `-Infinity`. If the array has fewer elements than the `AnalyserNode.frequencyBinCount`, excess elements are dropped. If it has more elements than needed, excess elements are ignored. ### Return value None (`undefined`). ## Examples const audioCtx = new AudioContext(); const analyser = audioCtx.createAnalyser(); // Float32Array should be the same length as the frequencyBinCount const myDataArray = new Float32Array(analyser.frequencyBinCount); // fill the Float32Array with data returned from getFloatFrequencyData() analyser.getFloatFrequencyData(myDataArray); ### Drawing a spectrum The following example shows basic usage of an `AudioContext` to connect a `MediaElementAudioSourceNode` to an `AnalyserNode`. While the audio is playing, we collect the frequency data repeatedly with `requestAnimationFrame()` and draw a "winamp bar graph style" to a `` element. For more complete applied examples/information, check out our Voice-change-O- matic demo (see app.js lines 108–193 for relevant code). ## Specifications ## Browser compatibility | Desktop | Mobile ---|---|--- | Chrome | Edge | Firefox | Opera | Safari | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet | WebView Android `getFloatFrequencyData` | 14 | 12 | 25 | 15 | 6 | 18 | 25 | 14 | 6 | 1.0 | 4.4.3 ## See also * Using the Web Audio API # AnalyserNode: getFloatTimeDomainData() method Baseline Widely available This feature is well established and works across many devices and browser versions. It’s been available across browsers since April 2021. * Learn more * See full compatibility * Report feedback The `getFloatTimeDomainData()` method of the `AnalyserNode` Interface copies the current waveform, or time-domain, data into a `Float32Array` array passed into it. Each array value is a _sample_ , the magnitude of the signal at a particular time. ## Syntax getFloatTimeDomainData(array) ### Parameters `array` The `Float32Array` that the time domain data will be copied to. If the array has fewer elements than the `AnalyserNode.fftSize`, excess elements are dropped. If it has more elements than needed, excess elements are ignored. ### Return value None (`undefined`). ## Examples The following example shows basic usage of an `AudioContext` to create an `AnalyserNode`, then `requestAnimationFrame` and `` to collect time domain data repeatedly and draw an "oscilloscope style" output of the current audio input. For more complete applied examples/information, check out our Voice-change-O-matic demo (see app.js lines 108–193 for relevant code). const audioCtx = new AudioContext(); const analyser = audioCtx.createAnalyser(); // … analyser.fftSize = 1024; const bufferLength = analyser.fftSize; console.log(bufferLength); const dataArray = new Float32Array(bufferLength); canvasCtx.clearRect(0, 0, WIDTH, HEIGHT); function draw() { drawVisual = requestAnimationFrame(draw); analyser.getFloatTimeDomainData(dataArray); canvasCtx.fillStyle = "rgb(200 200 200)"; canvasCtx.fillRect(0, 0, WIDTH, HEIGHT); canvasCtx.lineWidth = 2; canvasCtx.strokeStyle = "rgb(0 0 0)"; canvasCtx.beginPath(); const sliceWidth = (WIDTH * 1.0) / bufferLength; let x = 0; for (let i = 0; i < bufferLength; i++) { const v = dataArray[i] * 200.0; const y = HEIGHT / 2 + v; if (i === 0) { canvasCtx.moveTo(x, y); } else { canvasCtx.lineTo(x, y); } x += sliceWidth; } canvasCtx.lineTo(canvas.width, canvas.height / 2); canvasCtx.stroke(); } draw(); ## Specifications ## Browser compatibility | Desktop | Mobile ---|---|--- | Chrome | Edge | Firefox | Opera | Safari | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet | WebView Android `getFloatTimeDomainData` | 35 | 12 | 30 | 22 | 14.1 | 35 | 30 | 22 | 14.5 | 3.0 | 37 ## See also * Using the Web Audio API # AnalyserNode: maxDecibels property Baseline Widely available This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015. * Learn more * See full compatibility * Report feedback The `maxDecibels` property of the `AnalyserNode` interface is a double value representing the maximum power value in the scaling range for the FFT analysis data, for conversion to unsigned byte values — basically, this specifies the maximum value for the range of results when using `getByteFrequencyData()`. ## Value A double, representing the maximum decibel value for scaling the FFT analysis data, where `0` dB is the loudest possible sound, `-10` dB is a 10th of that, etc. The default value is `-30` dB. When getting data from `getByteFrequencyData()`, any frequencies with an amplitude of `maxDecibels` or higher will be returned as `255`. ### Exceptions `IndexSizeError` `DOMException` Thrown if a value less than or equal to `AnalyserNode.minDecibels` is set. ## Examples The following example shows basic usage of an `AudioContext` to create an `AnalyserNode`, then `requestAnimationFrame` and `` to collect frequency data repeatedly and draw a "winamp bar graph style" output of the current audio input. For more complete applied examples/information, check out our Voice-change-O-matic demo (see app.js lines 108–193 for relevant code). const audioCtx = new AudioContext(); const analyser = audioCtx.createAnalyser(); analyser.minDecibels = -90; analyser.maxDecibels = -10; // … analyser.fftSize = 256; const bufferLength = analyser.frequencyBinCount; console.log(bufferLength); const dataArray = new Uint8Array(bufferLength); canvasCtx.clearRect(0, 0, WIDTH, HEIGHT); function draw() { drawVisual = requestAnimationFrame(draw); analyser.getByteFrequencyData(dataArray); canvasCtx.fillStyle = "rgb(0 0 0)"; canvasCtx.fillRect(0, 0, WIDTH, HEIGHT); const barWidth = (WIDTH / bufferLength) * 2.5; let barHeight; let x = 0; for (let i = 0; i < bufferLength; i++) { barHeight = dataArray[i]; canvasCtx.fillStyle = `rgb(${barHeight + 100} 50 50)`; canvasCtx.fillRect(x, HEIGHT - barHeight / 2, barWidth, barHeight / 2); x += barWidth + 1; } } draw(); ## Specifications ## Browser compatibility | Desktop | Mobile ---|---|--- | Chrome | Edge | Firefox | Opera | Safari | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet | WebView Android `maxDecibels` | 14 | 12 | 25 | 15 | 6 | 18 | 25 | 14 | 6 | 1.0 | 4.4.3 ## See also * Using the Web Audio API # AnalyserNode: minDecibels property Baseline Widely available This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015. * Learn more * See full compatibility * Report feedback The `minDecibels` property of the `AnalyserNode` interface is a double value representing the minimum power value in the scaling range for the FFT analysis data, for conversion to unsigned byte values — basically, this specifies the minimum value for the range of results when using `getByteFrequencyData()`. ## Value A double, representing the minimum decibel value for scaling the FFT analysis data, where `0` dB is the loudest possible sound, `-10` dB is a 10th of that, etc. The default value is `-100` dB. When getting data from `getByteFrequencyData()`, any frequencies with an amplitude of `minDecibels` or lower will be returned as `0`. **Note:** If a value greater than `AnalyserNode.maxDecibels` is set, an `INDEX_SIZE_ERR` exception is thrown. ## Examples The following example shows basic usage of an `AudioContext` to create an `AnalyserNode`, then `requestAnimationFrame` and `` to collect frequency data repeatedly and draw a "winamp bar graph style" output of the current audio input. For more complete applied examples/information, check out our Voice-change-O-matic demo (see app.js lines 108–193 for relevant code). const audioCtx = new AudioContext(); const analyser = audioCtx.createAnalyser(); analyser.minDecibels = -90; analyser.maxDecibels = -10; // … analyser.fftSize = 256; const bufferLength = analyser.frequencyBinCount; console.log(bufferLength); const dataArray = new Uint8Array(bufferLength); canvasCtx.clearRect(0, 0, WIDTH, HEIGHT); function draw() { drawVisual = requestAnimationFrame(draw); analyser.getByteFrequencyData(dataArray); canvasCtx.fillStyle = "rgb(0 0 0)"; canvasCtx.fillRect(0, 0, WIDTH, HEIGHT); const barWidth = (WIDTH / bufferLength) * 2.5; let barHeight; let x = 0; for (let i = 0; i < bufferLength; i++) { barHeight = dataArray[i]; canvasCtx.fillStyle = `rgb(${barHeight + 100} 50 50)`; canvasCtx.fillRect(x, HEIGHT - barHeight / 2, barWidth, barHeight / 2); x += barWidth + 1; } } draw(); ## Specifications ## Browser compatibility | Desktop | Mobile ---|---|--- | Chrome | Edge | Firefox | Opera | Safari | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet | WebView Android `minDecibels` | 14 | 12 | 25 | 15 | 6 | 18 | 25 | 14 | 6 | 1.0 | 4.4.3 ## See also * Using the Web Audio API # AnalyserNode: smoothingTimeConstant property Baseline Widely available This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015. * Learn more * See full compatibility * Report feedback The `smoothingTimeConstant` property of the `AnalyserNode` interface is a double value representing the averaging constant with the last analysis frame. It's basically an average between the current buffer and the last buffer the `AnalyserNode` processed, and results in a much smoother set of value changes over time. ## Value A double within the range `0` to `1` (`0` meaning no time averaging). The default value is `0.8`. If 0 is set, there is no averaging done, whereas a value of 1 means "overlap the previous and current buffer quite a lot while computing the value", which essentially smooths the changes across `AnalyserNode.getFloatFrequencyData`/`AnalyserNode.getByteFrequencyData` calls. In technical terms, we apply a Blackman window and smooth the values over time. The default value is good enough for most cases. **Note:** If a value outside the range 0–1 is set, an `INDEX_SIZE_ERR` exception is thrown. ## Examples The following example shows basic usage of an `AudioContext` to create an `AnalyserNode`, then `requestAnimationFrame` and `` to collect frequency data repeatedly and draw a "winamp bar graph style" output of the current audio input. For more complete applied examples/information, check out our Voice-change-O-matic demo (see app.js lines 108–193 for relevant code). If you are curious about the effect the `smoothingTimeConstant()` has, try cloning the above example and setting `analyser.smoothingTimeConstant = 0;` instead. You'll notice that the value changes are much more jarring. const audioCtx = new AudioContext(); const analyser = audioCtx.createAnalyser(); analyser.minDecibels = -90; analyser.maxDecibels = -10; analyser.smoothingTimeConstant = 0.85; // … analyser.fftSize = 256; const bufferLength = analyser.frequencyBinCount; console.log(bufferLength); const dataArray = new Uint8Array(bufferLength); canvasCtx.clearRect(0, 0, WIDTH, HEIGHT); function draw() { drawVisual = requestAnimationFrame(draw); analyser.getByteFrequencyData(dataArray); canvasCtx.fillStyle = "rgb(0 0 0)"; canvasCtx.fillRect(0, 0, WIDTH, HEIGHT); const barWidth = (WIDTH / bufferLength) * 2.5; let barHeight; let x = 0; for (let i = 0; i < bufferLength; i++) { barHeight = dataArray[i]; canvasCtx.fillStyle = `rgb(${barHeight + 100} 50 50)`; canvasCtx.fillRect(x, HEIGHT - barHeight / 2, barWidth, barHeight / 2); x += barWidth + 1; } } draw(); ## Specifications ## Browser compatibility | Desktop | Mobile ---|---|--- | Chrome | Edge | Firefox | Opera | Safari | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet | WebView Android `smoothingTimeConstant` | 14 | 12 | 25 | 15 | 6 | 18 | 25 | 14 | 6 | 1.0 | 4.4.3 ## See also * Using the Web Audio API # ANGLE_instanced_arrays Baseline Widely available This feature is well established and works across many devices and browser versions. It’s been available across browsers since June 2016. * Learn more * See full compatibility * Report feedback The `ANGLE_instanced_arrays` extension is part of the WebGL API and allows to draw the same object, or groups of similar objects multiple times, if they share the same vertex data, primitive count and type. WebGL extensions are available using the `WebGLRenderingContext.getExtension()` method. For more information, see also Using Extensions in the WebGL tutorial. **Note:** This extension is only available to WebGL1 contexts. In WebGL2, the functionality of this extension is available on the WebGL2 context by default and the constants and methods are available without the `ANGLE_` suffix. Despite the name "ANGLE", this extension works on any device if the hardware supports it and not just on Windows when using the ANGLE library. "ANGLE" just indicates that this extension has been written by the ANGLE library authors. ## Constants This extension exposes one new constant, which can be used in the `gl.getVertexAttrib()` method: `ext.VERTEX_ATTRIB_ARRAY_DIVISOR_ANGLE` Returns a `GLint` describing the frequency divisor used for instanced rendering when used in the `gl.getVertexAttrib()` as the `pname` parameter. ## Instance methods This extension exposes three new methods. `ext.drawArraysInstancedANGLE()` Behaves identically to `gl.drawArrays()` except that multiple instances of the range of elements are executed, and the instance advances for each iteration. `ext.drawElementsInstancedANGLE()` Behaves identically to `gl.drawElements()` except that multiple instances of the set of elements are executed and the instance advances between each set. `ext.vertexAttribDivisorANGLE()` Modifies the rate at which generic vertex attributes advance when rendering multiple instances of primitives with `ext.drawArraysInstancedANGLE()` and `ext.drawElementsInstancedANGLE()`. ## Examples The following example shows how to draw a given geometry multiple times with a single draw call. **Warning:** The following is educational, not production level code. It should generally be avoided to construct data / buffers within the rendering loop or right before use. // enable the extension const ext = gl.getExtension("ANGLE_instanced_arrays"); // binding the geometry buffer as usual gl.bindBuffer(gl.ARRAY_BUFFER, geometryVertexBuffer); gl.enableVertexAttribArray(vertexPositionAttributeLocation); gl.vertexAttribPointer( vertexPositionAttributeLocation, 3, gl.FLOAT, false, 0, 0, ); // build position buffer const instancePositions = []; for (const instance of instances) { instancePositions.push( instance.position.x, instance.position.y, instance.position.z, ); } const instancePositionBuffer = createWebGLBufferFromData(instancePositions); // binding the instance position buffer as you would with any attribute gl.bindBuffer(gl.ARRAY_BUFFER, instancePositionBuffer); gl.enableVertexAttribArray(instancePositionAttributeLocation); gl.vertexAttribPointer( instancePositionAttributeLocation, 3, gl.FLOAT, false, 0, 0, ); // mark the attribute as instanced and advance it every single(1) instance rather than every vertex ext.vertexAttribDivisorANGLE(instancePositionAttributeLocation, 1); // draw geometry for each instance ext.drawArraysInstancedANGLE( gl.TRIANGLES, 0, numGeometryVertices, instances.length, ); ## Specifications ## Browser compatibility | Desktop | Mobile ---|---|--- | Chrome | Edge | Firefox | Opera | Safari | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet | WebView Android `ANGLE_instanced_arrays` | 3230–32Available only on macOS. | 12 | 47 | 1917–19Available only on macOS. | 8 | 30 | 47 | 18 | 8 | 2.0 | 4.4 `drawArraysInstancedANGLE` | 30 | 12 | 47 | 17 | 8 | 30 | 47 | 18 | 8 | 2.0 | 4.4 `drawElementsInstancedANGLE` | 30 | 12 | 47 | 17 | 8 | 30 | 47 | 18 | 8 | 2.0 | 4.4 `vertexAttribDivisorANGLE` | 30 | 12 | 47 | 17 | 8 | 30 | 47 | 18 | 8 | 2.0 | 4.4 ## See also * `WebGLRenderingContext.getExtension()` * `WebGL2RenderingContext.drawArraysInstanced()` * `WebGL2RenderingContext.drawElementsInstanced()` * `WebGL2RenderingContext.vertexAttribDivisor()` # ANGLE_instanced_arrays: drawArraysInstancedANGLE() method Baseline Widely available This feature is well established and works across many devices and browser versions. It’s been available across browsers since June 2016. * Learn more * See full compatibility * Report feedback The `ANGLE_instanced_arrays.drawArraysInstancedANGLE()` method of the WebGL API renders primitives from array data like the `gl.drawArrays()` method. In addition, it can execute multiple instances of the range of elements. **Note:** When using `WebGL2`, this method is available as `gl.drawArraysInstanced()` by default. ## Syntax drawArraysInstancedANGLE(mode, first, count, primcount) ### Parameters `mode` A `GLenum` specifying the type primitive to render. Possible values are: * `gl.POINTS`: Draws a single dot. * `gl.LINE_STRIP`: Draws a straight line to the next vertex. * `gl.LINE_LOOP`: Draws a straight line to the next vertex, and connects the last vertex back to the first. * `gl.LINES`: Draws a line between a pair of vertices. * `gl.TRIANGLE_STRIP` * `gl.TRIANGLE_FAN` * `gl.TRIANGLES`: Draws a triangle for a group of three vertices. `first` A `GLint` specifying the starting index in the array of vector points. `count` A `GLsizei` specifying the number of indices to be rendered. `primcount` A `GLsizei` specifying the number of instances of the range of elements to execute. ### Return value None (`undefined`). ### Exceptions * If `mode` is not one of the accepted values, a `gl.INVALID_ENUM` error is thrown. * If `first`, `count` or `primcount` are negative, a `gl.INVALID_VALUE` error is thrown. * if `gl.CURRENT_PROGRAM` is `null`, a `gl.INVALID_OPERATION` error is thrown. ## Examples const ext = gl.getExtension("ANGLE_instanced_arrays"); ext.drawArraysInstancedANGLE(gl.POINTS, 0, 8, 4); ## Specifications ## Browser compatibility | Desktop | Mobile ---|---|--- | Chrome | Edge | Firefox | Opera | Safari | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet | WebView Android `drawArraysInstancedANGLE` | 30 | 12 | 47 | 17 | 8 | 30 | 47 | 18 | 8 | 2.0 | 4.4 ## See also * `ext.drawElementsInstancedANGLE()` * `ext.vertexAttribDivisorANGLE()` * `WebGLRenderingContext.drawArrays()` * `WebGLRenderingContext.drawElements()` * `WebGL2RenderingContext.drawArraysInstanced()` * `WebGL2RenderingContext.drawElementsInstanced()` * `WebGL2RenderingContext.vertexAttribDivisor()` * `WEBGL_multi_draw.multiDrawArraysInstancedWEBGL()` # ANGLE_instanced_arrays: drawElementsInstancedANGLE() method Baseline Widely available This feature is well established and works across many devices and browser versions. It’s been available across browsers since June 2016. * Learn more * See full compatibility * Report feedback The `ANGLE_instanced_arrays.drawElementsInstancedANGLE()` method of the WebGL API renders primitives from array data like the `gl.drawElements()` method. In addition, it can execute multiple instances of a set of elements. **Note:** When using `WebGL2`, this method is available as `gl.drawElementsInstanced()` by default. ## Syntax drawElementsInstancedANGLE(mode, count, type, offset, primcount) ### Parameters `mode` A `GLenum` specifying the type primitive to render. Possible values are: * `gl.POINTS`: Draws a single dot. * `gl.LINE_STRIP`: Draws a straight line to the next vertex. * `gl.LINE_LOOP`: Draws a straight line to the next vertex, and connects the last vertex back to the first. * `gl.LINES`: Draws a line between a pair of vertices. * `gl.TRIANGLE_STRIP` * `gl.TRIANGLE_FAN` * `gl.TRIANGLES`: Draws a triangle for a group of three vertices. `count` A `GLsizei` specifying the number of elements to be rendered. `type` A `GLenum` specifying the type of the values in the element array buffer. Possible values are: * `gl.UNSIGNED_BYTE` * `gl.UNSIGNED_SHORT` * `gl.UNSIGNED_INT` when using the `OES_element_index_uint` extension. `offset` A `GLintptr` specifying an offset in the element array buffer. Must be a valid multiple of the size of the given `type`. `primcount` A `GLsizei` specifying the number of instances of the set of elements to execute. ### Return value None (`undefined`). ### Exceptions * If `mode` is not one of the accepted values, a `gl.INVALID_ENUM` error is thrown. * If `offset` is an invalid multiple of the size of the given type, a `gl.INVALID_OPERATION` error is thrown. * If `count` or `primcount` are negative, a `gl.INVALID_VALUE` error is thrown. ## Examples const ext = gl.getExtension("ANGLE_instanced_arrays"); ext.drawElementsInstancedANGLE(gl.POINTS, 2, gl.UNSIGNED_SHORT, 0, 4); ## Specifications ## Browser compatibility | Desktop | Mobile ---|---|--- | Chrome | Edge | Firefox | Opera | Safari | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet | WebView Android `drawElementsInstancedANGLE` | 30 | 12 | 47 | 17 | 8 | 30 | 47 | 18 | 8 | 2.0 | 4.4 ## See also * `ext.drawArraysInstancedANGLE()` * `ext.vertexAttribDivisorANGLE()` * `WebGLRenderingContext.drawArrays()` * `WebGLRenderingContext.drawElements()` * `WebGL2RenderingContext.drawArraysInstanced()` * `WebGL2RenderingContext.drawElementsInstanced()` * `WebGL2RenderingContext.vertexAttribDivisor()` * `WEBGL_multi_draw.multiDrawElementsInstancedWEBGL()` # ANGLE_instanced_arrays: vertexAttribDivisorANGLE() method Baseline Widely available This feature is well established and works across many devices and browser versions. It’s been available across browsers since June 2016. * Learn more * See full compatibility * Report feedback The **ANGLE_instanced_arrays.vertexAttribDivisorANGLE()** method of the WebGL API modifies the rate at which generic vertex attributes advance when rendering multiple instances of primitives with `ext.drawArraysInstancedANGLE()` and `ext.drawElementsInstancedANGLE()`. **Note:** When using `WebGL2`, this method is available as `gl.vertexAttribDivisor()` by default. ## Syntax vertexAttribDivisorANGLE(index, divisor) ### Parameters `index` A `GLuint` specifying the index of the generic vertex attributes. `divisor` A `GLuint` specifying the number of instances that will pass between updates of the generic attribute. ### Return value None (`undefined`). ## Examples const ext = gl.getExtension("ANGLE_instanced_arrays"); ext.vertexAttribDivisorANGLE(0, 2); ## Specifications ## Browser compatibility | Desktop | Mobile ---|---|--- | Chrome | Edge | Firefox | Opera | Safari | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet | WebView Android `vertexAttribDivisorANGLE` | 30 | 12 | 47 | 17 | 8 | 30 | 47 | 18 | 8 | 2.0 | 4.4 ## See also * `ext.drawArraysInstancedANGLE()` * `ext.drawElementsInstancedANGLE()` * `WebGLRenderingContext.drawArrays()` * `WebGLRenderingContext.drawElements()` * `WebGL2RenderingContext.drawArraysInstanced()` * `WebGL2RenderingContext.drawElementsInstanced()` * `WebGL2RenderingContext.vertexAttribDivisor()` # Animation Baseline Widely available This feature is well established and works across many devices and browser versions. It’s been available across browsers since March 2020. * Learn more * See full compatibility * Report feedback The `Animation` interface of the Web Animations API represents a single animation player and provides playback controls and a timeline for an animation node or source. EventTarget Animation ## Constructor `Animation()` Creates a new `Animation` object instance. ## Instance properties `Animation.currentTime` The current time value of the animation in milliseconds, whether running or paused. If the animation lacks a `timeline`, is inactive or hasn't been played yet, its value is `null`. `Animation.effect` Gets and sets the `AnimationEffect` associated with this animation. This will usually be a `KeyframeEffect` object. `Animation.finished` Read only Returns the current finished Promise for this animation. `Animation.id` Gets and sets the `String` used to identify the animation. `Animation.overallProgress` Read only Experimental Returns a number between `0` and `1` indicating the animation's overall progress towards its finished state. `Animation.pending` Read only Indicates whether the animation is currently waiting for an asynchronous operation such as initiating playback or pausing a running animation. `Animation.playState` Read only Returns an enumerated value describing the playback state of an animation. `Animation.playbackRate` Gets or sets the playback rate of the animation. `Animation.ready` Read only Returns the current ready Promise for this animation. `Animation.replaceState` Read only Indicates whether the animation is active, has been automatically removed after being replaced by another animation, or has been explicitly persisted by a call to `Animation.persist()`. `Animation.startTime` Gets or sets the scheduled time when an animation's playback should begin. `Animation.timeline` Gets or sets the `timeline` associated with this animation. ## Instance methods `Animation.cancel()` Clears all `keyframeEffects` caused by this animation and aborts its playback. `Animation.commitStyles()` Commits the current styling state of an animation to the element being animated, even after that animation has been removed. It will cause the current styling state to be written to the element being animated, in the form of properties inside a `style` attribute. `Animation.finish()` Seeks either end of an animation, depending on whether the animation is playing or reversing. `Animation.pause()` Suspends playing of an animation. `Animation.persist()` Explicitly persists an animation, preventing it from being automatically removed when another animation replaces it. `Animation.play()` Starts or resumes playing of an animation, or begins the animation again if it previously finished. `Animation.reverse()` Reverses playback direction, stopping at the start of the animation. If the animation is finished or unplayed, it will play from end to beginning. `Animation.updatePlaybackRate()` Sets the speed of an animation after first synchronizing its playback position. ## Events `cancel` Fires when the `Animation.cancel()` method is called or when the animation enters the `"idle"` play state from another state. `finish` Fires when the animation finishes playing. `remove` Fires when the animation is automatically removed by the browser. ## Accessibility concerns Blinking and flashing animation can be problematic for people with cognitive concerns such as Attention Deficit Hyperactivity Disorder (ADHD). Additionally, certain kinds of motion can be a trigger for Vestibular disorders, epilepsy, and migraine, and Scotopic sensitivity. Consider providing a mechanism for pausing or disabling animation, as well as using the Reduced Motion Media Query (or equivalent user agent client hint `Sec-CH-Prefers-Reduced-Motion`) to create a complimentary experience for users who have expressed a preference for no animated experiences. * Designing Safer Web Animation For Motion Sensitivity · An A List Apart Article * An Introduction to the Reduced Motion Media Query | CSS-Tricks * Responsive Design for Motion | WebKit * MDN Understanding WCAG, Guideline 2.2 explanations * Understanding Success Criterion 2.2.2 | W3C Understanding WCAG 2.0 ## Specifications ## Browser compatibility | Desktop | Mobile ---|---|--- | Chrome | Edge | Firefox | Opera | Safari | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet | WebView Android `Animation` | 75 | 79 | 48 | 62 | 13.1 | 75 | 48 | 54 | 13.4 | 11.0 | 75 `Animation` | 75 | 79 | 48 | 62 | 13.1 | 75 | 48 | 54 | 13.4 | 11.0 | 75 `cancel` | 75 | 79 | 48 | 62 | 13.1 | 75 | 48 | 54 | 13.4 | 11.0 | 75 `cancel_event` | 75 | 79 | 48 | 62 | 13.1 | 75 | 48 | 54 | 13.4 | 11.0 | 75 `commitStyles` | 84 | 84 | 75 | 70 | 13.1 | 84 | 79 | 60 | 13.4 | 14.0 | 84 `currentTime` | 75 | 79 | 48 | 62 | 13.1 | 75 | 48 | 54 | 13.4 | 11.0 | 75 `effect` | 75 | 79 | 63 | 62 | 13.1 | 75 | 63 | 54 | 13.4 | 11.0 | 75 `finish` | 75 | 79 | 48 | 62 | 13.1 | 75 | 48 | 54 | 13.4 | 11.0 | 75 `finish_event` | 75 | 79 | 48 | 62 | 13.1 | 75 | 48 | 54 | 13.4 | 11.0 | 75 `finished` | 84 | 84 | 63 | 70 | 13.1 | 84 | 63 | 60 | 13.4 | 14.0 | 84 `id` | 75 | 79 | 48 | 62 | 13.1 | 75 | 48 | 54 | 13.4 | 11.0 | 75 `overallProgress` | 133 | 133 | No | 118 | No | 133 | No | 88 | No | No | 133 `pause` | 75 | 79 | 48 | 62 | 13.1 | 75 | 48 | 54 | 13.4 | 11.0 | 75 `pending` | 76 | 79 | 59Before version 59, the pending status was reported by a `"pending"` value returned from `Animation.playState`. | 63 | 13.1 | 76 | 59Before version 59, the pending status was reported by a `"pending"` value returned from `Animation.playState`. | 54 | 13.4 | 12.0 | 76 `persist` | 84 | 84 | 75 | 70 | 13.1 | 84 | 79 | 60 | 13.4 | 14.0 | 84 `play` | 75 | 79 | 48 | 62 | 13.1 | 75 | 48 | 54 | 13.4 | 11.0 | 75 `playState` | 75Before Chrome 50/Opera 37, this property returned `idle` for an animation that had not yet started. Starting with Chrome 50/Opera 37, it shows `paused`. | 79 | 48Before Firefox 59, this property returned `pending` for Animations with incomplete asynchronous operations but as of Firefox 59 this is indicated by the separate `Animation.pending` property. This reflects recent changes to the specification. | 62Before Chrome 50/Opera 37, this property returned `idle` for an animation that had not yet started. Starting with Chrome 50/Opera 37, it shows `paused`. | 13.1 | 75Before Chrome Android 50/Opera 37, this property returned `idle` for an animation that had not yet started. Starting with Chrome Android 50/Opera 37, it shows `paused`. | 48Before Firefox for Android 59, this property returned `pending` for Animations with incomplete asynchronous operations but as of Firefox for Android 59 this is indicated by the separate `Animation.pending` property. This reflects recent changes to the specification. | 54Before Chrome 50/Opera 37, this property returned `idle` for an animation that had not yet started. Starting with Chrome 50/Opera 37, it shows `paused`. | 13.4 | 11.0Before Samsung Internet 5.0/Opera 37, this property returned `idle` for an animation that had not yet started. Starting with Samsung Internet 5.0/Opera 37, it shows `paused`. | 75Before WebView Android 50/Opera 37, this property returned `idle` for an animation that had not yet started. Starting with WebView Android 50/Opera 37, it shows `paused`. `playbackRate` | 75 | 79 | 48 | 62 | 13.1 | 75 | 48 | 54 | 13.4 | 11.0 | 75 `ready` | 84 | 84 | 63 | 70 | 13.1 | 84 | 63 | 60 | 13.4 | 14.0 | 84 `remove_event` | 84 | 84 | 75 | 70 | 13.1 | 84 | 79 | 60 | 13.4 | 14.0 | 84 `remove_filling_animation` | 84 | 84 | 75 | 70 | 13.1 | 84 | 79 | 60 | 13.4 | 14.0 | 84 `replaceState` | 84 | 84 | 75 | 70 | 13.1 | 84 | 79 | 60 | 13.4 | 14.0 | 84 `reverse` | 75 | 79 | 48 | 62 | 13.1 | 75 | 48 | 54 | 13.4 | 11.0 | 75 `startTime` | 75 | 79 | 48 | 62 | 13.1 | 75 | 48 | 54 | 13.4 | 11.0 | 75 `timeline` | 84 | 84 | 75Currently only the getter is supported | 70 | 13.1Currently only the getter is supported | 84 | 79Currently only the getter is supported | 60 | 13.4Currently only the getter is supported | 14.0 | 84 `updatePlaybackRate` | 76 | 79 | 60 | 63 | 13.1 | 76 | 60 | 54 | 13.4 | 12.0 | 76 ## See also * Web Animations API # Animation: Animation() constructor Baseline Widely available This feature is well established and works across many devices and browser versions. It’s been available across browsers since March 2020. * Learn more * See full compatibility * Report feedback The `Animation()` constructor of the Web Animations API returns a new `Animation` object instance. ## Syntax new Animation() new Animation(effect) new Animation(effect, timeline) ### Parameters `effect` Optional The target effect, as an object based on the `AnimationEffect` interface, to assign to the animation. Although in the future other effects such as `SequenceEffect`s or `GroupEffect`s might be possible, the only kind of effect currently available is `KeyframeEffect`. This can be `null` (which is the default) to indicate that there should be no effect applied. `timeline` Optional Specifies the `timeline` with which to associate the animation, as an object of a type based on the `AnimationTimeline` interface. The default value is `Document.timeline`, but this can be set to `null` as well. ## Examples In the Follow the White Rabbit example, the `Animation()` constructor is used to create an `Animation` for the `rabbitDownKeyframes` using the document's `timeline`: const rabbitDownAnimation = new Animation( rabbitDownKeyframes, document.timeline, ); ## Specifications ## Browser compatibility | Desktop | Mobile ---|---|--- | Chrome | Edge | Firefox | Opera | Safari | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet | WebView Android `Animation` | 75 | 79 | 48 | 62 | 13.1 | 75 | 48 | 54 | 13.4 | 11.0 | 75 ## See also * Web Animations API * `Animation` # Animation: cancel() method Baseline Widely available This feature is well established and works across many devices and browser versions. It’s been available across browsers since March 2020. * Learn more * See full compatibility * Report feedback The Web Animations API's `cancel()` method of the `Animation` interface clears all `KeyframeEffect`s caused by this animation and aborts its playback. **Note:** When an animation is cancelled, its `startTime` and `currentTime` are set to `null`. ## Syntax cancel() ### Parameters None. ### Return value None (`undefined`). ### Exceptions This method doesn't directly throw exceptions; however, if the animation's `playState` is anything but `"idle"` when cancelled, the current finished promise is rejected with a `DOMException` named `AbortError`. ## Specifications ## Browser compatibility | Desktop | Mobile ---|---|--- | Chrome | Edge | Firefox | Opera | Safari | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet | WebView Android `cancel` | 75 | 79 | 48 | 62 | 13.1 | 75 | 48 | 54 | 13.4 | 11.0 | 75 ## See also * Web Animations API * `KeyframeEffect` * `Animation` * `Animation.playState` * `Animation.finished` returns the promise this action will reject if the animation's `playState` is not `"idle"`. # Animation: cancel event Baseline Widely available This feature is well established and works across many devices and browser versions. It’s been available across browsers since March 2020. * Learn more * See full compatibility * Report feedback The `cancel` event of the `Animation` interface is fired when the `Animation.cancel()` method is called or when the animation enters the `"idle"` play state from another state, such as when the animation is removed from an element before it finishes playing. **Note:** Creating a new animation that is initially idle does not trigger a `cancel` event on the new animation. ## Syntax Use the event name in methods like `addEventListener()`, or set an event handler property. addEventListener("cancel", (event) => { }) oncancel = (event) => { } ## Event type An `AnimationPlaybackEvent`. Inherits from `Event`. Event AnimationPlaybackEvent ## Event properties _In addition to the properties listed below, properties from the parent interface,`Event`, are available._ `AnimationPlaybackEvent.currentTime` Read only The current time of the animation that generated the event. `AnimationPlaybackEvent.timelineTime` Read only The time value of the timeline of the animation that generated the event. ## Examples If this animation is canceled, remove its element. animation.oncancel = (event) => { animation.effect.target.remove(); }; ## Specifications ## Browser compatibility | Desktop | Mobile ---|---|--- | Chrome | Edge | Firefox | Opera | Safari | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet | WebView Android `cancel_event` | 75 | 79 | 48 | 62 | 13.1 | 75 | 48 | 54 | 13.4 | 11.0 | 75 ## See also * Web Animations API * `Animation` # Animation: commitStyles() method Baseline Widely available This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2020. * Learn more * See full compatibility * Report feedback The `commitStyles()` method of the Web Animations API's `Animation` interface writes the computed values of the animation's current styles into its target element's `style` attribute. `commitStyles()` works even if the animation has been automatically removed. `commitStyles()` can be used in combination with `fill` to cause the final state of an animation to persist after the animation ends. The same effect could be achieved with `fill` alone, but using indefinitely filling animations is discouraged. Animations take precedence over all static styles, so an indefinite filling animation can prevent the target element from ever being styled normally. Using `commitStyles()` writes the styling state into the element's `style` attribute, where they can be modified and replaced as normal. ## Syntax commitStyles() ### Parameters None. ### Return value None (`undefined`). ## Examples ### Committing the final state of an animation In this example we have two buttons, labeled "Commit styles" and "Fill forwards". Both buttons animate when you click them, and both buttons persist the final state of the animation. The difference, though, is that "Fill forwards" only uses `fill: "forwards"` to persist the animation's final state: this means that the browser has to maintain the animation's state indefinitely, or until it can be automatically removed. However, the "Commit styles" button waits for the animation to finish, then calls `commitStyles()`, then cancels the animation, so the finished style is captured as the value of the `style` attribute, rather than as the animation state. #### HTML
#### JavaScript const commitStyles = document.querySelector(".commit-styles"); let offset1 = 0; commitStyles.addEventListener("click", async (event) => { // Start the animation offset1 = 100 - offset1; const animation = commitStyles.animate( { transform: `translate(${offset1}px)` }, { duration: 500, fill: "forwards" }, ); // Wait for the animation to finish await animation.finished; // Commit animation state to style attribute animation.commitStyles(); // Cancel the animation animation.cancel(); }); const fillForwards = document.querySelector(".fill-forwards"); let offset2 = 0; fillForwards.addEventListener("click", async (event) => { // Start the animation offset2 = 100 - offset2; const animation = fillForwards.animate( { transform: `translate(${offset2}px)` }, { duration: 500, fill: "forwards" }, ); }); #### Result ## Specifications ## Browser compatibility | Desktop | Mobile ---|---|--- | Chrome | Edge | Firefox | Opera | Safari | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet | WebView Android `commitStyles` | 84 | 84 | 75 | 70 | 13.1 | 84 | 79 | 60 | 13.4 | 14.0 | 84 ## See also * Web Animations API * `Animation` for other methods and properties you can use to control web page animation. # Animation: currentTime property Baseline Widely available This feature is well established and works across many devices and browser versions. It’s been available across browsers since March 2020. * Learn more * See full compatibility * Report feedback The `Animation.currentTime` property of the Web Animations API returns and sets the current time value of the animation in milliseconds, whether running or paused. If the animation lacks a `timeline`, is inactive, or hasn't been played yet, `currentTime`'s return value is `null`. ## Value A number representing the current time in milliseconds, or `null` to deactivate the animation. ## Examples In the Drink Me/Eat Me game, Alice's height is animated so it can go from small to large or large to small. At the start of the game, her height is set between the two extremes by setting her animation's `currentTime` to half her `KeyframeEffect`'s duration: aliceChange.currentTime = aliceChange.effect.timing.duration / 2; A more generic means of seeking to the 50% mark of an animation would be: animation.currentTime = animation.effect.getComputedTiming().delay + animation.effect.getComputedTiming().activeDuration / 2; ## Reduced time precision To offer protection against timing attacks and fingerprinting, the precision of `animation.currentTime` might get rounded depending on browser settings. In Firefox, the `privacy.reduceTimerPrecision` preference is enabled by default and defaults to 2ms. You can also enable `privacy.resistFingerprinting`, in which case the precision will be 100ms or the value of `privacy.resistFingerprinting.reduceTimerPrecision.microseconds`, whichever is larger. For example, with reduced time precision, the result of `animation.currentTime` will always be a multiple of 0.002, or a multiple of 0.1 (or `privacy.resistFingerprinting.reduceTimerPrecision.microseconds`) with `privacy.resistFingerprinting` enabled. // reduced time precision (2ms) in Firefox 60 animation.currentTime; // Might be: // 23.404 // 24.192 // 25.514 // … // reduced time precision with `privacy.resistFingerprinting` enabled animation.currentTime; // Might be: // 49.8 // 50.6 // 51.7 // … ## Specifications ## Browser compatibility | Desktop | Mobile ---|---|--- | Chrome | Edge | Firefox | Opera | Safari | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet | WebView Android `currentTime` | 75 | 79 | 48 | 62 | 13.1 | 75 | 48 | 54 | 13.4 | 11.0 | 75 ## See also * `Animation` for other methods and properties you can use to control web page animation. * `Animation.startTime` for the time an animation is scheduled to start. * Web Animations API # Animation: effect property Baseline Widely available This feature is well established and works across many devices and browser versions. It’s been available across browsers since March 2020. * Learn more * See full compatibility * Report feedback The `Animation.effect` property of the Web Animations API gets and sets the target effect of an animation. The target effect may be either an effect object of a type based on `AnimationEffect`, such as `KeyframeEffect`, or `null`. ## Value A `AnimationEffect` object describing the target animation effect for the animation, or `null` to indicate no active effect. ## Specifications ## Browser compatibility | Desktop | Mobile ---|---|--- | Chrome | Edge | Firefox | Opera | Safari | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet | WebView Android `effect` | 75 | 79 | 63 | 62 | 13.1 | 75 | 63 | 54 | 13.4 | 11.0 | 75 ## See also * Web Animations API * `AnimationEffect` * `Animation` # Animation: finish() method Baseline Widely available This feature is well established and works across many devices and browser versions. It’s been available across browsers since March 2020. * Learn more * See full compatibility * Report feedback The `finish()` method of the Web Animations API's `Animation` Interface sets the current playback time to the end of the animation corresponding to the current playback direction. That is, if the animation is playing forward, it sets the playback time to the length of the animation sequence, and if the animation is playing in reverse (having had its `reverse()` method called), it sets the playback time to 0. ## Syntax finish() ### Parameters None. ### Return value None (`undefined`). ### Exceptions `InvalidState` The player's playback rate is 0 or the animation's playback rate is greater than 0 and the end time of the animation is infinity. ## Examples The following example shows how to use the `finish()` method and catch an `InvalidState` error. interfaceElement.addEventListener("mousedown", () => { try { player.finish(); } catch (e) { if (e instanceof InvalidState) { console.log("finish() called on paused or finished animation."); } else { logMyErrors(e); // Pass exception object to error handler } } }); The following example finishes all the animations on a single element, regardless of their direction of playback. elem.getAnimations().forEach((animation) => animation.finish()); ## Specifications ## Browser compatibility | Desktop | Mobile ---|---|--- | Chrome | Edge | Firefox | Opera | Safari | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet | WebView Android `finish` | 75 | 79 | 48 | 62 | 13.1 | 75 | 48 | 54 | 13.4 | 11.0 | 75 ## See also * Web Animations API * `Animation` for other methods and properties you can use to control web page animation. * `Animation.play()` to play an animation forward. * `Animation.reverse()` to play an animation backward. # Animation: finish event Baseline Widely available This feature is well established and works across many devices and browser versions. It’s been available across browsers since March 2020. * Learn more * See full compatibility * Report feedback The `finish` event of the `Animation` interface is fired when the animation finishes playing, either when the animation completes naturally, or when the `Animation.finish()` method is called to immediately cause the animation to finish up. **Note:** The `"paused"` play state supersedes the `"finished"` play state; if the animation is both paused and finished, the `"paused"` state is the one that will be reported. You can force the animation into the `"finished"` state by setting its `startTime` to `document.timeline.currentTime - (Animation.currentTime * Animation.playbackRate)`. ## Syntax Use the event name in methods like `addEventListener()`, or set an event handler property. addEventListener("finish", (event) => { }) onfinish = (event) => { } ## Event type An `AnimationPlaybackEvent`. Inherits from `Event`. Event AnimationPlaybackEvent ## Event properties _In addition to the properties listed below, properties from the parent interface,`Event`, are available._ `AnimationPlaybackEvent.currentTime` Read only The current time of the animation that generated the event. `AnimationPlaybackEvent.timelineTime` Read only The time value of the timeline of the animation that generated the event. ## Examples `Animation.onfinish` is used several times in the Alice in Web Animations API Land Growing/Shrinking Alice Game. Here is one instance where we add pointer events back to an element after its opacity animation has faded it in: // Add an animation to the game's ending credits const endingUI = document.getElementById("ending-ui"); const bringUI = endingUI.animate(keysFade, timingFade); // Pause said animation's credits bringUI.pause(); // This function removes pointer events on the credits. hide(endingUI); // When the credits are later faded in, // we re-add the pointer events when they're done bringUI.onfinish = (event) => { endingUI.style.pointerEvents = "auto"; }; ## Specifications ## Browser compatibility | Desktop | Mobile ---|---|--- | Chrome | Edge | Firefox | Opera | Safari | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet | WebView Android `finish_event` | 75 | 79 | 48 | 62 | 13.1 | 75 | 48 | 54 | 13.4 | 11.0 | 75 ## See also * Web Animations API * `Animation` * `Animation.finish()` # Animation: finished property Baseline Widely available This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2020. * Learn more * See full compatibility * Report feedback The `Animation.finished` read-only property of the Web Animations API returns a `Promise` which resolves once the animation has finished playing. **Note:** Every time the animation leaves the `finished` play state (that is, when it starts playing again), a new `Promise` is created for this property. The new `Promise` will resolve once the new animation sequence has completed. ## Value A `Promise` object which will resolve once the animation has finished running. ## Examples The following code waits until all animations running on the element `elem` have finished, then deletes the element from the DOM tree: Promise.all(elem.getAnimations().map((animation) => animation.finished)).then( () => elem.remove(), ); ## Specifications ## Browser compatibility | Desktop | Mobile ---|---|--- | Chrome | Edge | Firefox | Opera | Safari | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet | WebView Android `finished` | 84 | 84 | 63 | 70 | 13.1 | 84 | 63 | 60 | 13.4 | 14.0 | 84 ## See also * `KeyframeEffect` * Web Animations API * `Animation` # Animation: id property Baseline Widely available This feature is well established and works across many devices and browser versions. It’s been available across browsers since March 2020. * Learn more * See full compatibility * Report feedback The `Animation.id` property of the Web Animations API returns or sets a string used to identify the animation. ## Value A string which can be used to identify the animation, or `null` if the animation has no `id`. ## Examples In the Follow the White Rabbit example, you can assign the `rabbitDownAnimation` an `id` like so: rabbitDownAnimation.id = "rabbitGo"; ## Specifications ## Browser compatibility | Desktop | Mobile ---|---|--- | Chrome | Edge | Firefox | Opera | Safari | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet | WebView Android `id` | 75 | 79 | 48 | 62 | 13.1 | 75 | 48 | 54 | 13.4 | 11.0 | 75 ## See also * `KeyframeEffect` * Web Animations API * `Animation` # Animation: overallProgress property **Experimental:** **This is an experimental technology** Check the Browser compatibility table carefully before using this in production. The `overallProgress` read-only property of the `Animation` interface returns a number between `0` and `1` indicating the animation's overall progress towards its finished state. This is the overall progress across all of the animation's iterations, not each individual iteration. `overallProgress` works consistently across all animations, regardless of the type of `timeline`. ## Value A number between `0` and `1`, or `null` if the animation lacks a timeline, is inactive or hasn't been played yet, or if its `currentTime` is set to a non- time value. If the animation's `iterations` property is set to `Infinity`, or if its `currentTime` is set to a negative value, `overallProgress` will return `0`. If the animation's `duration` is set to `0`, `overallProgress` will return `1`. ## Examples ### Displaying a percentage progress This demo uses `overallProgress` to create a "percentage progress" readout, which is displayed to the screen while an animation runs. ### HTML The HTML contains a `

Progress: 0%

The demo's CSS provides some rudimentary styling, which is not important for understanding how the JavaScript works, therefore we have hidden it for brevity. ### JavaScript In the JavaScript, we start off by grabbing references to the `
    #### CSS div { width: 100px; height: 100px; background: red; transform: translate(100px); } #### JavaScript const target = document.getElementById("animation-target"); const persistentButton = document.getElementById("start-persistent"); const transientButton = document.getElementById("start-transient"); const cancelButton = document.getElementById("cancel"); persistentButton.addEventListener("click", () => startAnimation(true)); transientButton.addEventListener("click", () => startAnimation(false)); cancelButton.addEventListener("click", cancelTop); const stack = []; let offset = -100; function startAnimation(persist) { offset = -offset; const animation = target.animate( { transform: `translate(${100 + offset}px)` }, { duration: 500, fill: "forwards" }, ); stack.push(animation); if (persist) { animation.persist(); } // Add the animation to the displayed stack (implementation not shown) show(animation, offset); } function cancelTop() { stack.pop()?.cancel(); } #### Result Note that adding a new transient animation will replace any previously added transient animation. Those animations will be automatically removed, and their `replaceState` will be `"removed"`. However, persistent animations will not be removed. Also note that removed animations don't affect the display; the position of the `
    ` is determined by the most recent active or persisted animation. ## Specifications ## Browser compatibility | Desktop | Mobile ---|---|--- | Chrome | Edge | Firefox | Opera | Safari | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet | WebView Android `persist` | 84 | 84 | 75 | 70 | 13.1 | 84 | 79 | 60 | 13.4 | 14.0 | 84 ## See also * Web Animations API * `Animation` for other methods and properties you can use to control web page animation. * `Animation.replaceState` * `remove` event # Animation: play() method Baseline Widely available This feature is well established and works across many devices and browser versions. It’s been available across browsers since March 2020. * Learn more * See full compatibility * Report feedback The `play()` method of the Web Animations API's `Animation` Interface starts or resumes playing of an animation. If the animation is finished, calling `play()` restarts the animation, playing it from the beginning. ## Syntax play() ### Parameters None. ### Return value None (`undefined`). ## Examples In the Growing/Shrinking Alice Game example, clicking or tapping the cake causes Alice's growing animation (`aliceChange`) to play forward, causing her to get bigger, as well as triggering the cake's animation. Two `Animation.play()`s, one `EventListener`: // The cake has its own animation: const nommingCake = document .getElementById("eat-me_sprite") .animate( [{ transform: "translateY(0)" }, { transform: "translateY(-80%)" }], { fill: "forwards", easing: "steps(4, end)", duration: aliceChange.effect.timing.duration / 2, }, ); // Pause the cake's animation so it doesn't play immediately. nommingCake.pause(); // This function will play when ever a user clicks or taps const growAlice = () => { // Play Alice's animation. aliceChange.play(); // Play the cake's animation. nommingCake.play(); }; // When a user holds their mouse down or taps, call growAlice to make all the animations play. cake.addEventListener("mousedown", growAlice, false); cake.addEventListener("touchstart", growAlice, false); ## Specifications ## Browser compatibility | Desktop | Mobile ---|---|--- | Chrome | Edge | Firefox | Opera | Safari | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet | WebView Android `play` | 75 | 79 | 48 | 62 | 13.1 | 75 | 48 | 54 | 13.4 | 11.0 | 75 ## See also * Web Animations API * `Animation` for other methods and properties you can use to control web page animation. * `Animation.pause()` to pause an animation. * `Animation.reverse()` to play an animation backwards. * `Animation.finish()` to finish an animation. * `Animation.cancel()` to cancel an animation. # Animation: playbackRate property Baseline Widely available This feature is well established and works across many devices and browser versions. It’s been available across browsers since March 2020. * Learn more * See full compatibility * Report feedback The `Animation.playbackRate` property of the Web Animations API returns or sets the playback rate of the animation. Animations have a **playback rate** that provides a scaling factor from the rate of change of the animation's `timeline` time values to the animation's current time. The playback rate is initially `1`. ## Value Takes a number that can be 0, negative, or positive. Negative values reverse the animation. The value is a scaling factor, so for example a value of 2 would double the playback rate. **Note:** Setting an animation's `playbackRate` to `0` effectively pauses the animation (however, its `playState` does not necessarily become `paused`). ## Examples In the Growing/Shrinking Alice Game example, clicking or tapping the bottle causes Alice's growing animation (`aliceChange`) to reverse, causing her to shrink: const shrinkAlice = () => { aliceChange.playbackRate = -1; aliceChange.play(); }; // On tap or click, Alice will shrink. bottle.addEventListener("mousedown", shrinkAlice, false); bottle.addEventListener("touchstart", shrinkAlice, false); Contrariwise, clicking on the cake causes her to "grow," playing `aliceChange` forwards again: const growAlice = () => { aliceChange.playbackRate = 1; aliceChange.play(); }; // On tap or click, Alice will grow. cake.addEventListener("mousedown", growAlice, false); cake.addEventListener("touchstart", growAlice, false); In another example, the Red Queen's Race Game, Alice and the Red Queen are constantly slowing down: setInterval(() => { // Make sure the playback rate never falls below .4 if (redQueen_alice.playbackRate > 0.4) { redQueen_alice.playbackRate *= 0.9; } }, 3000); But clicking or tapping on them causes them to speed up by multiplying their `playbackRate`: const goFaster = () => { redQueen_alice.playbackRate *= 1.1; }; document.addEventListener("click", goFaster); document.addEventListener("touchstart", goFaster); ## Specifications ## Browser compatibility | Desktop | Mobile ---|---|--- | Chrome | Edge | Firefox | Opera | Safari | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet | WebView Android `playbackRate` | 75 | 79 | 48 | 62 | 13.1 | 75 | 48 | 54 | 13.4 | 11.0 | 75 ## See also * Web Animations API * `Animation` # Animation: playState property Baseline Widely available This feature is well established and works across many devices and browser versions. It’s been available across browsers since March 2020. * Learn more * See full compatibility * Report feedback The read-only `Animation.playState` property of the Web Animations API returns an enumerated value describing the playback state of an animation. ## Value `idle` The current time of the animation is unresolved and there are no pending tasks. `running` The animation is running. `paused` The animation was suspended and the `Animation.currentTime` property is not updating. `finished` The animation has reached one of its boundaries and the `Animation.currentTime` property is not updating. Previously, Web Animations defined a `pending` value to indicate that some asynchronous operation such as initiating playback was yet to complete. This is now indicated by the separate `Animation.pending` property. ## Examples In the Growing/Shrinking Alice Game example, players can get an ending with Alice crying into a pool of tears. In the game, for performance reasons, the tears should only be animating when they're visible. So they must be paused as soon as they are animated like so: // Setting up the tear animations tears.forEach((el) => { el.animate(tearsFalling, { delay: getRandomMsRange(-1000, 1000), // randomized for each tear duration: getRandomMsRange(2000, 6000), // randomized for each tear iterations: Infinity, easing: "cubic-bezier(0.6, 0.04, 0.98, 0.335)", }); el.pause(); }); // Play the tears falling when the ending needs to be shown. tears.forEach((el) => { el.play(); }); // Reset the crying tears animations and pause them. tears.forEach((el) => { el.pause(); el.currentTime = 0; }); ## Specifications ## Browser compatibility | Desktop | Mobile ---|---|--- | Chrome | Edge | Firefox | Opera | Safari | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet | WebView Android `playState` | 75Before Chrome 50/Opera 37, this property returned `idle` for an animation that had not yet started. Starting with Chrome 50/Opera 37, it shows `paused`. | 79 | 48Before Firefox 59, this property returned `pending` for Animations with incomplete asynchronous operations but as of Firefox 59 this is indicated by the separate `Animation.pending` property. This reflects recent changes to the specification. | 62Before Chrome 50/Opera 37, this property returned `idle` for an animation that had not yet started. Starting with Chrome 50/Opera 37, it shows `paused`. | 13.1 | 75Before Chrome Android 50/Opera 37, this property returned `idle` for an animation that had not yet started. Starting with Chrome Android 50/Opera 37, it shows `paused`. | 48Before Firefox for Android 59, this property returned `pending` for Animations with incomplete asynchronous operations but as of Firefox for Android 59 this is indicated by the separate `Animation.pending` property. This reflects recent changes to the specification. | 54Before Chrome 50/Opera 37, this property returned `idle` for an animation that had not yet started. Starting with Chrome 50/Opera 37, it shows `paused`. | 13.4 | 11.0Before Samsung Internet 5.0/Opera 37, this property returned `idle` for an animation that had not yet started. Starting with Samsung Internet 5.0/Opera 37, it shows `paused`. | 75Before WebView Android 50/Opera 37, this property returned `idle` for an animation that had not yet started. Starting with WebView Android 50/Opera 37, it shows `paused`. ## See also * Web Animations API * `Animation` for other methods and properties you can use to control web page animation. # Animation: ready property Baseline Widely available This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2020. * Learn more * See full compatibility * Report feedback The read-only `Animation.ready` property of the Web Animations API returns a `Promise` which resolves when the animation is ready to play. A new promise is created every time the animation enters the `"pending"` play state as well as when the animation is canceled, since in both of those scenarios, the animation is ready to be started again. **Note:** Since the same `Promise` is used for both pending `play` and pending `pause` requests, authors are advised to check the state of the animation when the promise is resolved. ## Value A `Promise` which resolves when the animation is ready to be played. You'll typically use a construct similar to this when using the ready promise: animation.ready.then(() => { // Do whatever needs to be done when // the animation is ready to run }); ## Examples In the following example, the state of the animation will be `running` when the **current ready Promise** is resolved because the animation does not leave the `pending` play state in between the calls to `pause` and `play` and hence the **current ready Promise** does not change. animation.pause(); animation.ready.then(() => { // Displays 'running' alert(animation.playState); }); animation.play(); ## Specifications ## Browser compatibility | Desktop | Mobile ---|---|--- | Chrome | Edge | Firefox | Opera | Safari | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet | WebView Android `ready` | 84 | 84 | 63 | 70 | 13.1 | 84 | 63 | 60 | 13.4 | 14.0 | 84 ## See also * Web Animations API * `Animation` * `Animation.playState` # Animation: remove event Baseline Widely available This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2020. * Learn more * See full compatibility * Report feedback The `remove` event of the `Animation` interface fires when the animation is automatically removed by the browser. ## Syntax Use the event name in methods like `addEventListener()`, or set an event handler property. addEventListener("remove", (event) => { }) onremove = (event) => { } ## Event type An `AnimationPlaybackEvent`. Inherits from `Event`. Event AnimationPlaybackEvent ## Event properties _In addition to the properties listed below, properties from the parent interface,`Event`, are available._ `AnimationPlaybackEvent.currentTime` Read only The current time of the animation that generated the event. `AnimationPlaybackEvent.timelineTime` Read only The time value of the timeline of the animation that generated the event. ## Examples ### Removing replaced animations In this example we have a `

    Click the button to start the animation (disabled by default to protect those who suffer migraines when experiencing such animations).

    Animations created: 0

    Animations removed: 0

    #### CSS :root, body { margin: 0; padding: 0; height: 100%; } button { margin: 0.5rem 0; } #### JavaScript const button = document.querySelector("#start"); let created = 0; let removed = 0; button.addEventListener( "click", () => { document.body.addEventListener("mousemove", (event) => { const animation = button.animate( { transform: `translate(${event.clientX}px, ${event.clientY}px)` }, { duration: 500, fill: "forwards" }, ); created++; showCounts(); // the remove event fires after the animation is removed animation.addEventListener("remove", () => { removed++; showCounts(); }); }); }, { once: true }, ); function showCounts() { document.getElementById("count-created").textContent = created; document.getElementById("count-removed").textContent = removed; } const reset = document.querySelector("#reset"); reset.addEventListener("click", () => { document.location.reload(); }); #### Result ## Specifications ## Browser compatibility | Desktop | Mobile ---|---|--- | Chrome | Edge | Firefox | Opera | Safari | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet | WebView Android `remove_event` | 84 | 84 | 75 | 70 | 13.1 | 84 | 79 | 60 | 13.4 | 14.0 | 84 ## See also * Web Animations API * `Animation`, `AnimationPlaybackEvent` * `Animation.replaceState`, to check whether an animation has been removed * `Animation.persist()`, to prevent removal of an animation # Animation: replaceState property Baseline Widely available This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2020. * Learn more * See full compatibility * Report feedback The read-only `Animation.replaceState` property of the Web Animations API indicates whether the animation has been removed by the browser automatically after being replaced by another animation. ## Value A string that represents the replace state of the animation. The value can be one of: `active` The initial value of the animation's replace state when the animation is created. `persisted` The animation has been explicitly persisted by invoking `Animation.persist()` on it. `removed` The animation has been removed by the browser automatically. ## Specifications ## Browser compatibility | Desktop | Mobile ---|---|--- | Chrome | Edge | Firefox | Opera | Safari | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet | WebView Android `replaceState` | 84 | 84 | 75 | 70 | 13.1 | 84 | 79 | 60 | 13.4 | 14.0 | 84 ## See also * Web Animations API * `Animation` * `remove` event * `Animation.persist()` # Animation: reverse() method Baseline Widely available This feature is well established and works across many devices and browser versions. It’s been available across browsers since March 2020. * Learn more * See full compatibility * Report feedback The `Animation.reverse()` method of the `Animation` Interface reverses the playback direction, meaning the animation ends at its beginning. If called on an unplayed animation, the whole animation is played backwards. If called on a paused animation, the animation will continue in reverse. ## Syntax reverse() ### Parameters None. ### Return value None (`undefined`). ## Examples In the Growing/Shrinking Alice Game example, clicking or tapping the bottle causes Alice's growing animation (`aliceChange`) to play backwards, causing her to get smaller. It is done by setting `aliceChange`'s `Animation.playbackRate` to `-1` like so: const shrinkAlice = () => { // play Alice's animation in reverse aliceChange.playbackRate = -1; aliceChange.play(); // play the bottle's animation drinking.play(); }; But it could also have been done by calling `reverse()` on `aliceChange` like so: const shrinkAlice = () => { // play Alice's animation in reverse aliceChange.reverse(); // play the bottle's animation drinking.play(); }; ## Specifications ## Browser compatibility | Desktop | Mobile ---|---|--- | Chrome | Edge | Firefox | Opera | Safari | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet | WebView Android `reverse` | 75 | 79 | 48 | 62 | 13.1 | 75 | 48 | 54 | 13.4 | 11.0 | 75 ## See also * Web Animations API * `Animation` for other methods and properties you can use to control web page animation. * `Animation.pause()` to pause an animation. * `Animation.play()` to move an animation forward. # Animation: startTime property Baseline Widely available This feature is well established and works across many devices and browser versions. It’s been available across browsers since March 2020. * Learn more * See full compatibility * Report feedback The `Animation.startTime` property of the `Animation` interface is a double- precision floating-point value which indicates the scheduled time when an animation's playback should begin. An animation's **start time** is the time value of its `timeline` when its target `KeyframeEffect` is scheduled to begin playback. An animation's **start time** is initially unresolved (meaning that it's `null` because it has no value). ## Value A floating-point number representing the current time in milliseconds, or `null` if no time is set. You can read this value to determine what the start time is currently set at, and you can change this value to make the animation start at a different time. ## Examples In the Running on Web Animations API example, we can sync all new animated cats by giving them all the same `startTime` as the original running cat: const catRunning = document .getElementById("withWAAPI") .animate(keyframes, timing); /* A function that makes new cats. */ function addCat() { const newCat = document.createElement("div"); newCat.classList.add("cat"); return newCat; } /* This is the function that adds a cat to the WAAPI column */ function animateNewCatWithWAAPI() { // make a new cat const newCat = addCat(); // animate said cat with the WAAPI's "animate" function const newAnimationPlayer = newCat.animate(keyframes, timing); // set the animation's start time to be the same as the original .cat#withWAAPI newAnimationPlayer.startTime = catRunning.startTime; // Add the cat to the pile. WAAPICats.appendChild(newCat); } ## Reduced time precision To offer protection against timing attacks and fingerprinting, the precision of `animation.startTime` might get rounded depending on browser settings. In Firefox, the `privacy.reduceTimerPrecision` preference is enabled by default and defaults to 2ms. You can also enable `privacy.resistFingerprinting`, in which case the precision will be 100ms or the value of `privacy.resistFingerprinting.reduceTimerPrecision.microseconds`, whichever is larger. For example, with reduced time precision, the result of `animation.startTime` will always be a multiple of 0.002, or a multiple of 0.1 (or `privacy.resistFingerprinting.reduceTimerPrecision.microseconds`) with `privacy.resistFingerprinting` enabled. // reduced time precision (2ms) in Firefox 60 animation.startTime; // Might be: // 23.404 // 24.192 // 25.514 // … // reduced time precision with `privacy.resistFingerprinting` enabled animation.startTime; // Might be: // 49.8 // 50.6 // 51.7 // … ## Specifications ## Browser compatibility | Desktop | Mobile ---|---|--- | Chrome | Edge | Firefox | Opera | Safari | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet | WebView Android `startTime` | 75 | 79 | 48 | 62 | 13.1 | 75 | 48 | 54 | 13.4 | 11.0 | 75 ## See also * Web Animations API * `Animation` * `Animation.currentTime` for the current time of the animation. # Animation: timeline property Baseline Widely available This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2020. * Learn more * See full compatibility * Report feedback The `Animation.timeline` property of the `Animation` interface returns or sets the `timeline` associated with this animation. A timeline is a source of time values for synchronization purposes, and is an `AnimationTimeline`-based object. By default, the animation's timeline and the `Document`'s timeline are the same. ## Value A timeline object to use as the timing source for the animation, or `null` to use the default, which is the `Document`'s timeline. ## Examples Here we set the animation's timeline to be the same as the document's timeline (this is the default timeline for all animations, by the way): animation.timeline = document.timeline; ## Specifications ## Browser compatibility | Desktop | Mobile ---|---|--- | Chrome | Edge | Firefox | Opera | Safari | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet | WebView Android `timeline` | 84 | 84 | 75Currently only the getter is supported | 70 | 13.1Currently only the getter is supported | 84 | 79Currently only the getter is supported | 60 | 13.4Currently only the getter is supported | 14.0 | 84 ## See also * Web Animations API * `Animation` * `AnimationTimeline` the parent object all timelines inherit from. * `DocumentTimeline` the only kind of timeline object available at this time. * `Document.timeline` is the default timeline all animations are assigned. # Animation: updatePlaybackRate() method Baseline Widely available This feature is well established and works across many devices and browser versions. It’s been available across browsers since March 2020. * Learn more * See full compatibility * Report feedback The `updatePlaybackRate()` method of the Web Animations API's `Animation` Interface sets the speed of an animation after first synchronizing its playback position. In some cases, an animation may run on a separate thread or process and will continue updating even while long-running JavaScript delays the main thread. In such a case, setting the `playbackRate` on the animation directly may cause the animation's playback position to jump since its playback position on the main thread may have drifted from the playback position where it is currently running. `updatePlaybackRate()` is an asynchronous method that sets the speed of an animation after synchronizing with its current playback position, ensuring that the resulting change in speed does not produce a sharp jump. After calling `updatePlaybackRate()` the animation's `playbackRate` is _not_ immediately updated. It will be updated once the animation's `ready` promise is resolved. ## Syntax updatePlaybackRate(playbackRate) ### Parameters `playbackRate` The new speed to set. This may be a positive number (to speed up or slow down the animation), a negative number (to make it play backwards), or zero (to effectively pause the animation). ### Return value None (`undefined`). ## Examples A speed selector component would benefit from smooth updating of `updatePlaybackRate()`, as demonstrated below: speedSelector.addEventListener("input", (evt) => { cartoon.updatePlaybackRate(parseFloat(evt.target.value)); cartoon.ready.then(() => { console.log(`Playback rate set to ${cartoon.playbackRate}`); }); }); ## Specifications ## Browser compatibility | Desktop | Mobile ---|---|--- | Chrome | Edge | Firefox | Opera | Safari | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet | WebView Android `updatePlaybackRate` | 76 | 79 | 60 | 63 | 13.1 | 76 | 60 | 54 | 13.4 | 12.0 | 76 ## See also * Web Animations API * `Animation.playbackRate` — read back the current playback rate or set it in a synchronous manner. * `Animation.reverse()` — invert the playback rate and restart playback if necessary. * `Animation` — contains other methods and properties you can use to control web page animation. # AnimationEffect Baseline Widely available This feature is well established and works across many devices and browser versions. It’s been available across browsers since March 2020. * Learn more * See full compatibility * Report feedback The `AnimationEffect` interface of the Web Animations API is an interface representing animation effects. `AnimationEffect` is an abstract interface and so isn't directly instantiable. However, concrete interfaces such as `KeyframeEffect` inherit from it, and instances of these interfaces can be passed to `Animation` objects for playing, and may also be used by CSS Animations and Transitions. ## Instance methods `AnimationEffect.getTiming()` Returns the object associated with the animation containing all the animation's timing values. `AnimationEffect.getComputedTiming()` Returns the calculated timing properties for this `AnimationEffect`. `AnimationEffect.updateTiming()` Updates the specified timing properties of this `AnimationEffect`. ## Specifications ## Browser compatibility | Desktop | Mobile ---|---|--- | Chrome | Edge | Firefox | Opera | Safari | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet | WebView Android `AnimationEffect` | 75 | 79 | 6348–63 | 62 | 13.1 | 75 | 6348–63 | 54 | 13.4 | 11.0 | 75 `getComputedTiming` | 75 | 79 | 63 | 62 | 13.1 | 75 | 63 | 54 | 13.4 | 11.0 | 75 `getTiming` | 75 | 79 | 63 | 62 | 13.1 | 75 | 63 | 54 | 13.4 | 11.0 | 75 `updateTiming` | 75 | 79 | 63 | 62 | 13.1 | 75 | 63 | 54 | 13.4 | 11.0 | 75 ## See also * Web Animations API * `Animation.effect` # AnimationEffect: getComputedTiming() method Baseline Widely available This feature is well established and works across many devices and browser versions. It’s been available across browsers since March 2020. * Learn more * See full compatibility * Report feedback The `getComputedTiming()` method of the `AnimationEffect` interface returns the calculated timing properties for this animation effect. **Note:** These values are comparable to the computed styles of an Element returned using `window.getComputedStyle(elem)`. ## Syntax getComputedTiming() ### Parameters None. ### Return value An object which contains: * all of the properties of the object returned by `AnimationEffect.getTiming()`, except that any `"auto"` values are replaced by computed values that may depend on the type of `AnimationEffect`. * the following additional properties: `endTime` A `number` indicating the end time of the effect in milliseconds from the effect's start. This is equal to `activeDuration` plus `delay` and `endDelay`. `activeDuration` A `number` indicating the total duration in milliseconds of all iterations of the effect. This is equal to `duration` multiplied by `iterations` (or zero if that product would be `NaN`). `localTime` A `number` or `null`. Indicates the length of time in milliseconds that the effect has run. This is equal to the `currentTime` of the associated animation, or `null` if the effect is not associated with an animation. `progress` `null` or a `number` at least `0` and less than `1`. Indicates the effect's progress through its current iteration. At the start of the `activeDuration`, this equals the fractional part of `iterationStart`. Returns `null` if the effect isn't mid-iteration, for example because the effect is in the `delay` or `endDelay` periods, the effect is finished, or `localTime` is `null`. `currentIteration` `null` or an integer `number`. Indicates the index of the current iteration. At the start of the `activeDuration`, this equals the integer part of `iterationStart`. Returns `null` whenever `progress` is `null`. ## Specifications ## Browser compatibility | Desktop | Mobile ---|---|--- | Chrome | Edge | Firefox | Opera | Safari | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet | WebView Android `getComputedTiming` | 75 | 79 | 63 | 62 | 13.1 | 75 | 63 | 54 | 13.4 | 11.0 | 75 ## See also * Web Animations API * `AnimationEffect` * `Animation` # AnimationEffect: getTiming() method Baseline Widely available This feature is well established and works across many devices and browser versions. It’s been available across browsers since March 2020. * Learn more * See full compatibility * Report feedback The `AnimationEffect.getTiming()` method of the `AnimationEffect` interface returns an object containing the timing properties for the Animation Effect. **Note:** Several of the timing properties returned by `getTiming()` may take on the placeholder value `"auto"`. To obtain resolved values for use in timing computations, instead use `AnimationEffect.getComputedTiming()`. In the future, `"auto"` or similar values might be added to the types of more timing properties, and new types of `AnimationEffect` might resolve `"auto"` to different values. ## Syntax getTiming() ### Parameters None. ### Return value An object containing the following properties: `delay` The `number` of milliseconds of delay before the start of the effect. (See also `animation-delay`.) `direction` `"normal"`, `"reverse"`, `"alternate"`, or `"alternate-reverse"`. Indicates whether the effect runs forwards (`"normal"`), backwards (`"reverse"`), switches direction after each iteration (`"alternate"`), or runs backwards and switches direction after each iteration (`"alternate- reverse"`). (See also `animation-direction`.) `duration` A `number` of milliseconds or the `string` `"auto"`. Indicates the time one iteration of the animation takes to complete. The meaning of `"auto"` may differ depending on the type of effect; for `KeyframeEffect`, `"auto"` is the same as `0`. (See also `animation-duration`.) `easing` A `string` representing an `` describing the rate of change of the effect over time. (See also `animation-timing-function`.) `endDelay` The `number` of milliseconds of delay after the end of the effect. This is primarily of use when sequencing animations based on the end time of another animation. `fill` `"none"`, `"forwards"`, `"backwards"`, `"both"`, or `"auto"`. Indicates whether the effect is reflected by its target(s) prior to playing (`"backwards"`), retained after the effect has completed (`"forwards"`), `"both"`, or neither (`"none"`). The meaning of `"auto"` may differ depending on the type of effect; for `KeyframeEffect`, `"auto"` is the same as `"none"`. (See also `animation-fill-mode`.) `iterations` The `number` of times the effect will repeat. A value of `Infinity` indicates that the effect repeats indefinitely. (See also `animation-iteration-count`.) `iterationStart` A `number` indicating at what point in the iteration the effect starts. For example, an effect with an `iterationStart` of 0.5 and 2 `iterations` would start halfway through its first iteration and end halfway through a third iteration. ## Specifications ## Browser compatibility | Desktop | Mobile ---|---|--- | Chrome | Edge | Firefox | Opera | Safari | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet | WebView Android `getTiming` | 75 | 79 | 63 | 62 | 13.1 | 75 | 63 | 54 | 13.4 | 11.0 | 75 ## See also * Web Animations API * `AnimationEffect` # AnimationEffect: updateTiming() method Baseline Widely available This feature is well established and works across many devices and browser versions. It’s been available across browsers since March 2020. * Learn more * See full compatibility * Report feedback The `updateTiming()` method of the `AnimationEffect` interface updates the specified timing properties for an animation effect. ## Syntax updateTiming(timing) ### Parameters `timing` Optional An object containing zero or more of the properties from the return value of `AnimationEffect.getTiming()`, representing the timing properties to update. ### Return value None (`undefined`). ### Exceptions `TypeError` Thrown if invalid values are provided for any of the timing properties. ### Examples #### Side effects `updateTiming()` may cause any associated `Animation` to start or stop playing, if for example the effect of a running animation is shortened such that its end time is before `Animation.currentTime` or the effect of a finished animation is lengthened such that its end time is after `Animation.currentTime`. const animation = document.body.animate([], { duration: 1000 }); animation.finish(); console.log(animation.playState); // finished animation.effect.updateTiming({ duration: 2000 }); console.log(animation.playState); // running ## Specifications ## Browser compatibility | Desktop | Mobile ---|---|--- | Chrome | Edge | Firefox | Opera | Safari | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet | WebView Android `updateTiming` | 75 | 79 | 63 | 62 | 13.1 | 75 | 63 | 54 | 13.4 | 11.0 | 75 ## See also * Web Animations API * `AnimationEffect` * `Animation` * `AnimationEffect.getTiming()` * `AnimationEffect.getComputedTiming()` # AnimationEvent Baseline Widely available This feature is well established and works across many devices and browser versions. It’s been available across browsers since September 2015. * Learn more * See full compatibility * Report feedback The `AnimationEvent` interface represents events providing information related to animations. Event AnimationEvent ## Constructor `AnimationEvent()` Creates an `AnimationEvent` event with the given parameters. ## Instance properties _Also inherits properties from its parent`Event`_. `AnimationEvent.animationName` Read only A string containing the value of the `animation-name` that generated the animation. `AnimationEvent.elapsedTime` Read only A `float` giving the amount of time the animation has been running, in seconds, when this event fired, excluding any time the animation was paused. For an `animationstart` event, `elapsedTime` is `0.0` unless there was a negative value for `animation-delay`, in which case the event will be fired with `elapsedTime` containing `(-1 * delay)`. `AnimationEvent.pseudoElement` Read only A string, starting with `'::'`, containing the name of the pseudo-element the animation runs on. If the animation doesn't run on a pseudo-element but on the element, an empty string: `''`. ## Instance methods _Inherits methods from its parent,`Event`_. ## Specifications ## Browser compatibility | Desktop | Mobile ---|---|--- | Chrome | Edge | Firefox | Opera | Safari | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet | WebView Android `AnimationEvent` | 43 | 14 | 23 | 30 | 96 | 43 | 23 | 30 | 96 | 4.0 | 43 `AnimationEvent` | 431–70 | 12 | 5 | 3015–5712.1–1512–15 | 94 | 4318–70 | 5 | 3014–4912.1–1412–14 | 93.2 | 4.01.0–10.0 | 434.4–70 `animationName` | 43 | 12 | 5 | 30 | 9 | 43 | 5 | 30 | 9 | 4.0 | 43 `elapsedTime` | 43 | 12 | 5 | 30 | 9 | 43 | 5 | 30 | 9 | 4.0 | 43 `pseudoElement` | 68 | 79 | 23 | 55 | 13.1 | 68 | 23 | 48 | 13.4 | 10.0 | 68 ## See also * Using CSS animations * Animation-related CSS properties and at-rules: `animation`, `animation-composition`, `animation-delay`, `animation-direction`, `animation-duration`, `animation-fill-mode`, `animation-iteration-count`, `animation-name`, `animation-play-state`, `animation-timing-function`, `@keyframes`. # AnimationEvent: AnimationEvent() constructor Baseline Widely available This feature is well established and works across many devices and browser versions. It’s been available across browsers since August 2016. * Learn more * See full compatibility * Report feedback The `AnimationEvent()` constructor returns a new `AnimationEvent` object, representing an event in relation with an animation. ## Syntax new AnimationEvent(type) new AnimationEvent(type, options) ### Parameters `type` A string with the name of the type of the `AnimationEvent`. It is case- sensitive and browsers set it to `animationstart`, `animationend`, or `animationiteration`. `options` Optional An object that, _in addition of the properties defined in`Event()`_, has the following properties: `animationName` Optional A string containing the value of the `animation-name` CSS property associated with the transition. It defaults to `""`. `elapsedTime` Optional A `float` giving the amount of time the animation has been running, in seconds, when this event fired, excluding any time the animation was paused. For an `animationstart` event, `elapsedTime` is `0.0` unless there was a negative value for `animation-delay`, in which case the event will be fired with `elapsedTime` containing `(-1 * delay)`. It defaults to `0.0`. `pseudoElement` Optional A string, starting with `"::"`, containing the name of the pseudo-element the animation runs on. If the animation doesn't run on a pseudo-element but on the element itself, specify an empty string: `""`. It defaults to `""`. ## Specifications ## Browser compatibility | Desktop | Mobile ---|---|--- | Chrome | Edge | Firefox | Opera | Safari | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet | WebView Android `AnimationEvent` | 43 | 14 | 23 | 30 | 96 | 43 | 23 | 30 | 96 | 4.0 | 43 ## See also * Using CSS animations * Animation-related CSS properties and at-rules: `animation`, `animation-delay`, `animation-direction`, `animation-duration`, `animation-fill-mode`, `animation-iteration-count`, `animation-name`, `animation-play-state`, `animation-timing-function`, `@keyframes` * The `AnimationEvent` interface it belongs to. # AnimationEvent: animationName property Baseline Widely available This feature is well established and works across many devices and browser versions. It’s been available across browsers since September 2015. * Learn more * See full compatibility * Report feedback The `AnimationEvent.animationName` read-only property is a string containing the value of the `animation-name` CSS property associated with the transition. ## Value A string containing the value of the `animation-name` CSS property. ## Specifications ## Browser compatibility | Desktop | Mobile ---|---|--- | Chrome | Edge | Firefox | Opera | Safari | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet | WebView Android `animationName` | 43 | 12 | 5 | 30 | 9 | 43 | 5 | 30 | 9 | 4.0 | 43 ## See also * Using CSS animations * Animation-related CSS properties and at-rules: `animation`, `animation-delay`, `animation-direction`, `animation-duration`, `animation-fill-mode`, `animation-iteration-count`, `animation-name`, `animation-play-state`, `animation-timing-function`, `@keyframes`. * The `AnimationEvent` interface it belongs to. # AnimationEvent: elapsedTime property Baseline Widely available This feature is well established and works across many devices and browser versions. It’s been available across browsers since September 2015. * Learn more * See full compatibility * Report feedback The `AnimationEvent.elapsedTime` read-only property is a `float` giving the amount of time the animation has been running, in seconds, when this event fired, excluding any time the animation was paused. For an `animationstart` event, `elapsedTime` is `0.0` unless there was a negative value for `animation-delay`, in which case the event will be fired with `elapsedTime` containing `(-1 * delay)`. ## Value A `float` giving the amount of time in seconds. ## Specifications ## Browser compatibility | Desktop | Mobile ---|---|--- | Chrome | Edge | Firefox | Opera | Safari | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet | WebView Android `elapsedTime` | 43 | 12 | 5 | 30 | 9 | 43 | 5 | 30 | 9 | 4.0 | 43 ## See also * Using CSS animations * Animation-related CSS properties and at-rules: `animation`, `animation-delay`, `animation-direction`, `animation-duration`, `animation-fill-mode`, `animation-iteration-count`, `animation-name`, `animation-play-state`, `animation-timing-function`, `@keyframes`. * The `AnimationEvent` interface it belongs to. # AnimationEvent: pseudoElement property Baseline Widely available This feature is well established and works across many devices and browser versions. It’s been available across browsers since March 2020. * Learn more * See full compatibility * Report feedback The `AnimationEvent.pseudoElement` read-only property is a string, starting with `'::'`, containing the name of the pseudo-element the animation runs on. If the animation doesn't run on a pseudo-element but on the element, an empty string: `''`. ## Value A string, starting with `'::'`, containing the name of the pseudo-element the animation runs on. ## Specifications ## Browser compatibility | Desktop | Mobile ---|---|--- | Chrome | Edge | Firefox | Opera | Safari | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet | WebView Android `pseudoElement` | 68 | 79 | 23 | 55 | 13.1 | 68 | 23 | 48 | 13.4 | 10.0 | 68 ## See also * Using CSS animations * Animation-related CSS properties and at-rules: `animation`, `animation-delay`, `animation-direction`, `animation-duration`, `animation-fill-mode`, `animation-iteration-count`, `animation-name`, `animation-play-state`, `animation-timing-function`, `@keyframes`. * The `AnimationEvent` interface it belongs to. # AnimationPlaybackEvent Baseline Widely available This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2020. * Learn more * See full compatibility * Report feedback The AnimationPlaybackEvent interface of the Web Animations API represents animation events. As animations play, they report changes to their `playState` through animation events. Event AnimationPlaybackEvent ## Constructor `AnimationPlaybackEvent()` Constructs a new `AnimationPlaybackEvent` object instance. ## Instance properties `AnimationPlaybackEvent.currentTime` Read only The current time of the animation that generated the event. `AnimationPlaybackEvent.timelineTime` Read only The time value of the timeline of the animation that generated the event. ## Specifications ## Browser compatibility | Desktop | Mobile ---|---|--- | Chrome | Edge | Firefox | Opera | Safari | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet | WebView Android `AnimationPlaybackEvent` | 84 | 84 | 63 | 70 | 13.1 | 84 | 63 | 60 | 13.4 | 14.0 | 84 `AnimationPlaybackEvent` | 84 | 84 | 63 | 70 | 13.1 | 84 | 63 | 60 | 13.4 | 14.0 | 84 `currentTime` | 84 | 84 | 63 | 70 | 13.1 | 84 | 63 | 60 | 13.4 | 14.0 | 84 `timelineTime` | 84 | 84 | 63 | 70 | 13.1 | 84 | 63 | 60 | 13.4 | 14.0 | 84 ## See also * Web Animations API * `Animation.playState` # AnimationPlaybackEvent: AnimationPlaybackEvent() constructor Baseline Widely available This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2020. * Learn more * See full compatibility * Report feedback The `AnimationPlaybackEvent()` constructor of the Web Animations API returns a new `AnimationPlaybackEvent` object instance. ## Syntax new AnimationPlaybackEvent(type) new AnimationPlaybackEvent(type, options) ### Parameters `type` A string with the name of the event. It is case-sensitive and browsers set it to `cancel`, `finish`, or `remove`. `options` Optional An object that, _in addition of the properties defined in`Event()`_, has the following properties: `detail` Optional An event-dependent value associated with the event. Defaults to `null`. ### Return value A new `AnimationPlaybackEvent` object. ## Specifications ## Browser compatibility | Desktop | Mobile ---|---|--- | Chrome | Edge | Firefox | Opera | Safari | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet | WebView Android `AnimationPlaybackEvent` | 84 | 84 | 63 | 70 | 13.1 | 84 | 63 | 60 | 13.4 | 14.0 | 84 ## See also * Web Animations API * `AnimationPlayBackEvent` * `Animation.playState` * `CustomEvent()` * `Event()` # AnimationPlaybackEvent: currentTime property Baseline Widely available This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2020. * Learn more * See full compatibility * Report feedback The `currentTime` read-only property of the `AnimationPlaybackEvent` interface represents the current time of the animation that generated the event at the moment the event is queued. This will be unresolved if the animation was `idle` at the time the event was generated. ## Value A number representing the current time in milliseconds, or `null`. ## Reduced time precision To offer protection against timing attacks and fingerprinting, the precision of `playbackEvent.currentTime` might get rounded depending on browser settings. In Firefox, the `privacy.reduceTimerPrecision` preference is enabled by default and defaults to 2ms. You can also enable `privacy.resistFingerprinting`, in which case the precision will be 100ms or the value of `privacy.resistFingerprinting.reduceTimerPrecision.microseconds`, whichever is larger. For example, with reduced time precision, the result of `playbackEvent.currentTime` will always be a multiple of 0.002, or a multiple of 0.1 (or `privacy.resistFingerprinting.reduceTimerPrecision.microseconds`) with `privacy.resistFingerprinting` enabled. // reduced time precision (2ms) in Firefox 60 playbackEvent.currentTime; // Might be: // 23.404 // 24.192 // 25.514 // … // reduced time precision with `privacy.resistFingerprinting` enabled playbackEvent.currentTime; // Might be: // 49.8 // 50.6 // 51.7 // … ## Specifications ## Browser compatibility | Desktop | Mobile ---|---|--- | Chrome | Edge | Firefox | Opera | Safari | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet | WebView Android `currentTime` | 84 | 84 | 63 | 70 | 13.1 | 84 | 63 | 60 | 13.4 | 14.0 | 84 ## See also * Web Animations API * `AnimationPlayBackEvent` # AnimationPlaybackEvent: timelineTime property Baseline Widely available This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2020. * Learn more * See full compatibility * Report feedback The `timelineTime` read-only property of the `AnimationPlaybackEvent` interface represents the time value of the animation's `timeline` at the moment the event is queued. This will be unresolved if the animation was not associated with a timeline at the time the event was generated or if the associated timeline was inactive. ## Value A number representing the current time in milliseconds, or `null`. ## Specifications ## Browser compatibility | Desktop | Mobile ---|---|--- | Chrome | Edge | Firefox | Opera | Safari | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet | WebView Android `timelineTime` | 84 | 84 | 63 | 70 | 13.1 | 84 | 63 | 60 | 13.4 | 14.0 | 84 ## See also * Web Animations API * `AnimationPlayBackEvent` * `AnimationTimeline` # AnimationTimeline Baseline Widely available * This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2020. * Some parts of this feature may have varying levels of support. * Learn more * See full compatibility * Report feedback The `AnimationTimeline` interface of the Web Animations API represents the timeline of an animation. This interface exists to define timeline features, inherited by other timeline types: * `DocumentTimeline` * `ScrollTimeline` * `ViewTimeline` ## Instance properties `currentTime` Read only Returns the time value in milliseconds for this timeline or `null` if this timeline is inactive. ## Specifications ## Browser compatibility | Desktop | Mobile ---|---|--- | Chrome | Edge | Firefox | Opera | Safari | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet | WebView Android `AnimationTimeline` | 84 | 84 | 75 | 70 | 13.1 | 84 | 79 | 60 | 13.4 | 14.0 | 84 `currentTime` | 84 | 84 | 75 | 70 | 13.1 | 84 | 79 | 60 | 13.4 | 14.0 | 84 `duration` | 115 | 115 | No | 101 | No | 115 | No | 77 | No | 23.0 | 115 ## See also * `DocumentTimeline`, `ScrollTimeline`, `ViewTimeline` * `Document.timeline` * Web Animations API * CSS scroll-driven animations # AnimationTimeline: currentTime property Baseline Widely available This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2020. * Learn more * See full compatibility * Report feedback The `currentTime` read-only property of the Web Animations API's `AnimationTimeline` interface returns the timeline's current time in milliseconds, or `null` if the timeline is inactive. ## Value A number representing the timeline's current time in milliseconds, or `null` if the timeline is inactive. ## Reduced time precision To offer protection against timing attacks and fingerprinting, the precision of `animationTimeline.currentTime` might get rounded depending on browser settings. In Firefox, the `privacy.reduceTimerPrecision` preference is enabled by default and defaults to 2ms. You can also enable `privacy.resistFingerprinting`, in which case the precision will be 100ms or the value of `privacy.resistFingerprinting.reduceTimerPrecision.microseconds`, whichever is larger. For example, with reduced time precision, the result of `animationTimeline.currentTime` will always be a multiple of 0.002, or a multiple of 0.1 (or `privacy.resistFingerprinting.reduceTimerPrecision.microseconds`) with `privacy.resistFingerprinting` enabled. // reduced time precision (2ms) in Firefox 60 animationTimeline.currentTime; // Might be: // 23.404 // 24.192 // 25.514 // … // reduced time precision with `privacy.resistFingerprinting` enabled animationTimeline.currentTime; // Might be: // 49.8 // 50.6 // 51.7 // … ## Specifications ## Browser compatibility | Desktop | Mobile ---|---|--- | Chrome | Edge | Firefox | Opera | Safari | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet | WebView Android `currentTime` | 84 | 84 | 75 | 70 | 13.1 | 84 | 79 | 60 | 13.4 | 14.0 | 84 ## See also * Web Animations API * `AnimationTimeline` * `DocumentTimeline` inherits this property * `Document.timeline` returns a timeline object which inherits this property # Attr Baseline Widely available This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015. * Learn more * See full compatibility * Report feedback The `Attr` interface represents one of an element's attributes as an object. In most situations, you will directly retrieve the attribute value as a string (e.g., `Element.getAttribute()`), but some cases may require interacting with `Attr` instances (e.g., `Element.getAttributeNode()`). EventTarget Node Attr The core idea of an object of type `Attr` is the association between a _name_ and a _value_. An attribute may also be part of a _namespace_ and, in this case, it also has a URI identifying the namespace, and a prefix that is an abbreviation for the namespace. The name is deemed _local_ when it ignores the eventual namespace prefix and deemed _qualified_ when it includes the prefix of the namespace, if any, separated from the local name by a colon (`:`). We have three cases: an attribute outside of a namespace, an attribute inside a namespace without a prefix defined, an attribute inside a namespace with a prefix: Attribute | Namespace name | Namespace prefix | Attribute local name | Attribute qualified name ---|---|---|---|--- `myAttr` | _none_ | _none_ | `myAttr` | `myAttr` `myAttr` | `mynamespace` | _none_ | `myAttr` | `myAttr` `myAttr` | `mynamespace` | `myns` | `myAttr` | `myns:myAttr` **Note:** This interface represents only attributes present in the tree representation of the `Element`, being a SVG, an HTML or a MathML element. It doesn't represent the _property_ of an interface associated with such element, such as `HTMLTableElement` for a `` element. (See this article for more information about attributes and how they are _reflected_ into properties.) ## Instance properties _This interface also inherits the properties of its parent interfaces,`Node` and `EventTarget`._ `localName` Read only A string representing the local part of the qualified name of the attribute. `name` Read only The attribute's _qualified name_. If the attribute is not in a namespace, it will be the same as `localName` property. `namespaceURI` Read only A string representing the URI of the namespace of the attribute, or `null` if there is no namespace. `ownerElement` Read only The `Element` the attribute belongs to. `prefix` Read only A string representing the namespace prefix of the attribute, or `null` if a namespace without prefix or no namespace are specified. `specified` Read only Deprecated This property always returns `true`. `value` The attribute's value, a string that can be set and get using this property. ## Instance methods _This interface has no specific methods, but inherits the methods of its parent interfaces,`Node` and `EventTarget`._ ## Specifications ## Browser compatibility | Desktop | Mobile ---|---|--- | Chrome | Edge | Firefox | Opera | Safari | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet | WebView Android `Attr` | 1 | 12 | 1 | 8 | 1 | 18 | 4 | 10.1 | 1 | 1.0 | 4.4 `localName` | 1 | 12 | 1 | ≤12.1 | 1 | 18 | 4 | ≤12.1 | 1 | 1.0 | 4.4 `name` | 1 | 12 | 1 | ≤12.1 | 1 | 18 | 4 | ≤12.1 | 1 | 1.0 | 4.4 `namespaceURI` | 1 | 12 | 1 | ≤12.1 | 1 | 18 | 4 | ≤12.1 | 1 | 1.0 | 4.4 `ownerElement` | 1 | 12 | 1 | ≤12.1 | 1 | 18 | 4 | ≤12.1 | 1 | 1.0 | 4.4 `prefix` | 1 | 12 | 1 | ≤12.1 | 1 | 18 | 4 | ≤12.1 | 1 | 1.0 | 4.4 `specified` | 1 | 12 | 1 | ≤12.1 | 1 | 18 | 4 | ≤12.1 | 1 | 1.0 | 4.4 `value` | 1 | 12 | 1 | ≤12.1 | 1 | 18 | 4 | ≤12.1 | 1 | 1.0 | 4.4 ## See also * Other nodes are `CDATASection`, `CharacterData`, `Comment`, `Document`, `Element`, `ProcessingInstruction`, and `Text`. # Attr: localName property Baseline Widely available This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015. * Learn more * See full compatibility * Report feedback The read-only `localName` property of the `Attr` interface returns the _local part_ of the _qualified name_ of an attribute, that is the name of the attribute, stripped from any namespace in front of it. For example, if the qualified name is `xml:lang`, the returned local name is `lang`, if the element supports that namespace. The local name is always in lower case, whatever case at the attribute creation. **Note:** HTML only supports a fixed set of namespaces on SVG and MathML elements. These are `xml` (for the `xml:lang` attribute), `xlink` (for the `xlink:href`, `xlink:show`, `xlink:target` and `xlink:title` attributes) and `xpath`. That means that the local name of an attribute of an HTML element is always be equal to its qualified name: Colons are treated as regular characters. In XML, like in SVG or MathML, the colon denotes the end of the prefix and what is before is the namespace; the local name may be different from the qualified name. ## Value A string representing the local part of the attribute's qualified name. ## Example The following example displays the local name of the first attribute of the two first elements, when we click on the appropriate button. The `` element is XML and supports namespaces leading to the local name (`lang`) to be different from the qualified name `xml:lang`. The `

    Local part of the attribute xml:lang: None.

    ### JavaScript const elements = document.querySelectorAll(".struct"); const buttons = document.querySelectorAll("button"); const outputEl = document.querySelector("#result"); let i = 0; for (const button of buttons) { const element = elements[i]; button.addEventListener("click", () => { const attribute = element.attributes[0]; outputEl.value = attribute.localName; }); i++; } ## Specifications ## Browser compatibility | Desktop | Mobile ---|---|--- | Chrome | Edge | Firefox | Opera | Safari | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet | WebView Android `localName` | 1 | 12 | 1 | ≤12.1 | 1 | 18 | 4 | ≤12.1 | 1 | 1.0 | 4.4 ## See also * The properties `Attr.name`, returning the qualified name of the attribute, and `Attr.prefix`, the namespace prefix. * The `Element.localName()` property, returning the local name of an `Element`. # Attr: name property Baseline Widely available This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015. * Learn more * See full compatibility * Report feedback The read-only `name` property of the `Attr` interface returns the _qualified name_ of an attribute, that is the name of the attribute, with the namespace prefix, if any, in front of it. For example, if the local name is `lang` and the namespace prefix is `xml`, the returned qualified name is `xml:lang`. The qualified name is always in lower case, whatever case at the attribute creation. ## Value A string representing the attribute's qualified name. ## Example The following example displays the qualified name of the first attribute of the two first elements, when we click on the appropriate button. ### HTML Click me

    Qualified name of the attribute xml:lang: None.

    ### JavaScript const elements = document.querySelectorAll(".struct"); const buttons = document.querySelectorAll("button"); const outputEl = document.querySelector("#result"); let i = 0; for (const button of buttons) { const element = elements[i]; button.addEventListener("click", () => { const attribute = element.attributes[0]; outputEl.value = attribute.name; }); i++; } ## Specifications ## Browser compatibility | Desktop | Mobile ---|---|--- | Chrome | Edge | Firefox | Opera | Safari | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet | WebView Android `name` | 1 | 12 | 1 | ≤12.1 | 1 | 18 | 4 | ≤12.1 | 1 | 1.0 | 4.4 ## See also * The properties `Attr.localName`, returning the local part of the qualified name of the attribute, and `Attr.prefix`, the namespace prefix. * The `Element.tagName()` property, returning the qualified name of an `Element`. # Attr: namespaceURI property Baseline Widely available This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015. * Learn more * See full compatibility * Report feedback The read-only `namespaceURI` property of the `Attr` interface returns the namespace URI of the attribute, or `null` if the element is not in a namespace. The namespace URI is set at the `Attr` creation and cannot be changed. An attribute with a namespace can be created using `Element.setAttributeNS()`. **Note:** An attribute does not inherit its namespace from the element it is attached to. If an attribute is not explicitly given a namespace, it has no namespace. The browser does not handle or enforce namespace validation per se. It is up to the JavaScript application to do any necessary validation. Note, too, that the namespace prefix, once it is associated with a particular attribute node, cannot be changed. ## Value A string containing the URI of the namespace, or `null` if the attribute is not in a namespace. ## Example The following example shows the results for a prefixed attribute in a case of an HTML element, and of a SVG element. As HTML doesn't handle namespaces, it will always return `null` in that case. In the case of the SVG element, it will return the URI of the XML namespace, `http://www.w3.org/XML/1998/namespace`. ### HTML Click me

    Namespace URI of the attribute xml:lang: None.

    ### JavaScript const elements = document.querySelectorAll(".struct"); const buttons = document.querySelectorAll("button"); const outputEl = document.querySelector("#result"); let i = 0; for (const button of buttons) { const element = elements[i]; button.addEventListener("click", () => { const attribute = element.attributes[0]; outputEl.value = attribute.namespaceURI; }); i++; } ## Specifications ## Browser compatibility | Desktop | Mobile ---|---|--- | Chrome | Edge | Firefox | Opera | Safari | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet | WebView Android `namespaceURI` | 1 | 12 | 1 | ≤12.1 | 1 | 18 | 4 | ≤12.1 | 1 | 1.0 | 4.4 ## See also * The properties `Attr.name`, returning the qualified name of the attribute, `Attr.localName`, the local part of the name, and `Attr.prefix`, the namespace prefix. * The `Element.namespaceURI` property, equivalent to this one but for an `Element`. * The `Element.setAttributeNS()` method, creating an attribute with a given namespace. # Attr: ownerElement property Baseline Widely available This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015. * Learn more * See full compatibility * Report feedback The read-only `ownerElement` property of the `Attr` interface returns the `Element` the attribute belongs to. ## Value The `Element` the attribute belongs to, or `null` if the attribute is not linked to an element. ## Example The following example displays the qualified name of the element of the two first elements, when we click on the appropriate button. ### HTML Click me

    Qualified name of the owner element of the attribute xml:lang: None.

    ### JavaScript const elements = document.querySelectorAll(".struct"); const buttons = document.querySelectorAll("button"); const outputEl = document.querySelector("#result"); let i = 0; for (const button of buttons) { const element = elements[i]; button.addEventListener("click", () => { const attribute = element.attributes[0]; outputEl.value = attribute.ownerElement.tagName.toLowerCase(); }); i++; } ## Specifications ## Browser compatibility | Desktop | Mobile ---|---|--- | Chrome | Edge | Firefox | Opera | Safari | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet | WebView Android `ownerElement` | 1 | 12 | 1 | ≤12.1 | 1 | 18 | 4 | ≤12.1 | 1 | 1.0 | 4.4 # Attr: prefix property Baseline Widely available This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015. * Learn more * See full compatibility * Report feedback The read-only `prefix` property of the `Attr` returns the namespace prefix of the attribute, or `null` if no prefix is specified. The prefix is always in lower case, whatever case is used at the attribute creation. **Note:** Only XML supports namespaces. HTML does not. That means that the prefix of an attribute of an HTML element will always be `null`. Also, only the `xml` (for the `xml:lang` attribute), `xlink` (for the `xlink:href`, `xlink:show`, `xlink:target` and `xlink:title` attributes) and `xpath` namespaces are supported, and only on SVG and MathML elements. ## Value A string containing the prefix of the namespace the attribute belongs too. If none, it returns `null`. ## Example ### HTML Click me

    Prefix of the attribute xml:lang: None.

    ### JavaScript const elements = document.querySelectorAll(".struct"); const buttons = document.querySelectorAll("button"); const outputEl = document.querySelector("#result"); let i = 0; for (const button of buttons) { const element = elements[i]; button.addEventListener("click", () => { const attribute = element.attributes[0]; outputEl.value = attribute.prefix; }); i++; } ## Specifications ## Browser compatibility | Desktop | Mobile ---|---|--- | Chrome | Edge | Firefox | Opera | Safari | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet | WebView Android `prefix` | 1 | 12 | 1 | ≤12.1 | 1 | 18 | 4 | ≤12.1 | 1 | 1.0 | 4.4 ## See also * The properties `Attr.name`, returning the qualified name of the attribute, and `Attr.localName`, its local name. * The `Element.prefix()` property, returning the namespace prefix of an `Element`. # Attr: specified property **Deprecated:** This feature is no longer recommended. Though some browsers might still support it, it may have already been removed from the relevant web standards, may be in the process of being dropped, or may only be kept for compatibility purposes. Avoid using it, and update existing code if possible; see the compatibility table at the bottom of this page to guide your decision. Be aware that this feature may cease to work at any time. The read-only `specified` property of the `Attr` interface always returns `true`. ## Value Always returns `true`. ## Specifications ## Browser compatibility | Desktop | Mobile ---|---|--- | Chrome | Edge | Firefox | Opera | Safari | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet | WebView Android `specified` | 1 | 12 | 1 | ≤12.1 | 1 | 18 | 4 | ≤12.1 | 1 | 1.0 | 4.4 # Attr: value property Baseline Widely available This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015. * Learn more * See full compatibility * Report feedback The `value` property of the `Attr` interface contains the value of the attribute. ## Value A string representing the attribute value. ## Example The following example displays the current value of the attribute `test`. Clicking on the button will change it to a different value, and read it again to update the displayed value. ### HTML

    Current value of the test attribute: None.

    ### JavaScript const element = document.querySelector("label"); const button = document.querySelector("button"); const result = document.querySelector("#result"); const attribute = element.attributes[0]; result.value = attribute.value; button.addEventListener("click", () => { attribute.value = "a new value"; result.value = attribute.value; }); ## Specifications ## Browser compatibility | Desktop | Mobile ---|---|--- | Chrome | Edge | Firefox | Opera | Safari | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet | WebView Android `value` | 1 | 12 | 1 | ≤12.1 | 1 | 18 | 4 | ≤12.1 | 1 | 1.0 | 4.4 # Attribution Reporting API Limited availability This feature is not Baseline because it does not work in some of the most widely-used browsers. * Learn more * See full compatibility * Report feedback **Experimental:** **This is an experimental technology** Check the Browser compatibility table carefully before using this in production. **Secure context:** This feature is available only in secure contexts (HTTPS), in some or all supporting browsers. The **Attribution Reporting API** enables developers to measure conversions — for example when a user clicks an ad embedded on one site and then proceeds to purchase the item over on the vendor's site — and then access reports on those conversions. It does this without relying on third-party tracking cookies. ## Concepts and usage Advertisers commonly want to measure how many users see an ad and then go on to view and purchase a product (conversions). This allows them to figure out what advertising placements are giving them the greatest return on investment (ROI) so they can adjust their advertising strategy accordingly. The process of measuring conversions usually includes capturing data such as: * Which users converted (for example purchased an item, or signed up for a service), and how many. * The geographic regions they are based in. * What sites the ads were placed on. * How many products were sold, services were signed up for, etc. * How much revenue was generated. Traditionally on the web, conversion has been measured using third-party tracking cookies. An ad will typically be embedded on a web page in an ` The JavaScript implementation of `makeDocument()` follows: function makeDocument() { let frame = document.getElementById("theFrame"); let doc = document.implementation.createHTMLDocument("New Document"); let p = doc.createElement("p"); p.textContent = "This is a new paragraph."; try { doc.body.appendChild(p); } catch (e) { console.log(e); } // Copy the new HTML document into the frame let destDocument = frame.contentDocument; let srcNode = doc.documentElement; let newNode = destDocument.importNode(srcNode, true); destDocument.replaceChild(newNode, destDocument.documentElement); } The code handles creating the new HTML document and inserting some content into it. `createHTMLDocument()` constructs a new HTML document whose `` is `"New Document"`. Then we create a new paragraph element with some simple content, and then the new paragraph gets inserted into the new document. `destDocument` stores the `contentDocument` of the frame; this is the document into which we'll be injecting the new content. The next two lines handle importing the contents of our new document into the new document's context. Finally, `destDocument.replaceChild` actually replaces the contents of the frame with the new document's contents. View Live Examples The returned document is pre-constructed with the following HTML: <!doctype html> <html lang="en-US"> <head> <meta charset="UTF-8" /> <title>title … ## Specifications ## Browser compatibility | Desktop | Mobile ---|---|--- | Chrome | Edge | Firefox | Opera | Safari | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet | WebView Android `createHTMLDocument` | 1 | 12 | 4 | ≤12.1 | 1 | 18 | 4 | ≤12.1 | 1 | 1.0 | 4.4 ## See also * The `DOMImplementation` interface it belongs to. # DOMImplementation: hasFeature() method **Deprecated:** This feature is no longer recommended. Though some browsers might still support it, it may have already been removed from the relevant web standards, may be in the process of being dropped, or may only be kept for compatibility purposes. Avoid using it, and update existing code if possible; see the compatibility table at the bottom of this page to guide your decision. Be aware that this feature may cease to work at any time. The `DOMImplementation.hasFeature()` method returns a boolean flag indicating if a given feature is supported. It is deprecated and modern browsers return `true` in all cases. The different implementations fairly diverged in what kind of features were reported. The latest version of the spec settled to force this method to always return `true`, where the functionality was accurate and in use. ## Syntax hasFeature(feature, version) ### Parameters `feature` A string representing the feature name. `version` A string representing the version of the specification defining the feature. ### Return value A boolean value of `true`. ## Specifications ## Browser compatibility | Desktop | Mobile ---|---|--- | Chrome | Edge | Firefox | Opera | Safari | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet | WebView Android `hasFeature` | 1 | 12 | 1Since Firefox 19, `hasFeature()` mostly returns `true`. | ≤12.1 | 1 | 18 | 4 | ≤12.1 | 1 | 1.0 | 4.4 ## See also * The `DOMImplementation` interface it belongs to. # DOMMatrix Baseline Widely available This feature is well established and works across many devices and browser versions. It’s been available across browsers since January 2020. * Learn more * See full compatibility * Report feedback **Note:** This feature is available in Web Workers. The `DOMMatrix` interface represents 4×4 matrices, suitable for 2D and 3D operations including rotation and translation. It is a mutable version of the `DOMMatrixReadOnly` interface. The interface is available inside web workers. `WebKitCSSMatrix` and `SVGMatrix` are aliases to `DOMMatrix`. DOMMatrixReadOnly DOMMatrix ## Constructor `DOMMatrix()` Creates and returns a new `DOMMatrix` object. ## Instance properties _This interface inherits properties from`DOMMatrixReadOnly`, though some of these properties are altered to be mutable._ `m11`, `m12`, `m13`, `m14`, `m21`, `m22`, `m23`, `m24`, `m31`, `m32`, `m33`, `m34`, `m41`, `m42`, `m43`, `m44` Double-precision floating-point values representing each component of a 4×4 matrix, where `m11` through `m14` are the first column, `m21` through `m24` are the second column, and so forth. `a`, `b`, `c`, `d`, `e`, `f` Double-precision floating-point values representing the components of a 4×4 matrix which are required in order to perform 2D rotations and translations. These are aliases for specific components of a 4×4 matrix, as shown below. `2D` | `3D equivalent` ---|--- `a` | `m11` `b` | `m12` `c` | `m21` `d` | `m22` `e` | `m41` `f` | `m42` ## Instance methods _This interface includes the following methods, as well as the methods it inherits from`DOMMatrixReadOnly`._ `DOMMatrix.invertSelf()` Modifies the matrix by inverting it. If the matrix can't be inverted, its components are all set to `NaN`, and `is2D` returns `false`. `DOMMatrix.multiplySelf()` Modifies the matrix by post-multiplying it with the specified `DOMMatrix`. This is equivalent to the dot product `A⋅B`, where matrix `A` is the source matrix and `B` is the matrix given as an input to the method. Returns itself. `DOMMatrix.preMultiplySelf()` Modifies the matrix by pre-multiplying it with the specified `DOMMatrix`. Returns itself. `DOMMatrix.translateSelf()` Modifies the matrix by applying the specified vector. The default vector is `[0, 0, 0]`. Returns itself. `DOMMatrix.scaleSelf()` Modifies the matrix by applying the specified scaling factors, with the center located at the specified origin. Also returns itself. By default, the scaling factor is `1` for all three axes, and the origin is `(0, 0, 0)`. Returns itself. `DOMMatrix.scale3dSelf()` Modifies the matrix by applying the specified scaling factor to all three axes, centered on the given origin. Returns itself. `DOMMatrix.rotateSelf()` Modifies the matrix by rotating itself around each axis by the specified number of degrees. Returns itself. `DOMMatrix.rotateAxisAngleSelf()` Modifies the matrix by rotating it by the specified angle around the given vector. Returns itself. `DOMMatrix.rotateFromVectorSelf()` Modifies the matrix by rotating it by the angle between the specified vector and `(1, 0)`. Returns itself. `DOMMatrix.setMatrixValue()` Replaces the contents of the matrix with the matrix described by the specified transform or transforms. Returns itself. `DOMMatrix.skewXSelf()` Modifies the matrix by applying the specified skew transformation along the X-axis. Returns itself. `DOMMatrix.skewYSelf()` Modifies the matrix by applying the specified skew transformation along the Y-axis. Returns itself. ## Static methods _This interface inherits methods from`DOMMatrixReadOnly`._ `fromFloat32Array()` Creates a new mutable `DOMMatrix` object given an array of single-precision (32-bit) floating-point values. If the array has six values, the result is a 2D matrix; if the array has 16 values, the result is a 3D matrix. Otherwise, a `TypeError` exception is thrown. `fromFloat64Array()` Creates a new mutable `DOMMatrix` object given an array of double-precision (64-bit) floating-point values. If the array has six values, the result is a 2D matrix; if the array has 16 values, the result is a 3D matrix. Otherwise, a `TypeError` exception is thrown. `fromMatrix()` Creates a new mutable `DOMMatrix` object given an existing matrix or an object which provides the values for its properties. ## Usage notes The matrix defined by the `DOMMatrix` interface is comprised of four rows of four columns each. While it's beyond the scope of this article to explain the mathematics involved, this 4×4 size is enough to describe any transformation you might apply to either 2D or 3D geometries. Here are the positions of the 16 elements (m_11 through m_44) which comprise the 4×4 abstract matrix: [m11m21m31m41m12m22m32m42m13m23m33m43m14m24m34m44]\left [ \begin{matrix} m_{11} & m_{21} & m_{31} & m_{41} \\\ m_{12} & m_{22} & m_{32} & m_{42} \\\ m_{13} & m_{23} & m_{33} & m_{43} \\\ m_{14} & m_{24} & m_{34} & m_{44} \end{matrix} \right ] The `DOMMatrix` interface is designed with the intent that it will be used for all matrices within markup. ## Specifications ## Browser compatibility | Desktop | Mobile ---|---|--- | Chrome | Edge | Firefox | Opera | Safari | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet | WebView Android `DOMMatrix` | 6152 | 79121212–79 | 33491.5 | 4815≤12.1 | 1154 | 611818 | 33494 | 4814≤12.1 | 1143 | 8.01.01.0 | 614.44.4 `DOMMatrix` | 6152 | 79121212–79 | 33491.5 | 4815≤12.1 | 1154 | 611818 | 33494 | 4814≤12.1 | 1143 | 8.01.01.0 | 614.44.4 `a` | 61 | 79 | 33 | 48 | 11 | 61 | 33 | 45 | 11 | 8.0 | 61 `b` | 61 | 79 | 33 | 48 | 11 | 61 | 33 | 45 | 11 | 8.0 | 61 `c` | 61 | 79 | 33 | 48 | 11 | 61 | 33 | 45 | 11 | 8.0 | 61 `d` | 61 | 79 | 33 | 48 | 11 | 61 | 33 | 45 | 11 | 8.0 | 61 `e` | 61 | 79 | 33 | 48 | 11 | 61 | 33 | 45 | 11 | 8.0 | 61 `f` | 61 | 79 | 33 | 48 | 11 | 61 | 33 | 45 | 11 | 8.0 | 61 `fromFloat32Array_static` | 61 | 79 | 69 | 48 | 11 | 61 | 79 | 45 | 11 | 8.0 | 61 `fromFloat64Array_static` | 61 | 79 | 69 | 48 | 11 | 61 | 79 | 45 | 11 | 8.0 | 61 `fromMatrix_static` | 61 | 79 | 69 | 48 | 11 | 61 | 79 | 45 | 11 | 8.0 | 61 `invertSelf` | 61 | 79 | 33 | 48 | 11 | 61 | 33 | 45 | 11 | 8.0 | 61 `m11` | 61 | 79 | 33 | 48 | 11 | 61 | 33 | 45 | 11 | 8.0 | 61 `m12` | 61 | 79 | 33 | 48 | 11 | 61 | 33 | 45 | 11 | 8.0 | 61 `m13` | 61 | 79 | 33 | 48 | 11 | 61 | 33 | 45 | 11 | 8.0 | 61 `m14` | 61 | 79 | 33 | 48 | 11 | 61 | 33 | 45 | 11 | 8.0 | 61 `m21` | 61 | 79 | 33 | 48 | 11 | 61 | 33 | 45 | 11 | 8.0 | 61 `m22` | 61 | 79 | 33 | 48 | 11 | 61 | 33 | 45 | 11 | 8.0 | 61 `m23` | 61 | 79 | 33 | 48 | 11 | 61 | 33 | 45 | 11 | 8.0 | 61 `m24` | 61 | 79 | 33 | 48 | 11 | 61 | 33 | 45 | 11 | 8.0 | 61 `m31` | 61 | 79 | 33 | 48 | 11 | 61 | 33 | 45 | 11 | 8.0 | 61 `m32` | 61 | 79 | 33 | 48 | 11 | 61 | 33 | 45 | 11 | 8.0 | 61 `m33` | 61 | 79 | 33 | 48 | 11 | 61 | 33 | 45 | 11 | 8.0 | 61 `m34` | 61 | 79 | 33 | 48 | 11 | 61 | 33 | 45 | 11 | 8.0 | 61 `m41` | 61 | 79 | 33 | 48 | 11 | 61 | 33 | 45 | 11 | 8.0 | 61 `m42` | 61 | 79 | 33 | 48 | 11 | 61 | 33 | 45 | 11 | 8.0 | 61 `m43` | 61 | 79 | 33 | 48 | 11 | 61 | 33 | 45 | 11 | 8.0 | 61 `m44` | 61 | 79 | 33 | 48 | 11 | 61 | 33 | 45 | 11 | 8.0 | 61 `multiplySelf` | 61 | 79 | 33 | 48 | 11 | 61 | 33 | 45 | 11 | 8.0 | 61 `preMultiplySelf` | 61 | 79 | 33 | 48 | 11 | 61 | 33 | 45 | 11 | 8.0 | 61 `rotateAxisAngleSelf` | 61 | 79 | 33 | 48 | 11 | 61 | 33 | 45 | 11 | 8.0 | 61 `rotateFromVectorSelf` | 61 | 79 | 33 | 48 | 11 | 61 | 33 | 45 | 11 | 8.0 | 61 `rotateSelf` | 61 | 79 | 33 | 48 | 11 | 61 | 33 | 45 | 11 | 8.0 | 61 `scale3dSelf` | 61 | 79 | 33Starting in Firefox 69, the first parameter (`scale`) is now optional with a default value of 1, per the specification. Previously it was required. | 48 | 11 | 61 | 33Starting in Firefox for Android 79, the first parameter (`scale`) is now optional with a default value of 1, per the specification. Previously it was required. | 45 | 11 | 8.0 | 61 `scaleSelf` | 61 | 79 | 33Firefox 69 introduced support for the modern six-parameter syntax for `scaleSelf()`. Previously, it only supported the older three-parameter syntax: `scale(scaleX[, originX][, originY]]])`. | 48 | 11 | 61 | 33Firefox for Android 79 introduced support for the modern six-parameter syntax for `scaleSelf()`. Previously, it only supported the older three-parameter syntax: `scale(scaleX[, originX][, originY]]])`. | 45 | 11 | 8.0 | 61 `setMatrixValue` | 61 | 79 | 33 | 48 | 11 | 61 | 33 | 45 | 11 | 8.0 | 61 `skewXSelf` | 61 | 79 | 33 | 48 | 11 | 61 | 33 | 45 | 11 | 8.0 | 61 `skewYSelf` | 61 | 79 | 33 | 48 | 11 | 61 | 33 | 45 | 11 | 8.0 | 61 `translateSelf` | 61 | 79 | 33 | 48 | 11 | 61 | 33 | 45 | 11 | 8.0 | 61 `worker_support` | 61 | 79 | 69 | 48 | 11 | 61 | 79 | 45 | 11 | 8.0 | 61 ## See also * `DOMMatrixReadOnly.is2D` * `DOMMatrixReadOnly.isIdentity` # DOMMatrix: DOMMatrix() constructor Baseline Widely available This feature is well established and works across many devices and browser versions. It’s been available across browsers since January 2020. * Learn more * See full compatibility * Report feedback **Note:** This feature is available in Web Workers. The `DOMMatrix` constructor creates a new `DOMMatrix` object which represents 4x4 matrices, suitable for 2D and 3D operations. ## Syntax new DOMMatrix() new DOMMatrix(init) ### Parameters `init` Optional An array of numbers specifying the matrix you want to create, or a CSS transform string. In case an array of numbers is passed, the behavior depends on the length of the array: * for a 6-element array of components in the form `[a, b, c, d, e, f]`, a 2D matrix is created, initialized with the provided components. * for a 16-element array of components (in the column-major order) in the form `[m11, m12, m13, …, m42, m43, m44]`, a 3D matrix is created, initialized with the provided components. ## Examples This example creates a DOMMatrix to use as an argument for calling `DOMPointReadOnly.matrixTransform()`. const point = new DOMPoint(5, 4); const scaleX = 2; const scaleY = 3; const translateX = 12; const translateY = 8; const angle = Math.PI / 2; const matrix = new DOMMatrix([ Math.cos(angle) * scaleX, Math.sin(angle) * scaleX, -Math.sin(angle) * scaleY, Math.cos(angle) * scaleY, translateX, translateY, ]); const transformedPoint = point.matrixTransform(matrix); ## Specifications ## Browser compatibility | Desktop | Mobile ---|---|--- | Chrome | Edge | Firefox | Opera | Safari | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet | WebView Android `DOMMatrix` | 6152 | 79121212–79 | 33491.5 | 4815≤12.1 | 1154 | 611818 | 33494 | 4814≤12.1 | 1143 | 8.01.01.0 | 614.44.4 # DOMMatrix: invertSelf() method Baseline Widely available This feature is well established and works across many devices and browser versions. It’s been available across browsers since January 2020. * Learn more * See full compatibility * Report feedback **Note:** This feature is available in Web Workers. The `invertSelf()` method of the `DOMMatrix` interface inverts the original matrix. If the matrix cannot be inverted, the new matrix's components are all set to `NaN` and its `is2D` property is set to `false`. To invert a matrix without mutating it, see `DOMMatrixReadOnly.inverse()` ## Syntax invertSelf() ### Return value A `DOMMatrix`. ## Examples In this example, we create a matrix with a rotation of 30deg. Then invert it, resulting in a rotation of -30deg. const matrix = new DOMMatrix().rotate(30); console.log(matrix.toString()); // output: matrix(0.866, 0.5, -0.5, 0.866, 0, 0) matrix.invertSelf(); console.log(matrix.toString()); // output: matrix(0.866, -0.5, 0.5, 0.866, 0, 0) ## Specifications ## Browser compatibility | Desktop | Mobile ---|---|--- | Chrome | Edge | Firefox | Opera | Safari | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet | WebView Android `invertSelf` | 61 | 79 | 33 | 48 | 11 | 61 | 33 | 45 | 11 | 8.0 | 61 ## See also * `DOMMatrixReadOnly.inverse()` * CSS `matrix()` function * CSS `matrix3d()` function # DOMMatrix: multiplySelf() method Baseline Widely available This feature is well established and works across many devices and browser versions. It’s been available across browsers since January 2020. * Learn more * See full compatibility * Report feedback **Note:** This feature is available in Web Workers. The `multiplySelf()` method of the `DOMMatrix` interface multiplies a matrix by the `otherMatrix` parameter, computing the dot product of the original matrix and the specified matrix: `A⋅B`. If no matrix is specified as the multiplier, the matrix is multiplied by a matrix in which every element is `0` _except_ the bottom-right corner and the element immediately above and to its left: `m33` and `m34`. These have the default value of `1`. To multiply a matrix without mutating it, see `DOMMatrixReadOnly.multiply()`. ## Syntax multiplySelf() multiplySelf(otherMatrix) ### Parameters `otherMatrix` Optional The `DOMMatrix` multiplier. ### Return value Returns itself; the `DOMMatrix` updated to the results of the applied multiplications. ## Examples const matrix = new DOMMatrix().rotate(30); console.log(matrix.toString()); // output: matrix(0.866, 0.5, -0.5, 0.866, 0, 0) matrix.multiplySelf(matrix); console.log(matrix.toString()); // output: matrix(0.5, 0.866, -0.866, 0.5, 0, 0) (a 60deg rotation) ## Specifications ## Browser compatibility | Desktop | Mobile ---|---|--- | Chrome | Edge | Firefox | Opera | Safari | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet | WebView Android `multiplySelf` | 61 | 79 | 33 | 48 | 11 | 61 | 33 | 45 | 11 | 8.0 | 61 ## See also * `DOMMatrixReadOnly.multiply()` * `DOMMatrix.preMultiplySelf()` * CSS `matrix()` function * CSS `matrix3d()` function # DOMMatrix: preMultiplySelf() method Baseline Widely available This feature is well established and works across many devices and browser versions. It’s been available across browsers since January 2020. * Learn more * See full compatibility * Report feedback **Note:** This feature is available in Web Workers. The `preMultiplySelf()` method of the `DOMMatrix` interface modifies the matrix by pre-multiplying it with the specified `DOMMatrix`. This is equivalent to the dot product `B⋅A`, where matrix `A` is the source matrix and `B` is the matrix given as an input to the method. If no matrix is specified as the multiplier, the matrix is multiplied by a matrix in which every element is `0` _except_ the bottom-right corner and the element immediately above and to its left: `m33` and `m34`. These have the default value of `1`. ## Syntax preMultiplySelf() preMultiplySelf(otherMatrix) ### Parameters `otherMatrix` Optional The `DOMMatrix` multiplier. ### Return value Returns itself; a `DOMMatrix` updated to results of the applied multiplications. ## Examples const matrix = new DOMMatrix().translate(3, 22); const otherMatrix = new DOMMatrix().translateSelf(15, 45); console.log(matrix.toString()); // output: matrix(1, 0, 0, 1, 3, 22) console.log(otherMatrix.toString()); // output: matrix(1, 0, 0, 1, 15, 45) matrix.preMultiplySelf(otherMatrix); console.log(matrix.toString()); // output: matrix(1, 0, 0, 1, 18, 67) console.log(otherMatrix.toString()); // output: matrix(1, 0, 0, 1, 15, 45) ## Specifications ## Browser compatibility | Desktop | Mobile ---|---|--- | Chrome | Edge | Firefox | Opera | Safari | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet | WebView Android `preMultiplySelf` | 61 | 79 | 33 | 48 | 11 | 61 | 33 | 45 | 11 | 8.0 | 61 ## See also * `DOMMatrix.multiplySelf()` * `DOMMatrixReadOnly.multiply()` * CSS `matrix()` function * CSS `matrix3d()` function # DOMMatrix: rotateAxisAngleSelf() method Baseline Widely available This feature is well established and works across many devices and browser versions. It’s been available across browsers since January 2020. * Learn more * See full compatibility * Report feedback **Note:** This feature is available in Web Workers. The `rotateAxisAngleSelf()` method of the `DOMMatrix` interface is a transformation method that rotates the source matrix by the given vector and angle, returning the altered matrix. To rotate a matrix without mutating it, see `DOMMatrixReadOnly.rotateAxisAngle()`, which creates a new rotated matrix while leaving the original unchanged. ## Syntax rotateAxisAngleSelf() rotateAxisAngleSelf(rotX) rotateAxisAngleSelf(rotX, rotY) rotateAxisAngleSelf(rotX, rotY, rotZ) rotateAxisAngleSelf(rotX, rotY, rotZ, angle) ### Parameters `rotX` A number; the x-coordinate of the vector denoting the axis of rotation. If non-zero, `is2D` is false. `rotY` Optional A number; the y-coordinate of the vector denoting the axis of rotation. If undefined, the `rotX` value is used. If non-zero, `is2D` is false. `rotZ` Optional A number; the z-coordinate of the vector denoting the axis of rotation. If undefined, the `rotX` value is used. `angle` Optional A number; the angle of the rotation around the axis vector, in degrees. If `rotY` and `rotZ` are both missing, `rotZ` is set to the value of `rotX`, and both `rotX` and `rotY` are `0`. ### Return value A `DOMMatrix`. ## Examples const matrix = new DOMMatrix(); // create a matrix console.log(matrix.rotateAxisAngleSelf(10, 20, 30, 45).toString()); /* "matrix3d( 0.728, 0.609, -0.315, 0, -0.525, 0.791, 0.315, 0, 0.441, -0.063, 0.895, 0, 0, 0, 0, 1)" */ console.log(matrix.toString()); /* "matrix3d( 0.728, 0.609, -0.315, 0, -0.525, 0.791, 0.315, 0, 0.441, -0.063, 0.895, 0, 0, 0, 0, 1)" */ ## Specifications ## Browser compatibility | Desktop | Mobile ---|---|--- | Chrome | Edge | Firefox | Opera | Safari | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet | WebView Android `rotateAxisAngleSelf` | 61 | 79 | 33 | 48 | 11 | 61 | 33 | 45 | 11 | 8.0 | 61 ## See also * `DOMMatrixReadOnly.rotateAxisAngle()` * `DOMMatrix.rotateSelf()` * `DOMMatrix.rotateFromVectorSelf()` * CSS `transform` property and `rotate3d()` function * CSS `rotate` property * CSS transforms module * SVG `transform` attribute * `CanvasRenderingContext2D` interface and `rotate()` method # DOMMatrix: rotateFromVectorSelf() method Baseline Widely available This feature is well established and works across many devices and browser versions. It’s been available across browsers since January 2020. * Learn more * See full compatibility * Report feedback **Note:** This feature is available in Web Workers. The `rotateFromVectorSelf()` method of the `DOMMatrix` interface is a mutable transformation method that modifies a matrix by rotating the matrix by the angle between the specified vector and `(1, 0)`. The rotation angle is determined by the angle between the vector `(1,0)T` and `(x,y)T` in the clockwise direction, or `(+/-)arctan(y/x)`. If `x` and `y` are both `0`, the angle is specified as `0`, and the matrix is not altered. To rotate a matrix from a vector without mutating it, see `DOMMatrixReadOnly.rotateFromVector()`, which creates a new rotated matrix while leaving the original unchanged. ## Syntax rotateFromVectorSelf() rotateFromVectorSelf(rotX) rotateFromVectorSelf(rotX, rotY) ### Parameters `rotX` Optional A number; The x-coordinate of x,y vector that determines the rotation angle. If undefined, `0` is used. `rotY` Optional A number; The y-coordinate of x,y vector that determines the rotation angle. If undefined, `0` is used. ### Return value Returns itself; the updated `DOMMatrix`. ## Examples const matrix = new DOMMatrix(); // create a matrix console.log(matrix.rotateFromVectorSelf().toString()); // output: matrix(1, 0, 0, 1, 0, 0) (no rotation applied) console.log(matrix.rotateFromVectorSelf(10, 20).toString()); // output: matrix(0.447, 0.894, -0.894, 0.447, 0, 0) console.log(matrix.toString()); // output: matrix(0.447, 0.894, -0.894, 0.447, 0, 0) (same as above) ## Specifications ## Browser compatibility | Desktop | Mobile ---|---|--- | Chrome | Edge | Firefox | Opera | Safari | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet | WebView Android `rotateFromVectorSelf` | 61 | 79 | 33 | 48 | 11 | 61 | 33 | 45 | 11 | 8.0 | 61 ## See also * `DOMMatrixReadOnly.rotateFromVector()` * `DOMMatrix.rotateSelf()` * `DOMMatrix.rotateAxisAngleSelf()` * CSS `transform` property and `rotate3d()` function * CSS `rotate` property * CSS transforms module * SVG `transform` attribute * `CanvasRenderingContext2D` interface and `rotate()` method # DOMMatrix: rotateSelf() method Baseline Widely available This feature is well established and works across many devices and browser versions. It’s been available across browsers since January 2020. * Learn more * See full compatibility * Report feedback **Note:** This feature is available in Web Workers. The `rotateSelf()` method of the `DOMMatrix` interface is a mutable transformation method that modifies a matrix. It rotates the source matrix around each of its axes by the specified number of degrees and returns the rotated matrix. To rotate a matrix without mutating it, see `DOMMatrixReadOnly.rotate()` ## Syntax rotateSelf() rotateSelf(rotX) rotateSelf(rotX, rotY) rotateSelf(rotX, rotY, rotZ) ### Parameters `rotX` A number; the x-coordinate of the vector denoting the axis of rotation `rotY` Optional A number; the y-coordinate of the vector denoting the axis of rotation. `rotZ` Optional A number; the z-coordinate of the vector denoting the axis of rotation If only one parameter is passed, `rotZ` is the value of `rotX`, and both `rotX` and `rotY` are `0`, and the rotation is a 2D rotation. If `rotX` and `rotY` are non-zero, the `is2D` is `false`. ### Return value Returns itself; the `DOMMatrix` rotated by the given vectors. ## Examples const matrix = new DOMMatrix(); // create a matrix console.log(matrix.toString()); // output: "matrix(1, 0, 0, 1, 0, 0)" matrix.rotateSelf(30); // mutate it console.log(matrix); // output: "matrix(0.866, 0.5, -0.5, 0.866, 0, 0)" ## Specifications ## Browser compatibility | Desktop | Mobile ---|---|--- | Chrome | Edge | Firefox | Opera | Safari | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet | WebView Android `rotateSelf` | 61 | 79 | 33 | 48 | 11 | 61 | 33 | 45 | 11 | 8.0 | 61 ## See also * `DOMMatrixReadOnly.rotate()` * CSS `transform` property * CSS `rotate` property * CSS `` functions * `rotate()` * `rotate3d()` * `rotateX()` * `rotateY()` * `rotateZ()` * CSS transforms module * SVG `transform` attribute * `CanvasRenderingContext2D` interface methods * `CanvasRenderingContext2D.rotate()` * `CanvasRenderingContext2D.transform()` * `CanvasRenderingContext2D.setTransform()` * `CanvasRenderingContext2D.resetTransform()` # DOMMatrix: scale3dSelf() method Baseline Widely available This feature is well established and works across many devices and browser versions. It’s been available across browsers since January 2020. * Learn more * See full compatibility * Report feedback **Note:** This feature is available in Web Workers. The `scale3dSelf()` method of the `DOMMatrix` interface is a mutable transformation method that modifies a matrix by applying a specified scaling factor to all three axes, centered on the given origin, with a default origin of `(0, 0, 0)`, returning the 3D-scaled matrix. To 3D-scale a matrix without mutating it, see `DOMMatrixReadOnly.scale3d()`, which creates a new scaled matrix while leaving the original unchanged. ## Syntax scale3dSelf() scale3dSelf(scale) scale3dSelf(scale, originX) scale3dSelf(scale, originX, originY) scale3dSelf(scale, originX, originY, originZ) ### Parameters `scale` A multiplier; the scale value. If no scale is supplied, this defaults to `1`. If scale is not 1, the `is2D` property of the current matrix is set to `false`. `originX` Optional An x-coordinate for the origin of the transformation. If no origin is supplied, this defaults to `0`. `originY` Optional A y-coordinate for the origin of the transformation. If no origin is supplied, this defaults to `0`. `originZ` Optional A z-coordinate for the origin of the transformation. If no origin is supplied, this defaults to `0`. ### Return value Returns itself; a `DOMMatrix`. ## Examples const matrix = new DOMMatrix(); console.log(matrix.scale3dSelf(2).toString()); /* matrix3d( 2, 0, 0, 0, 0, 2, 0, 0, 0, 0, 2, 0, 0, 0, 0, 1) */ console.log(matrix.scale3dSelf(3.1, 25, 25, 1.25).toString()); /* matrix3d( 6.2, 0, 0, 0, 0, 6.2, 0, 0, 0, 0, 6.2, 0, -105, -105, -5.25, 1) */ console.log(matrix.toString()); /* matrix3d( 6.2, 0, 0, 0, 0, 6.2, 0, 0, 0, 0, 6.2, 0, -105, -105, -5.25, 1) (same as above) */ ## Specifications ## Browser compatibility | Desktop | Mobile ---|---|--- | Chrome | Edge | Firefox | Opera | Safari | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet | WebView Android `scale3dSelf` | 61 | 79 | 33Starting in Firefox 69, the first parameter (`scale`) is now optional with a default value of 1, per the specification. Previously it was required. | 48 | 11 | 61 | 33Starting in Firefox for Android 79, the first parameter (`scale`) is now optional with a default value of 1, per the specification. Previously it was required. | 45 | 11 | 8.0 | 61 ## See also * `DOMMatrixReadOnly.scale3d()` * `DOMMatrix.scaleSelf()` * CSS `transform` property and the `scale3d()` and `matrix3d()` functions * CSS transforms module * SVG `transform` attribute * `CanvasRenderingContext2D` interface `transform()` method # DOMMatrix: scaleSelf() method Baseline Widely available This feature is well established and works across many devices and browser versions. It’s been available across browsers since January 2020. * Learn more * See full compatibility * Report feedback **Note:** This feature is available in Web Workers. The `scaleSelf()` method of the `DOMMatrix` interface is a mutable transformation method that modifies a matrix by applying a specified scaling factor, centered on the given origin, with a default origin of `(0, 0)`, returning the scaled matrix. To scale a matrix without mutating it, see `DOMMatrixReadOnly.scale()`, which creates a new scaled matrix while leaving the original unchanged. ## Syntax scaleSelf() scaleSelf(scaleX) scaleSelf(scaleX, scaleY) scaleSelf(scaleX, scaleY, scaleZ) scaleSelf(scaleX, scaleY, scaleZ, originX) scaleSelf(scaleX, scaleY, scaleZ, originX, originY) scaleSelf(scaleX, scaleY, scaleZ, originX, originY, originZ) ### Parameters `scaleX` Optional A multiplier for the scale value on the x-axis. If not supplied, this defaults to `1`. `scaleY` Optional A multiplier for the scale value on the y-axis. If not supplied, this defaults to the value of `scaleX`. `scaleZ` Optional A multiplier for the scale value on the z-axis. If this value is anything other than 1, the resulting matrix will be 3D. `originX` Optional An x-coordinate for the origin of the transformation. If no origin is supplied, this defaults to 0. `originY` Optional A y-coordinate for the origin of the transformation. If no origin is supplied, this defaults to 0. `originZ` Optional A z-coordinate for the origin of the transformation. If no origin is supplied, this defaults to 0. If this value is anything other than 0, the resulting matrix will be 3D. ### Return value Returns itself; a `DOMMatrix`. If a scale is applied about the z-axis, the matrix will be a 4✕4 3D matrix. ## Examples This SVG contains two semi-opaque squares, one red and one blue, each positioned at the document origin: This JavaScript first creates a matrix, then scales the matrix to one that halves the width and doubles the height, using the `scaleSelf()` method. The matrix is then applied to the blue square as a `transform`, changing its dimensions and position. The red square is left unchanged. const matrix = new DOMMatrix(); matrix.scaleSelf(0.5, 2); document .querySelector("#transformed") .setAttribute("transform", matrix.toString()); ## Specifications ## Browser compatibility | Desktop | Mobile ---|---|--- | Chrome | Edge | Firefox | Opera | Safari | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet | WebView Android `scaleSelf` | 61 | 79 | 33Firefox 69 introduced support for the modern six-parameter syntax for `scaleSelf()`. Previously, it only supported the older three-parameter syntax: `scale(scaleX[, originX][, originY]]])`. | 48 | 11 | 61 | 33Firefox for Android 79 introduced support for the modern six-parameter syntax for `scaleSelf()`. Previously, it only supported the older three-parameter syntax: `scale(scaleX[, originX][, originY]]])`. | 45 | 11 | 8.0 | 61 ## See also * `DOMMatrixReadOnly.scale()` * `DOMMatrix.scale3dSelf()` * CSS `transform` property and the `scaleSelf()` and `matrix()` functions * CSS transforms module * SVG `transform` attribute * `CanvasRenderingContext2D` interface `transform()` method # DOMMatrix: setMatrixValue() method Baseline Widely available This feature is well established and works across many devices and browser versions. It’s been available across browsers since January 2020. * Learn more * See full compatibility * Report feedback **Note:** This feature is available in Web Workers. The `setMatrixValue()` method of the `DOMMatrix` interface replaces the contents of the matrix with the matrix described by the specified transform or transforms, returning itself. ## Syntax setMatrixValue(transformList) ### Parameters `transformList` A string. Its value follows the same syntax as the CSS `transform` property value. ### Return value Returns itself; the `DOMMatrix` with updated values. ## Examples In this example, we create a matrix, apply a 3D transform using the `DOMMatrix.translateSelf()` method, revert it to a 2D transform using the `setMatrixValue()` method, then revert it back to a 3D transform with another `setMatrixValue()` method call. const matrix = new DOMMatrix(); console.log(matrix.toString()); // matrix(1, 0, 0, 1, 0, 0) console.log(matrix.is2D); // true matrix.translateSelf(30, 40, 50); console.log(matrix.toString()); // matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 30, 40, 50, 1) console.log(matrix.is2D); // false matrix.setMatrixValue("matrix(1, 0, 0, 1, 15, 45)"); console.log(matrix.toString()); // output: matrix(1, 0, 0, 1, 15, 45) console.log(matrix.is2D); // true matrix.setMatrixValue( "matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 30, 40, 50, 1)", ); console.log(matrix.toString()); // matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 30, 40, 50, 1) console.log(matrix.is2D); // false ## Specifications ## Browser compatibility | Desktop | Mobile ---|---|--- | Chrome | Edge | Firefox | Opera | Safari | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet | WebView Android `setMatrixValue` | 61 | 79 | 33 | 48 | 11 | 61 | 33 | 45 | 11 | 8.0 | 61 ## See also * `DOMMatrix.translateSelf()` * `DOMMatrixReadOnly.is2D` * CSS `matrix()` function * CSS `matrix3d()` function # DOMMatrix: skewXSelf() method Baseline Widely available This feature is well established and works across many devices and browser versions. It’s been available across browsers since January 2020. * Learn more * See full compatibility * Report feedback **Note:** This feature is available in Web Workers. The `skewXSelf()` method of the `DOMMatrix` interface is a mutable transformation method that modifies a matrix. It skews the source matrix by applying the specified skew transformation along the X-axis and returns the skewed matrix. To skew a matrix along the X-axis without mutating it, see `DOMMatrixReadOnly.skewX()` ## Syntax skewXSelf() skewXSelf(sX) ### Parameters `sX` A number; the angle, in degrees, by which to skew the matrix along the X axis. ### Return value Returns itself; the `DOMMatrix` skewed along the X-axis by the given angle. ## Examples const matrix = new DOMMatrix(); // create a matrix console.log(matrix.toString()); // output: "matrix(1, 0, 0, 1, 0, 0)" matrix.skewXSelf(14); // mutate it console.log(matrix); // output: "matrix(1, 0, 0.25, 1, 0, 0)" ## Specifications ## Browser compatibility | Desktop | Mobile ---|---|--- | Chrome | Edge | Firefox | Opera | Safari | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet | WebView Android `skewXSelf` | 61 | 79 | 33 | 48 | 11 | 61 | 33 | 45 | 11 | 8.0 | 61 ## See also * `DOMMatrixReadOnly.skewX()` * CSS `transform` property * CSS `` functions * `skew()` * `skewX()` * `skewY()` * CSS transforms module * SVG `transform` attribute * `CanvasRenderingContext2D` interface methods * `CanvasRenderingContext2D.transform()` * `CanvasRenderingContext2D.setTransform()` * `CanvasRenderingContext2D.resetTransform()` # DOMMatrix: skewYSelf() method Baseline Widely available This feature is well established and works across many devices and browser versions. It’s been available across browsers since January 2020. * Learn more * See full compatibility * Report feedback **Note:** This feature is available in Web Workers. The `skewYSelf()` method of the `DOMMatrix` interface is a mutable transformation method that modifies a matrix. It skews the source matrix by applying the specified skew transformation along the Y-axis and returns the skewed matrix. To skew a matrix along the Y-axis without mutating it, see `DOMMatrixReadOnly.skewY()` ## Syntax skewYSelf() skewYSelf(sY) ### Parameters `sY` A number; the angle, in degrees, by which to skew the matrix along the Y axis. ### Return value Returns itself; the `DOMMatrix` skewed along the Y-axis by the given angle. ## Examples const matrix = new DOMMatrix(); // create a matrix console.log(matrix.toString()); // output: "matrix(1, 0, 0, 1, 0, 0)" matrix.skewYSelf(-14); // mutate it console.log(matrix); // output: "matrix(1, -0.25, 0, 1, 0, 0)" ## Specifications ## Browser compatibility | Desktop | Mobile ---|---|--- | Chrome | Edge | Firefox | Opera | Safari | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet | WebView Android `skewYSelf` | 61 | 79 | 33 | 48 | 11 | 61 | 33 | 45 | 11 | 8.0 | 61 ## See also * `DOMMatrixReadOnly.skewY()` * CSS `transform` property * CSS `` functions * `skew()` * `skewX()` * `skewY()` * CSS transforms module * SVG `transform` attribute * `CanvasRenderingContext2D` interface methods * `CanvasRenderingContext2D.transform()` * `CanvasRenderingContext2D.setTransform()` * `CanvasRenderingContext2D.resetTransform()` # DOMMatrixReadOnly Baseline Widely available This feature is well established and works across many devices and browser versions. It’s been available across browsers since January 2020. * Learn more * See full compatibility * Report feedback **Note:** This feature is available in Web Workers. The `DOMMatrixReadOnly` interface represents a read-only 4×4 matrix, suitable for 2D and 3D operations. The `DOMMatrix` interface — which is based upon `DOMMatrixReadOnly`—adds mutability, allowing you to alter the matrix after creating it. This interface should be available inside web workers, though some implementations doesn't allow it yet. ## Constructor `DOMMatrixReadOnly()` Creates a new `DOMMatrixReadOnly` object. ## Instance properties _This interface doesn't inherit any properties._ `DOMMatrixReadOnly.is2D` Read only A Boolean flag whose value is `true` if the matrix was initialized as a 2D matrix. If `false`, the matrix is 3D. `DOMMatrixReadOnly.isIdentity` Read only A Boolean whose value is `true` if the matrix is an identity matrix. `m11`, `m12`, `m13`, `m14`, `m21`, `m22`, `m23`, `m24`, `m31`, `m32`, `m33`, `m34`, `m41`, `m42`, `m43`, `m44` Double-precision floating-point values representing each component of a 4×4 matrix, where `m11` through `m14` are the first column, `m21` through `m24` are the second column, and so forth. `a`, `b`, `c`, `d`, `e`, `f` Double-precision floating-point values representing the components of a 4×4 matrix which are required in order to perform 2D rotations and translations. These are aliases for specific components of a 4×4 matrix, as shown below. 2D | 3D equivalent ---|--- `a` | `m11` `b` | `m12` `c` | `m21` `d` | `m22` `e` | `m41` `f` | `m42` ## Instance methods _This interface doesn't inherit any methods. None of the following methods alter the original matrix._ `DOMMatrixReadOnly.flipX()` Returns a new `DOMMatrix` created by flipping the source matrix around its X-axis. This is equivalent to multiplying the matrix by `DOMMatrix(-1, 0, 0, 1, 0, 0)`. The original matrix is not modified. `DOMMatrixReadOnly.flipY()` Returns a new `DOMMatrix` created by flipping the source matrix around its Y-axis. This is equivalent to multiplying the matrix by `DOMMatrix(1, 0, 0, -1, 0, 0)`. The original matrix is not modified. `DOMMatrixReadOnly.inverse()` Returns a new `DOMMatrix` created by inverting the source matrix. The original matrix is not altered. `DOMMatrixReadOnly.multiply()` Returns a new `DOMMatrix` created by computing the dot product of the source matrix and the specified matrix. The original matrix is not `DOMMatrixReadOnly.rotateAxisAngle()` Returns a new `DOMMatrix` created by rotating the source matrix by the given angle around the specified vector. The original matrix is not modified. `DOMMatrixReadOnly.rotate()` Returns a new `DOMMatrix` created by rotating the source matrix around each of its axes by the specified number of degrees. The original matrix is not altered. `DOMMatrixReadOnly.rotateFromVector()` Returns a new `DOMMatrix` created by rotating the source matrix by the angle between the specified vector and `(1, 0)`. The original matrix is not modified. `DOMMatrixReadOnly.scale()` Returns a new `DOMMatrix` created by scaling the source matrix by the amount specified for each axis, centered on the given origin. By default, the X and Z axes are scaled by `1` and the Y axis has no default scaling value. The default origin is `(0, 0, 0)`. The original matrix is not modified. `DOMMatrixReadOnly.scale3d()` Returns a new `DOMMatrix` created by scaling the source 3D matrix by the given factor along all its axes, centered on the specified origin point. The default origin is `(0, 0, 0)`. The original matrix is not modified. `DOMMatrixReadOnly.scaleNonUniform()` Deprecated Returns a new `DOMMatrix` created by applying the specified scaling on the X, Y, and Z axes, centered at the given origin. By default, the Y and Z axes' scaling factors are both `1`, but the scaling factor for X must be specified. The default origin is `(0, 0, 0)`. The original matrix is not changed. `DOMMatrixReadOnly.skewX()` Returns a new `DOMMatrix` created by applying the specified skew transformation to the source matrix along its X-axis. The original matrix is not modified. `DOMMatrixReadOnly.skewY()` Returns a new `DOMMatrix` created by applying the specified skew transformation to the source matrix along its Y-axis. The original matrix is not modified. `DOMMatrixReadOnly.toFloat32Array()` Returns a new `Float32Array` of single-precision floating-point numbers, containing all 16 elements which comprise the matrix. `DOMMatrixReadOnly.toFloat64Array()` Returns a new `Float64Array` of double-precision floating-point numbers, containing all 16 elements which comprise the matrix. `DOMMatrixReadOnly.toJSON()` Returns a JSON representation of the `DOMMatrixReadOnly` object. `DOMMatrixReadOnly.toString()` Creates and returns a string representation of the matrix in CSS matrix syntax, using the appropriate CSS matrix notation. `DOMMatrixReadOnly.transformPoint()` Transforms the specified point using the matrix, returning a new `DOMPoint` object containing the transformed point. Neither the matrix nor the original point are altered. `DOMMatrixReadOnly.translate()` Returns a new `DOMMatrix` containing a matrix calculated by translating the source matrix using the specified vector. By default, the vector is `(0, 0, 0)`. The original matrix is not changed. ## Static methods `fromFloat32Array()` Creates a new mutable `DOMMatrix` object given an array of single-precision (32-bit) floating-point values. If the array has six values, the result is a 2D matrix; if the array has 16 values, the result is a 3D matrix. Otherwise, a `TypeError` exception is thrown. `fromFloat64Array()` Creates a new mutable `DOMMatrix` object given an array of double-precision (64-bit) floating-point values. If the array has six values, the result is a 2D matrix; if the array has 16 values, the result is a 3D matrix. Otherwise, a `TypeError` exception is thrown. `fromMatrix()` Creates a new mutable `DOMMatrix` object given an existing matrix or an object which provides the values for its properties. If no matrix is specified, the matrix is initialized with every element set to `0` _except_ the bottom-right corner and the element immediately above and to its left: `m33` and `m34`. These have the default value of `1`. ## Specifications ## Browser compatibility | Desktop | Mobile ---|---|--- | Chrome | Edge | Firefox | Opera | Safari | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet | WebView Android `DOMMatrixReadOnly` | 61 | 79 | 62 | 48 | 11 | 61 | 62 | 45 | 11 | 8.0 | 61 `DOMMatrixReadOnly` | 61 | 79 | 33 | 48 | 11 | 61 | 33 | 45 | 11 | 8.0 | 61 `a` | 61 | 79 | 33 | 48 | 11 | 61 | 33 | 45 | 11 | 8.0 | 61 `b` | 61 | 79 | 33 | 48 | 11 | 61 | 33 | 45 | 11 | 8.0 | 61 `c` | 61 | 79 | 33 | 48 | 11 | 61 | 33 | 45 | 11 | 8.0 | 61 `d` | 61 | 79 | 33 | 48 | 11 | 61 | 33 | 45 | 11 | 8.0 | 61 `e` | 61 | 79 | 33 | 48 | 11 | 61 | 33 | 45 | 11 | 8.0 | 61 `f` | 61 | 79 | 33 | 48 | 11 | 61 | 33 | 45 | 11 | 8.0 | 61 `flipX` | 61 | 79 | 33 | 48 | 11 | 61 | 33 | 45 | 11 | 8.0 | 61 `flipY` | 61 | 79 | 33 | 48 | 11 | 61 | 33 | 45 | 11 | 8.0 | 61 `fromFloat32Array_static` | 61 | 79 | 69 | 48 | 11 | 61 | 79 | 45 | 11 | 8.0 | 61 `fromFloat64Array_static` | 61 | 79 | 69 | 48 | 11 | 61 | 79 | 45 | 11 | 8.0 | 61 `fromMatrix_static` | 61 | 79 | 69 | 48 | 11 | 61 | 79 | 45 | 11 | 8.0 | 61 `inverse` | 61 | 79 | 33 | 48 | 11 | 61 | 33 | 45 | 11 | 8.0 | 61 `is2D` | 61 | 79 | 33 | 48 | 11 | 61 | 33 | 45 | 11 | 8.0 | 61 `isIdentity` | 61 | 79 | 59 | 48 | 11 | 61 | 59 | 45 | 11 | 8.0 | 61 `m11` | 61 | 79 | 33 | 48 | 11 | 61 | 33 | 45 | 11 | 8.0 | 61 `m12` | 61 | 79 | 33 | 48 | 11 | 61 | 33 | 45 | 11 | 8.0 | 61 `m13` | 61 | 79 | 33 | 48 | 11 | 61 | 33 | 45 | 11 | 8.0 | 61 `m14` | 61 | 79 | 33 | 48 | 11 | 61 | 33 | 45 | 11 | 8.0 | 61 `m21` | 61 | 79 | 33 | 48 | 11 | 61 | 33 | 45 | 11 | 8.0 | 61 `m22` | 61 | 79 | 33 | 48 | 11 | 61 | 33 | 45 | 11 | 8.0 | 61 `m23` | 61 | 79 | 33 | 48 | 11 | 61 | 33 | 45 | 11 | 8.0 | 61 `m24` | 61 | 79 | 33 | 48 | 11 | 61 | 33 | 45 | 11 | 8.0 | 61 `m31` | 61 | 79 | 33 | 48 | 11 | 61 | 33 | 45 | 11 | 8.0 | 61 `m32` | 61 | 79 | 33 | 48 | 11 | 61 | 33 | 45 | 11 | 8.0 | 61 `m33` | 61 | 79 | 33 | 48 | 11 | 61 | 33 | 45 | 11 | 8.0 | 61 `m34` | 61 | 79 | 33 | 48 | 11 | 61 | 33 | 45 | 11 | 8.0 | 61 `m41` | 61 | 79 | 33 | 48 | 11 | 61 | 33 | 45 | 11 | 8.0 | 61 `m42` | 61 | 79 | 33 | 48 | 11 | 61 | 33 | 45 | 11 | 8.0 | 61 `m43` | 61 | 79 | 33 | 48 | 11 | 61 | 33 | 45 | 11 | 8.0 | 61 `m44` | 61 | 79 | 33 | 48 | 11 | 61 | 33 | 45 | 11 | 8.0 | 61 `multiply` | 61 | 79 | 33 | 48 | 11 | 61 | 33 | 45 | 11 | 8.0 | 61 `rotate` | 61 | 79 | 33 | 48 | 11 | 61 | 33 | 45 | 11 | 8.0 | 61 `rotateAxisAngle` | 61 | 79 | 33 | 48 | 11 | 61 | 33 | 45 | 11 | 8.0 | 61 `rotateFromVector` | 61 | 79 | 33 | 48 | 11 | 61 | 33 | 45 | 11 | 8.0 | 61 `scale` | 61 | 79 | 33Firefox 69 introduced support for the modern six-parameter syntax for `scale()`. Previously, it only supported the older three-parameter syntax: `scale(scaleX[, originX][, originY]]])`. | 48 | 11 | 61 | 33Firefox for Android 79 introduced support for the modern six-parameter syntax for `scale()`. Previously, it only supported the older three-parameter syntax: `scale(scaleX[, originX][, originY]]])`. | 45 | 11 | 8.0 | 61 `scale3d` | 61 | 79 | 33Starting in Firefox 69, the first parameter (`scale`) is now optional with a default value of 1, per the specification. Previously it was required. | 48 | 11 | 61 | 33Starting in Firefox for Android 79, the first parameter (`scale`) is now optional with a default value of 1, per the specification. Previously it was required. | 45 | 11 | 8.0 | 61 `scaleNonUniform` | 73 | 79 | 33 | 60 | 17.4 | 73 | 33 | 52 | 17.4 | 11.0 | 73 `skewX` | 61 | 79 | 33Before Firefox 69, the `sx` parameter was required; you may now call `skewX()` with no inputs. A value of 0 is correctly assumed. | 48 | 11 | 61 | 33Before Firefox for Android 79, the `sx` parameter was required; you may now call `skewX()` with no inputs. A value of 0 is correctly assumed. | 45 | 11 | 8.0 | 61 `skewY` | 61 | 79 | 33Before Firefox 69, the `sy` parameter was required; you may now call `skewY()` with no inputs. A value of 0 is correctly assumed. | 48 | 11 | 61 | 33Before Firefox for Android 79, the `sy` parameter was required; you may now call `skewY()` with no inputs. A value of 0 is correctly assumed. | 45 | 11 | 8.0 | 61 `toFloat32Array` | 61 | 79 | 33 | 48 | 11 | 61 | 33 | 45 | 11 | 8.0 | 61 `toFloat64Array` | 61 | 79 | 33 | 48 | 11 | 61 | 33 | 45 | 11 | 8.0 | 61 `toJSON` | 61 | 79 | 62 | 48 | 11 | 61 | 62 | 45 | 11 | 8.0 | 61 `toString` | 61 | 79 | 33 | 48 | 11 | 61 | 33 | 45 | 11 | 8.0 | 61 `transformPoint` | 61 | 79 | 33 | 48 | 11 | 61 | 33 | 45 | 11 | 8.0 | 61 `translate` | 61 | 79 | 33 | 48 | 11 | 61 | 33 | 45 | 11 | 8.0 | 61 `worker_support` | 61 | 79 | 69 | 48 | 11 | 61 | 79 | 45 | 11 | 8.0 | 61 ## See also * The mutable matrix type, `DOMMatrix`, which is based on this one. * The CSS `matrix()` and `matrix3d()` functional notation that can be generated from this interface to be used in a CSS `transform`. # DOMMatrixReadOnly: DOMMatrixReadOnly() constructor Baseline Widely available This feature is well established and works across many devices and browser versions. It’s been available across browsers since January 2020. * Learn more * See full compatibility * Report feedback **Note:** This feature is available in Web Workers. The `DOMMatrixReadOnly` constructor creates a new `DOMMatrixReadOnly` object which represents 4x4 matrices, suitable for 2D and 3D operations. ## Syntax DOMMatrixReadOnly() DOMMatrixReadOnly(init) ### Parameters `init` Optional Either a string containing a sequence of numbers or an array of numbers specifying the matrix you want to create. In case an array of numbers is passed, the behavior depends on the length of the array: * for a 6-element array of components in the form `[a, b, c, d, e, f]`, a 2D read-only matrix is created, initialized with the provided components. * for a 16-element array of components (in the column-major order) in the form `[m11, m12, m13, …, m42, m43, m44]`, a 3D read-only matrix is created, initialized with the provided components. ## Specifications ## Browser compatibility | Desktop | Mobile ---|---|--- | Chrome | Edge | Firefox | Opera | Safari | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet | WebView Android `DOMMatrixReadOnly` | 61 | 79 | 62 | 48 | 11 | 61 | 62 | 45 | 11 | 8.0 | 61 # DOMMatrixReadOnly: flipX() method Baseline Widely available This feature is well established and works across many devices and browser versions. It’s been available across browsers since January 2020. * Learn more * See full compatibility * Report feedback **Note:** This feature is available in Web Workers. The `flipX()` method of the `DOMMatrixReadOnly` interface creates a new matrix being the result of the original matrix flipped about the x-axis. This is equivalent to multiplying the matrix by `DOMMatrix(-1, 0, 0, 1, 0, 0)`. The original matrix is not modified. ## Syntax flipX() ### Return value Returns a `DOMMatrix`. ## Examples ### Inverting a triangle In this example, the SVG contains two paths in the shape of a triangle, both drawn to the same position. Note that the x co-ordinate of the viewBox attribute is negative, showing us content from both sides of the x-axis. #### HTML #### JavaScript The JavaScript first creates an identity matrix, then uses the `flipX()` method to create a new matrix, which is then applied to the blue triangle, inverting it across the x-axis. The red triangle is left in place. const flipped = document.getElementById("flipped"); const matrix = new DOMMatrixReadOnly(); const flippedMatrix = matrix.flipX(); flipped.setAttribute("transform", flippedMatrix.toString()); #### Result ## Specifications ## Browser compatibility | Desktop | Mobile ---|---|--- | Chrome | Edge | Firefox | Opera | Safari | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet | WebView Android `flipX` | 61 | 79 | 33 | 48 | 11 | 61 | 33 | 45 | 11 | 8.0 | 61 ## See also * `DOMMatrixReadOnly.flipY()` # DOMMatrixReadOnly: flipY() method Baseline Widely available This feature is well established and works across many devices and browser versions. It’s been available across browsers since January 2020. * Learn more * See full compatibility * Report feedback **Note:** This feature is available in Web Workers. The `flipY()` method of the `DOMMatrixReadOnly` interface creates a new matrix being the result of the original matrix flipped about the y-axis. This is equivalent to multiplying the matrix by `DOMMatrix(1, 0, 0, -1, 0, 0)`. The original matrix is not modified. ## Syntax flipY() ### Return value A `DOMMatrix`. ## Examples ### Inverting a triangle In this example, the SVG contains two identical paths in the shape of a triangle; they are both drawn to have the same size and position. The view box has a negative y value showing us content from both sides of the y-axis. This enables the flipped triangle to be withing the viewport after it is transformed. #### HTML #### JavaScript The JavaScript creates an identity matrix, then uses the `flipY()` method to create a new matrix, which is then applied to the blue triangle, inverting it across the y-axis. The red triangle is left in place. const flipped = document.getElementById("flipped"); const matrix = new DOMMatrix(); const flippedMatrix = matrix.flipY(); flipped.setAttribute("transform", flippedMatrix.toString()); #### Result ## Specifications ## Browser compatibility | Desktop | Mobile ---|---|--- | Chrome | Edge | Firefox | Opera | Safari | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet | WebView Android `flipY` | 61 | 79 | 33 | 48 | 11 | 61 | 33 | 45 | 11 | 8.0 | 61 ## See also * `DOMMatrixReadOnly.flipX()` # DOMMatrixReadOnly: inverse() method Baseline Widely available This feature is well established and works across many devices and browser versions. It’s been available across browsers since January 2020. * Learn more * See full compatibility * Report feedback **Note:** This feature is available in Web Workers. The `inverse()` method of the `DOMMatrixReadOnly` interface creates a new matrix which is the inverse of the original matrix. If the matrix cannot be inverted, the new matrix's components are all set to `NaN` and its `is2D` property is set to `false`. The original matrix is not changed. To mutate the matrix as you invert it, see `DOMMatrix.invertSelf()`. ## Syntax inverse() ### Return value A `DOMMatrix`. ## Examples const matrix = new DOMMatrixReadOnly().rotate(30); const invertedMatrix = matrix.inverse(); console.log(matrix.toString()); // output: matrix(0.866, 0.5, -0.5, 0.866, 0, 0) console.log(invertedMatrix.toString()); // output: matrix(0.866, -0.5, 0.5, 0.866, 0, 0) ## Specifications ## Browser compatibility | Desktop | Mobile ---|---|--- | Chrome | Edge | Firefox | Opera | Safari | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet | WebView Android `inverse` | 61 | 79 | 33 | 48 | 11 | 61 | 33 | 45 | 11 | 8.0 | 61 ## See also * `DOMMatrix.invertSelf()` * `DOMMatrixReadOnly.flipX()` * `DOMMatrixReadOnly.flipY()` * CSS `matrix()` function * CSS `matrix3d()` function # DOMMatrixReadOnly: is2D property Baseline Widely available This feature is well established and works across many devices and browser versions. It’s been available across browsers since January 2020. * Learn more * See full compatibility * Report feedback **Note:** This feature is available in Web Workers. The readonly `is2D` property of the `DOMMatrixReadOnly` interface is a Boolean flag that is `true` when the matrix is 2D. The value is `true` if the matrix was initialized as a 2D matrix and only 2D transformation operations were applied. Otherwise, the matrix is defined in 3D, and `is2D` is `false`. ## Value A Boolean value. ## Examples // Initialize a 2D matrix const matrix = new DOMMatrix(); // create a matrix console.log(matrix.is2D); // output: true // Transform in a 2D space console.log(matrix.rotate(30).is2D); // output: true // Apply a 3D transform console.log(matrix.rotate(10, 20, 1).is2D); // output: false ## Specifications ## Browser compatibility | Desktop | Mobile ---|---|--- | Chrome | Edge | Firefox | Opera | Safari | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet | WebView Android `is2D` | 61 | 79 | 33 | 48 | 11 | 61 | 33 | 45 | 11 | 8.0 | 61 ## See also * `CSSTransformValue.is2D` * `CSSTransformComponent.is2D` * CSS `` functions * CSS `transform` property * CSS transforms module * SVG `transform` attribute * `CanvasRenderingContext2D` interface # DOMMatrixReadOnly: isIdentity property Baseline Widely available This feature is well established and works across many devices and browser versions. It’s been available across browsers since January 2020. * Learn more * See full compatibility * Report feedback **Note:** This feature is available in Web Workers. The readonly `isIdentity` property of the `DOMMatrixReadOnly` interface is a Boolean whose value is `true` if the matrix is the identity matrix. The identity matrix is one in which every value is `0` _except_ those on the main diagonal from top-left to bottom-right corner (in other words, where the offsets in each direction are equal). ## Value A Boolean value. ## Examples // Initialize a 2D matrix const matrix = new DOMMatrix(); // create a matrix console.log(matrix.isIdentity); // output: true // Apply a transform that has no effect console.log(matrix.translate(0).isIdentity); // output: true // Apply a transform with effect: this rotates the matrix by 30deg console.log(matrix.rotate(30).isIdentity); // output: false ## Specifications ## Browser compatibility | Desktop | Mobile ---|---|--- | Chrome | Edge | Firefox | Opera | Safari | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet | WebView Android `isIdentity` | 61 | 79 | 59 | 48 | 11 | 61 | 59 | 45 | 11 | 8.0 | 61 ## See also * `DOMMatrix` interface * `CSSMatrixComponent` interface * `CanvasRenderingContext2D` interface * CSS `matrix()` function * CSS `transform` property * CSS transforms module * SVG `transform` attribute # DOMMatrixReadOnly: multiply() method Baseline Widely available This feature is well established and works across many devices and browser versions. It’s been available across browsers since January 2020. * Learn more * See full compatibility * Report feedback **Note:** This feature is available in Web Workers. The `multiply()` method of the `DOMMatrixReadOnly` interface creates and returns a new matrix which is the dot product of the matrix and the `otherMatrix` parameter. If `otherMatrix` is omitted, the matrix is multiplied by a matrix in which every element is `0` _except_ the bottom-right corner and the element immediately above and to its left: `m33` and `m34`. These have the default value of `1`. The original matrix is not modified. To mutate the matrix as you multiply it, see `DOMMatrix.multiplySelf()`. ## Syntax multiply() multiply(otherMatrix) ### Parameters `otherMatrix` Optional The `DOMMatrix` multiplier. ### Return value A `DOMMatrix`. ## Examples const matrix = new DOMMatrixReadOnly().translate(13, 21); const multipliedMatrix = matrix.multiply(matrix); console.log(matrix.toString()); // output: matrix(1, 0, 0, 1, 13, 21) console.log(multipliedMatrix.toString()); // output: matrix(1, 0, 0, 1, 26, 42) ## Specifications ## Browser compatibility | Desktop | Mobile ---|---|--- | Chrome | Edge | Firefox | Opera | Safari | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet | WebView Android `multiply` | 61 | 79 | 33 | 48 | 11 | 61 | 33 | 45 | 11 | 8.0 | 61 ## See also * `DOMMatrix.multiplySelf()` * `DOMMatrix.preMultiplySelf()` * CSS `matrix()` function * CSS `matrix3d()` function # DOMMatrixReadOnly: rotate() method Baseline Widely available This feature is well established and works across many devices and browser versions. It’s been available across browsers since January 2020. * Learn more * See full compatibility * Report feedback **Note:** This feature is available in Web Workers. The `rotate()` method of the `DOMMatrixReadOnly` interface returns a new `DOMMatrix` created by rotating the source matrix around each of its axes by the specified number of degrees. The original matrix is not altered. To mutate the matrix as you rotate it, see `DOMMatrix.rotateSelf()`. ## Syntax rotate() rotate(rotX) rotate(rotX, rotY) rotate(rotX, rotY, rotZ) ### Parameters `rotX` A number; the x-coordinate of the vector denoting the axis of rotation. If non-zero, `is2D` is false. `rotY` Optional A number; the y-coordinate of the vector denoting the axis of rotation. If non-zero, `is2D` is false. `rotZ` Optional A number; the z-coordinate of the vector denoting the axis of rotation. If only `rotX` is passed, then `rotX` is used as the value for the z-coordinate, and the x- and -y-coordinates are both set to zero. ### Return value A `DOMMatrix`. ## Examples const matrix = new DOMMatrix(); // create a matrix console.log(matrix.toString()); // output: "matrix(1, 0, 0, 1, 0, 0)" const rotated = matrix.rotate(30); // rotation and assignment console.log(matrix.toString()); // original matrix is unchanged // output: "matrix(1, 0, 0, 1, 0, 0)" console.log(rotated.toString()); // output: "matrix(0.866, 0.5, -0.5, 0.866, 0, 0)" ## Specifications ## Browser compatibility | Desktop | Mobile ---|---|--- | Chrome | Edge | Firefox | Opera | Safari | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet | WebView Android `rotate` | 61 | 79 | 33 | 48 | 11 | 61 | 33 | 45 | 11 | 8.0 | 61 ## See also * `DOMMatrix.rotateSelf()` * `DOMMatrixReadOnly.rotateAxisAngle()` * `DOMMatrixReadOnly.rotateFromVector()` * CSS `transform` property and `rotate3d()` function * CSS `rotate` property * CSS transforms module * SVG `transform` attribute * `CanvasRenderingContext2D` interface and `rotate()` method # DOMMatrixReadOnly: rotateAxisAngle() method Baseline Widely available This feature is well established and works across many devices and browser versions. It’s been available across browsers since January 2020. * Learn more * See full compatibility * Report feedback **Note:** This feature is available in Web Workers. The `rotateAxisAngle()` method of the `DOMMatrixReadOnly` interface returns a new `DOMMatrix` created by rotating the source matrix by the given vector and angle. The original matrix is not altered. To mutate the matrix as you rotate it, see `DOMMatrix.rotateAxisAngleSelf()`. ## Syntax rotateAxisAngle() rotateAxisAngle(rotX) rotateAxisAngle(rotX, rotY) rotateAxisAngle(rotX, rotY, rotZ) rotateAxisAngle(rotX, rotY, rotZ, angle) ### Parameters `rotX` A number; the x-coordinate of the vector denoting the axis of rotation. If non-zero, `is2D` is false. `rotY` Optional A number; the y-coordinate of the vector denoting the axis of rotation. If undefined, the `rotX` value is used. If non-zero, `is2D` is false. `rotZ` Optional A number; the z-coordinate of the vector denoting the axis of rotation. If undefined, the `rotX` value is used. `angle` Optional A number; the angle of the rotation around the axis vector, in degrees. ### Return value A `DOMMatrix`. ## Examples const matrix = new DOMMatrix(); // create a matrix console.log(matrix.rotateAxisAngle().toString()); // matrix(1, 0, 0, 1, 0, 0) console.log(matrix.rotateAxisAngle(10, 20, 30).toString()); // matrix(1, 0, 0, 1, 0, 0) console.log(matrix.rotateAxisAngle(10, 20, 30, 45).toString()); /* matrix3d( 0.728, 0.609, -0.315, 0, -0.525, 0.791, 0.315, 0, 0.441, -0.063, 0.895, 0, 0, 0, 0, 1) */ console.log(matrix.rotateAxisAngle(5, 5, 5, -45).toString()); /* matrix3d( 0.805, -0.311, 0.506, 0, 0.506, 0.805, -0.311, 0, -0.311, 0.506, 0.805, 0, 0, 0, 0, 1) */ console.log(matrix.toString()); // output: "matrix(1, 0, 0, 1, 0, 0)" (unchanged) ## Specifications ## Browser compatibility | Desktop | Mobile ---|---|--- | Chrome | Edge | Firefox | Opera | Safari | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet | WebView Android `rotateAxisAngle` | 61 | 79 | 33 | 48 | 11 | 61 | 33 | 45 | 11 | 8.0 | 61 ## See also * `DOMMatrix.rotateAxisAngleSelf()` * `DOMMatrixReadOnly.rotate()` * `DOMMatrixReadOnly.rotateFromVector()` * CSS `transform` property and `rotate3d()` function * CSS `rotate` property * CSS transforms module * SVG `transform` attribute * `CanvasRenderingContext2D` interface and `rotate()` method # DOMMatrixReadOnly: rotateFromVector() method Baseline Widely available This feature is well established and works across many devices and browser versions. It’s been available across browsers since January 2020. * Learn more * See full compatibility * Report feedback **Note:** This feature is available in Web Workers. The `rotateFromVector()` method of the `DOMMatrixReadOnly` interface is returns a new `DOMMatrix` created by rotating the source matrix by the angle between the specified vector and `(1, 0)`. The rotation angle is determined by the angle between the vector `(1,0)T` and `(x,y)T` in the clockwise direction, or `(+/-)arctan(y/x)`. If `x` and `y` are both `0`, the angle is specified as `0`. The original matrix is not altered. To mutate the matrix as you rotate it by the angle between the specified vector and `(1, 0)`, see `DOMMatrix.rotateFromVectorSelf()`. ## Syntax rotateFromVector() rotateFromVector(rotX) rotateFromVector(rotX, rotY) ### Parameters `rotX` Optional A number; The x-coordinate of the x,y vector that determines the rotation angle. If undefined, `0` is used. `rotY` Optional A number; The y-coordinate of the x,y vector that determines the rotation angle. If undefined, `0` is used. ### Return value A `DOMMatrix`. ## Examples const matrix = new DOMMatrix(); // create a matrix console.log(matrix.toString()); // original value // output: "matrix(1, 0, 0, 1, 0, 0)" console.log(matrix.rotateFromVector().toString()); // defaults to `0` // output: matrix(1, 0, 0, 1, 0, 0) console.log(matrix.rotateFromVector(10, 20).toString()); // matrix(0.447, 0.894, -0.894, 0.447, 0, 0) console.log(matrix.rotateFromVector(-5, 5).toString()); // matrix(-0.707, 0.707, -0.707, -0.707, 0, 0) console.log(matrix.toString()); // matrix remains unchanged // output: "matrix(1, 0, 0, 1, 0, 0)" ## Specifications ## Browser compatibility | Desktop | Mobile ---|---|--- | Chrome | Edge | Firefox | Opera | Safari | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet | WebView Android `rotateFromVector` | 61 | 79 | 33 | 48 | 11 | 61 | 33 | 45 | 11 | 8.0 | 61 ## See also * `DOMMatrix.rotateFromVectorSelf()` * `DOMMatrixReadOnly.rotate()` * `DOMMatrixReadOnly.rotateAxisAngle()` * CSS `transform` property and `rotate3d()` function * CSS `rotate` property * CSS transforms module * SVG `transform` attribute * `CanvasRenderingContext2D` interface and `rotate()` method # DOMMatrixReadOnly: scale() method Baseline Widely available This feature is well established and works across many devices and browser versions. It’s been available across browsers since January 2020. * Learn more * See full compatibility * Report feedback **Note:** This feature is available in Web Workers. The `scale()` method of the `DOMMatrixReadOnly` interface creates a new matrix being the result of the original matrix with a scale transform applied. ## Syntax scale(scaleX) scale(scaleX, scaleY) scale(scaleX, scaleY, scaleZ) scale(scaleX, scaleY, scaleZ, originX) scale(scaleX, scaleY, scaleZ, originX, originY) scale(scaleX, scaleY, scaleZ, originX, originY, originZ) ### Parameters `scaleX` A multiplier for the scale value on the x-axis. `scaleY` Optional A multiplier for the scale value on the y-axis. If not supplied, this defaults to the value of `scaleX`. `scaleZ` Optional A multiplier for the scale value on the z-axis. If this value is anything other than 1, the resulting matrix will be 3D. `originX` Optional An x-coordinate for the origin of the transformation. If no origin is supplied, this defaults to 0. `originY` Optional A y-coordinate for the origin of the transformation. If no origin is supplied, this defaults to 0. `originZ` Optional A z-coordinate for the origin of the transformation. If no origin is supplied, this defaults to 0. If this value is anything other than 0, the resulting matrix will be 3D. ### Return value Returns a `DOMMatrix` containing a new matrix being the result of the matrix x and y dimensions being scaled by the given factor, centered on the origin given. The original matrix is not modified. If a scale is applied about the z-axis, the resulting matrix will be a 4✕4 3D matrix. ## Examples This SVG contains three squares, one red, one blue, and one green, each positioned at the document origin: This JavaScript first creates an identity matrix, then uses the `scale()` method to create a new matrix with a single parameter. We test if the browser supports a six parameter `scale()` method by creating a new matrix using three parameters and observing its `is2D` property. If this is `false` then the third parameter has been accepted by the browser as a `scaleZ` parameter, making this a 3D matrix. We then create a new matrix scaled about a given origin, using either three or six parameters depending on the browser support. These new matrices are then applied to the blue and green squares as a `transform`, changing their dimensions and position. The red square is left in place. const matrix = new DOMMatrixReadOnly(); const scaledMatrix = matrix.scale(0.5); let scaledMatrixWithOrigin = matrix.scale(0.5, 25, 25); // if the browser has interpreted these parameters as scaleX, scaleY, scaleZ, the resulting matrix is 3D const browserExpectsSixParamScale = !scaledMatrixWithOrigin.is2D; if (browserExpectsSixParamScale) { scaledMatrixWithOrigin = matrix.scale(0.5, 0.5, 1, 25, 25, 0); } document .querySelector("#transformed") .setAttribute("transform", scaledMatrix.toString()); document .querySelector("#transformedOrigin") .setAttribute("transform", scaledMatrixWithOrigin.toString()); ## Specifications ## Browser compatibility | Desktop | Mobile ---|---|--- | Chrome | Edge | Firefox | Opera | Safari | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet | WebView Android `scale` | 61 | 79 | 33Firefox 69 introduced support for the modern six-parameter syntax for `scale()`. Previously, it only supported the older three-parameter syntax: `scale(scaleX[, originX][, originY]]])`. | 48 | 11 | 61 | 33Firefox for Android 79 introduced support for the modern six-parameter syntax for `scale()`. Previously, it only supported the older three-parameter syntax: `scale(scaleX[, originX][, originY]]])`. | 45 | 11 | 8.0 | 61 # DOMMatrixReadOnly: scale3d() method Baseline Widely available This feature is well established and works across many devices and browser versions. It’s been available across browsers since January 2020. * Learn more * See full compatibility * Report feedback **Note:** This feature is available in Web Workers. The `scale3d()` method of the `DOMMatrixReadOnly` interface creates a new matrix which is the result of a 3D scale transform being applied to the matrix. It returns a new `DOMMatrix` created by scaling the source 3d matrix by the given scale factor centered on the origin point specified by the origin parameters, with a default origin of `(0, 0, 0)`. The original matrix is not modified. To mutate the matrix as you 3D-scale it, see `DOMMatrix.scale3dSelf()` ## Syntax scale3d() scale3d(scale) scale3d(scale, originX) scale3d(scale, originX, originY) scale3d(scale, originX, originY, originZ) ### Parameters `scale` A multiplier; the scale value. If no scale is supplied, this defaults to `1`. `originX` Optional An x-coordinate for the origin of the transformation. If no origin is supplied, this defaults to `0`. `originY` Optional A y-coordinate for the origin of the transformation. If no origin is supplied, this defaults to `0`. `originZ` Optional A z-coordinate for the origin of the transformation. If this value is `0`, the default if omitted, the resulting matrix may not be 3d. ### Return value A `DOMMatrix`. ## Examples const matrix = new DOMMatrix(); console.log(matrix.toString()); // no transforms applied // matrix(1, 0, 0, 1, 0, 0) console.log(matrix.scale3d(2).toString()); /* matrix3d( 2, 0, 0, 0, 0, 2, 0, 0, 0, 0, 2, 0, 0, 0, 0, 1) */ console.log(matrix.scale3d(0.5, 25, 25, 1.25).toString()); /* matrix3d( 0.5, 0, 0, 0, 0, 0.5, 0, 0, 0, 0, 0.5, 0, 1 2.5, 12.5, 0.625, 1) */ console.log(matrix.toString()); // original matrix is unchanged // matrix(1, 0, 0, 1, 0, 0) ## Specifications ## Browser compatibility | Desktop | Mobile ---|---|--- | Chrome | Edge | Firefox | Opera | Safari | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet | WebView Android `scale3d` | 61 | 79 | 33Starting in Firefox 69, the first parameter (`scale`) is now optional with a default value of 1, per the specification. Previously it was required. | 48 | 11 | 61 | 33Starting in Firefox for Android 79, the first parameter (`scale`) is now optional with a default value of 1, per the specification. Previously it was required. | 45 | 11 | 8.0 | 61 ## See also * `DOMMatrix.scale3dSelf()` * `DOMMatrixReadOnly.scale()` * CSS `transform` property and `scale3d()` and `matrix3d()` functions * CSS transforms module * SVG `transform` attribute * `CanvasRenderingContext2D` interface's `CanvasRenderingContext2D.transform()` method # DOMMatrixReadOnly: skewX() method Baseline Widely available This feature is well established and works across many devices and browser versions. It’s been available across browsers since January 2020. * Learn more * See full compatibility * Report feedback **Note:** This feature is available in Web Workers. The `skewX()` method of the `DOMMatrixReadOnly` interface returns a new `DOMMatrix` created by applying the specified skew transformation to the source matrix along its x-axis. The original matrix is not modified. To mutate the matrix as you skew it along the x-axis, see `DOMMatrix.skewXSelf()`. ## Syntax skewX() skewX(sX) ### Parameters `sX` A number; the angle, in degrees, by which to skew the matrix along the x-axis. ### Return value A `DOMMatrix`. ## Examples const matrix = new DOMMatrix(); // create a matrix console.log(matrix.toString()); // no transform applied // "matrix(1, 0, 0, 1, 0, 0)" console.log(matrix.skewX(14).toString()); // "matrix(1, 0, 0.25, 1, 0, 0)" console.log(matrix.toString()); // original is unchanged // "matrix(1, 0, 0, 1, 0, 0)" ## Specifications ## Browser compatibility | Desktop | Mobile ---|---|--- | Chrome | Edge | Firefox | Opera | Safari | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet | WebView Android `skewX` | 61 | 79 | 33Before Firefox 69, the `sx` parameter was required; you may now call `skewX()` with no inputs. A value of 0 is correctly assumed. | 48 | 11 | 61 | 33Before Firefox for Android 79, the `sx` parameter was required; you may now call `skewX()` with no inputs. A value of 0 is correctly assumed. | 45 | 11 | 8.0 | 61 ## See also * `DOMMatrixReadOnly.skewY()` * `DOMMatrix.skewXSelf()` * CSS `transform` property and the `skew()`, `skewX()`, and `matrix()` functions * CSS transforms module * SVG `transform` attribute * `CanvasRenderingContext2D` interface's `transform()` method # DOMMatrixReadOnly: skewY() method Baseline Widely available This feature is well established and works across many devices and browser versions. It’s been available across browsers since January 2020. * Learn more * See full compatibility * Report feedback **Note:** This feature is available in Web Workers. The `skewY()` method of the `DOMMatrixReadOnly` interface returns a new `DOMMatrix` created by applying the specified skew transformation to the source matrix along its y-axis. The original matrix is not modified. To mutate the matrix as you skew it along the y-axis, see `DOMMatrix.skewYSelf()`. ## Syntax skewY() skewY(sY) ### Parameters `sY` A number; the angle, in degrees, by which to skew the matrix along the y-axis. ### Return value A `DOMMatrix`. ## Examples const matrix = new DOMMatrix(); // create a matrix console.log(matrix.toString()); // original value // "matrix(1, 0, 0, 1, 0, 0)" console.log(matrix.skewY(14).toString()); // skew along y-axis // "matrix(1, -0.25, 0, 1, 0, 0)" console.log(matrix.toString()); // original unchanged // "matrix(1, 0, 0, 1, 0, 0)" ## Specifications ## Browser compatibility | Desktop | Mobile ---|---|--- | Chrome | Edge | Firefox | Opera | Safari | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet | WebView Android `skewY` | 61 | 79 | 33Before Firefox 69, the `sy` parameter was required; you may now call `skewY()` with no inputs. A value of 0 is correctly assumed. | 48 | 11 | 61 | 33Before Firefox for Android 79, the `sy` parameter was required; you may now call `skewY()` with no inputs. A value of 0 is correctly assumed. | 45 | 11 | 8.0 | 61 ## See also * `DOMMatrix.skewYSelf()` * `DOMMatrixReadOnly.skewX()` * CSS `transform` property and the `skew()`, `skewY()`, and `matrix()` functions * CSS transforms module * SVG `transform` attribute * `CanvasRenderingContext2D` interface's `transform()` method # DOMMatrixReadOnly: toFloat32Array() method Baseline Widely available This feature is well established and works across many devices and browser versions. It’s been available across browsers since January 2020. * Learn more * See full compatibility * Report feedback The `toFloat32Array()` method of the `DOMMatrixReadOnly` interface returns a new `Float32Array` containing all 16 elements (`m11`, `m12`, `m13`, `m14`, `m21`, `m22`, `m23`, `m24`, `m31`, `m32`, `m33`, `m34`, `m41`, `m42`, `m43`, `m44`) which comprise the matrix. The elements are stored into the array as single-precision floating-point numbers in column-major (colexographical access, or "colex") order. (In other words, down the first column from top to bottom, then the second column, and so forth.) For double-precision floating-point numbers, see `DOMMatrixReadOnly.toFloat64Array()`. ## Syntax toFloat32Array() ### Parameters None. ### Return value A `Float32Array`; an array of the matrix's 16 element values. ## Examples ### Basic usage const matrix = new DOMMatrixReadOnly(); const float32 = matrix.translate(20, 30, 50).toFloat32Array(); console.log(float32); // Float64Array(16) [ 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 20, 30, 0, 1 ] ] console.log(`m41: ${float32[12]}, m42: ${float32[13]}, m43: ${float32[14]}`); // m41: 20, m42: 30, M44: 40 ### Single precision There are multiple ways to access the values of a matrix. This example rotates a matrix by 30deg, saving the rotated state as a JSON object using the `DOMMatrixReadOnly.toJSON()` method and as a single-precision array using the `toFloat32Array()` method. const matrix = new DOMMatrixReadOnly(); const json = matrix.rotate(30).toJSON(); const float32 = matrix.rotate(30).toFloat32Array(); console.log(`a: ${json["a"]}, b: ${json["b"]}`); // a: 0.8660254037844387, b: 0.49999999999999994 console.log(`a: ${float32[0]}, b: ${float32[1]}`); // a: 0.8660253882408142, b: 0.5 ## Specifications ## Browser compatibility | Desktop | Mobile ---|---|--- | Chrome | Edge | Firefox | Opera | Safari | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet | WebView Android `toFloat32Array` | 61 | 79 | 33 | 48 | 11 | 61 | 33 | 45 | 11 | 8.0 | 61 ## See also * `DOMMatrixReadOnly.toFloat64Array()` * `DOMMatrix.setMatrixValue()` # DOMMatrixReadOnly: toFloat64Array() method Baseline Widely available This feature is well established and works across many devices and browser versions. It’s been available across browsers since January 2020. * Learn more * See full compatibility * Report feedback The `toFloat64Array()` method of the `DOMMatrixReadOnly` interface returns a new `Float64Array` containing all 16 elements (`m11`, `m12`, `m13`, `m14`, `m21`, `m22`, `m23`, `m24`, `m31`, `m32`, `m33`, `m34`, `m41`, `m42`, `m43`, `m44`) which comprise the matrix. The elements are stored into the array as double-precision floating-point numbers in column-major (colexographical access, or "colex") order. (In other words, down the first column from top to bottom, then the second column, and so forth.) ## Syntax toFloat64Array() ### Parameters None. ### Return value A `Float64Array`; an array of the matrix's 16 element values. ## Examples const matrix = new DOMMatrixReadOnly(); let float64 = matrix.translate(20, 30, 50).toFloat64Array(); console.log(float64); // Float64Array(16) [ 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 20, 30, 0, 1 ] ] console.log(`m41: ${float64[12]}, m42: ${float64[13]}, m43: ${float64[14]}`); // m41: 20, m42: 30, M44: 40 float64 = matrix.rotate(30).toFloat64Array(); console.log(float64); console.log(`m11: ${float64[0]}, m12: ${float64[1]}`); // m11: 0.8660254037844387, m12: 0.49999999999999994 ## Specifications ## Browser compatibility | Desktop | Mobile ---|---|--- | Chrome | Edge | Firefox | Opera | Safari | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet | WebView Android `toFloat64Array` | 61 | 79 | 33 | 48 | 11 | 61 | 33 | 45 | 11 | 8.0 | 61 ## See also * `DOMMatrixReadOnly.toFloat32Array()` * `DOMMatrix.setMatrixValue()` # DOMMatrixReadOnly: toJSON() method Baseline Widely available This feature is well established and works across many devices and browser versions. It’s been available across browsers since January 2020. * Learn more * See full compatibility * Report feedback The `toJSON()` method of the `DOMMatrixReadOnly` interface creates and returns a `JSON` object. The JSON object includes the 2D matrix elements `a` through `f`, the 16 elements of the 4X4 3D matrix, `m[1-4][1-4]`, the boolean `is2D` property, and the boolean `isIdentity` property. ## Syntax toJSON() ### Parameters None. ### Return value A `JSON` object; a JSON representation of the `DOMMatrixReadOnly` object. ## Examples const matrix = new DOMMatrixReadOnly(); console.log(matrix.translate(20, 30).toJSON()); /* { "a": 1, "b": 0, "c": 0, "d": 1, "e": 20, "f": 30, "m11": 1, "m12": 0, "m13": 0, "m14": 0, "m21": 0, "m22": 1, "m23": 0, "m24": 0, "m31": 0, "m32": 0, "m33": 1, "m34": 0, "m41": 20, "m42": 30, "m43": 0, "m44": 1, "is2D": true, "isIdentity": false } */ console.log(matrix.translate(22, 55, 66).toJSON()); /* { "a": 1, "b": 0, "c": 0, "d": 1, "e": 22, "f": 55, "m11": 1, "m12": 0, "m13": 0, "m14": 0, "m21": 0, "m22": 1, "m23": 0, "m24": 0, "m31": 0, "m32": 0, "m33": 1, "m34": 0, "m41": 22, "m42": 55, "m43": 66, "m44": 1, "is2D": false, "isIdentity": false } */ ## Specifications ## Browser compatibility | Desktop | Mobile ---|---|--- | Chrome | Edge | Firefox | Opera | Safari | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet | WebView Android `toJSON` | 61 | 79 | 62 | 48 | 11 | 61 | 62 | 45 | 11 | 8.0 | 61 ## See also * `DOMMatrixReadOnly.toString()` * `DOMMatrix.setMatrixValue()` # DOMMatrixReadOnly: toString() method Baseline Widely available This feature is well established and works across many devices and browser versions. It’s been available across browsers since January 2020. * Learn more * See full compatibility * Report feedback The `toString()` stringifier of the `DOMMatrixReadOnly` interface returns the value of the matrix as a string in the form of a `matrix()` or `matrix3d()` CSS transform function; comma-separated lists of 6 or 16 coordinate values, prepended by `"matrix(` or `"matrix3d(` respectively, appended by `)"`. For a 2D matrix, the elements `a` through `f` are listed, for a total of six values and the form `matrix(a, b, c, d, e, f)`. See the `matrix()` CSS function for details on this syntax. For a 3D matrix, the returned string contains all 16 elements and takes the form `matrix3d(m11, m12, m13, m14, m21, m22, m23, m24, m31, m32, m33, m34, m41, m42, m43, m44)`. See the CSS `matrix3d()` function for details on the 3D notation's syntax. ## Syntax toString() ### Parameters None. ### Return value A string; the values of the list separated by commas, within `matrix()` or `matrix3d()` function syntax. ## Examples const matrix = new DOMMatrixReadOnly(); console.log(matrix.translate(20, 30).toString()); // matrix(1, 0, 0, 1, 20, 30) console.log(matrix.translate(30, 40, 50).toString()); // matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 30, 40, 50, 1) console.log(matrix.skewY(15).skewX(5).rotate(3).translate(20, 50).toString()); // matrix(1.003, 0.321, 0.035, 1.01, 21.816, 56.824) console.log( matrix.skewY(15).skewX(5).rotate(3).translate(20, 50, 60).toString(), ); // matrix3d(1.003, 0.321, 0, 0, 0.0350, 1.008, 0, 0, 0, 0, 1, 0, 21.816, 56.824, 60, 1) ## Specifications **No specification found** No specification data found for `api.DOMMatrixReadOnly.toString`. Check for problems with this page or contribute a missing `spec_url` to mdn/browser-compat-data. Also make sure the specification is included in w3c/browser-specs. ## Browser compatibility | Desktop | Mobile ---|---|--- | Chrome | Edge | Firefox | Opera | Safari | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet | WebView Android `toString` | 61 | 79 | 33 | 48 | 11 | 61 | 33 | 45 | 11 | 8.0 | 61 ## See also * `DOMMatrixReadOnly.toJSON()` * `DOMMatrix.setMatrixValue()` # DOMMatrixReadOnly: transformPoint() method Baseline Widely available This feature is well established and works across many devices and browser versions. It’s been available across browsers since January 2020. * Learn more * See full compatibility * Report feedback **Note:** This feature is available in Web Workers. The `transformPoint` method of the `DOMMatrixReadOnly` interface creates a new `DOMPoint` object, transforming a specified point by the matrix. Neither the matrix nor the original point are altered. You can also create a new `DOMPoint` by applying a matrix to a point with the `DOMPointReadOnly.matrixTransform()` method. ## Syntax transformPoint() transformPoint(point) ### Parameters `point` A `DOMPoint` or `DOMPointReadOnly` instance, or an object containing up to four of the following properties: `x` The `x`-coordinate of the point in space as a number. The default value is `0`. `y` The `y`-coordinate of the point in space as a number. The default value is `0`. `z` The `z`-coordinate, or depth coordinate, of the point in space as a number. The default value is `0`.; positive values are closer to the user and negative values retreat back into the screen. `w` The `w` perspective value of the point, as a number. The default is `1`. ### Return value A `DOMPoint`. ## Examples ### 2D transform const matrix = new DOMMatrixReadOnly(); const point = new DOMPointReadOnly(10, 20); // DOMPointReadOnly {x: 10, y: 20, z: 0, w: 1} let newPoint = matrix.transformPoint(point); // DOMPoint {x: 10, y: 20, z: 0, w: 1} ### 3D transform In this example, we apply a 3D point to a 3D matrix: // Matrix with translate(22, 37, 10) applied const matrix3D = new DOMMatrixReadOnly([ 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 22, 37, 10, 1, ]); const point3D = new DOMPointReadOnly(5, 10, 3); // DOMPointReadOnly {x: 5, y: 10, z: 3, w: 1} const transformedPoint3D = point3D.matrixTransform(matrix3D); // DOMPoint {x: 27, y: 47, z: 13, w: 1} ## Specifications ## Browser compatibility | Desktop | Mobile ---|---|--- | Chrome | Edge | Firefox | Opera | Safari | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet | WebView Android `transformPoint` | 61 | 79 | 33 | 48 | 11 | 61 | 33 | 45 | 11 | 8.0 | 61 ## See also * `DOMPointReadOnly.matrixTransform()` * CSS `matrix()` and `matrix3d()` functions # DOMMatrixReadOnly: translate() method Baseline Widely available This feature is well established and works across many devices and browser versions. It’s been available across browsers since January 2020. * Learn more * See full compatibility * Report feedback **Note:** This feature is available in Web Workers. The `translate()` method of the `DOMMatrixReadOnly` interface creates a new matrix being the result of the original matrix with a translation applied. ## Syntax translate(translateX, translateY) translate(translateX, translateY, translateZ) ### Parameters `translateX` A number representing the abscissa (x-coordinate) of the translating vector. `translateY` A number representing the ordinate (y-coordinate) of the translating vector. `translateZ` Optional A number representing the z component of the translating vector. If not supplied, this defaults to 0. If this is anything other than 0, the resulting matrix will be 3D. ### Return value Returns a `DOMMatrix` containing a new matrix being the result of the matrix being translated by the given vector. The original matrix is not modified. If a translation is applied about the z-axis, the resulting matrix will be a 4x4 3D matrix. ## Examples This SVG contains two squares, one red and one blue, each positioned at the document origin: The following JavaScript first creates an identity matrix, then uses the `translate()` method to create a new, translated matrix — which is then applied to the blue square as a `transform`. The red square is left in place. const matrix = new DOMMatrixReadOnly().translate(25, 25); document .querySelector("#transformed") .setAttribute("transform", matrix.toString()); ## Specifications ## Browser compatibility | Desktop | Mobile ---|---|--- | Chrome | Edge | Firefox | Opera | Safari | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet | WebView Android `translate` | 61 | 79 | 33 | 48 | 11 | 61 | 33 | 45 | 11 | 8.0 | 61 # DOMParser Baseline Widely available This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015. * Learn more * See full compatibility * Report feedback The `DOMParser` interface provides the ability to parse XML or HTML source code from a string into a DOM `Document`. You can perform the opposite operation—converting a DOM tree into XML or HTML source—using the `XMLSerializer` interface. In the case of an HTML document, you can also replace portions of the DOM with new DOM trees built from HTML by setting the value of the `Element.innerHTML` and `outerHTML` properties. These properties can also be read to fetch HTML fragments corresponding to the corresponding DOM subtree. Note that `XMLHttpRequest` can parse XML and HTML directly from a URL- addressable resource, returning a `Document` in its `response` property. **Note:** Be aware that block-level elements like `

    ` will be automatically closed if another block-level element is nested inside and therefore parsed before the closing `

    ` tag. ## Constructor `DOMParser()` Creates a new `DOMParser` object. ## Instance methods `DOMParser.parseFromString()` Parses a string using either the HTML parser or the XML parser, returning an `HTMLDocument` or `XMLDocument`. ## Examples The documentation for `DOMParser.parseFromString()`, this interface's only method, contains examples for parsing XML, SVG, and HTML strings. ## Specifications ## Browser compatibility | Desktop | Mobile ---|---|--- | Chrome | Edge | Firefox | Opera | Safari | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet | WebView Android `DOMParser` | 1 | 12 | 1 | 8 | 1.3 | 18 | 4 | 10.1 | 1 | 1.0 | 4.4 `DOMParser` | 1 | 12 | 1 | 8 | 1.3 | 18 | 4 | 10.1 | 1 | 1.0 | 4.4 `parseFromString` | 1 | 12 | 1 | 8 | 1.3 | 18 | 4 | 10.1 | 1 | 1.0 | 4.4 ## See also * Parsing and serializing XML * `XMLHttpRequest` * `XMLSerializer` * `JSON.parse()` \- counterpart for `JSON` documents. # DOMParser: DOMParser() constructor Baseline Widely available This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015. * Learn more * See full compatibility * Report feedback The `DOMParser()` constructor creates a new `DOMParser` object. This object can be used to parse the text of a document using the `parseFromString()` method. ## Syntax new DOMParser() ### Parameters None. ### Return value A new `DOMParser` object. This object can be used to parse the text of a document using the `parseFromString()` method. ## Specifications ## Browser compatibility | Desktop | Mobile ---|---|--- | Chrome | Edge | Firefox | Opera | Safari | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet | WebView Android `DOMParser` | 1 | 12 | 1 | 8 | 1.3 | 18 | 4 | 10.1 | 1 | 1.0 | 4.4 # DOMParser: parseFromString() method Baseline Widely available This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015. * Learn more * See full compatibility * Report feedback The `parseFromString()` method of the `DOMParser` interface parses a string containing either HTML or XML, returning an `HTMLDocument` or an `XMLDocument`. **Note:** The `Document.parseHTMLUnsafe()` static method provides an ergonomic alternative for parsing HTML strings into a `Document`. ## Syntax parseFromString(string, mimeType) ### Parameters `string` The string to be parsed. It must contain either an HTML, xml, XHTML, or svg document. `mimeType` A string. This string determines whether the XML parser or the HTML parser is used to parse the string. Valid values are: * `text/html` * `text/xml` * `application/xml` * `application/xhtml+xml` * `image/svg+xml` A value of `text/html` will invoke the HTML parser, and the method will return an `HTMLDocument`. Any `

    Sample Paragraph

    
          
        
        
    
    ## Specifications
    
    ## Browser compatibility
    
    | Desktop | Mobile  
    ---|---|---  
    | Chrome | Edge | Firefox | Opera | Safari | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet | WebView Android  
    `attributes` | 1 | 12 | 1 | 8 | 1 | 18 | 4 | 10.1 | 1 | 1.0 | 4.4  
      
    ## See also
    
      * `NamedNodeMap`, the interface of the returned object
      * Cross-browser compatibility considerations: on quirksmode 
    
    # Element: auxclick event
    
    Baseline 2024
    
    Newly available
    
    Since December 2024, this feature works across the latest devices and browser
    versions. This feature might not work in older devices or browsers.
    
      * Learn more
      * See full compatibility
      * Report feedback
    
    The `auxclick` event is fired at an `Element` when a non-primary pointing
    device button (any mouse button other than the primary—usually
    leftmost—button) has been pressed and released both within the same element.
    
    `auxclick` is fired after the `mousedown` and `mouseup` events have been
    fired, in that order.
    
    ## Syntax
    
    Use the event name in methods like `addEventListener()`, or set an event
    handler property.
    
        
        
        addEventListener("auxclick", (event) => { })
        
        onauxclick = (event) => { }
        
    
    ## Event type
    
    A `PointerEvent`. Inherits from `MouseEvent`.
    
    Event  UIEvent  MouseEvent  PointerEvent
    
    **Note:** In earlier versions of the specification, the event type for this
    event was a `MouseEvent`. Check browser compatibility for more information.
    
    ## Event properties
    
    _This interface inherits properties from`MouseEvent` and `Event`._
    
    `PointerEvent.altitudeAngle` Read only Experimental
    
        
    
    Represents the angle between a transducer (a pointer or stylus) axis and the
    X-Y plane of a device screen.
    
    `PointerEvent.azimuthAngle` Read only Experimental
    
        
    
    Represents the angle between the Y-Z plane and the plane containing both the
    transducer (a pointer or stylus) axis and the Y axis.
    
    `PointerEvent.pointerId` Read only
    
        
    
    A unique identifier for the pointer causing the event.
    
    `PointerEvent.width` Read only
    
        
    
    The width (magnitude on the X axis), in CSS pixels, of the contact geometry of
    the pointer.
    
    `PointerEvent.height` Read only
    
        
    
    The height (magnitude on the Y axis), in CSS pixels, of the contact geometry
    of the pointer.
    
    `PointerEvent.pressure` Read only
    
        
    
    The normalized pressure of the pointer input in the range `0` to `1`, where
    `0` and `1` represent the minimum and maximum pressure the hardware is capable
    of detecting, respectively.
    
    `PointerEvent.tangentialPressure` Read only
    
        
    
    The normalized tangential pressure of the pointer input (also known as barrel
    pressure or cylinder stress) in the range `-1` to `1`, where `0` is the
    neutral position of the control.
    
    `PointerEvent.tiltX` Read only
    
        
    
    The plane angle (in degrees, in the range of `-90` to `90`) between the Y–Z
    plane and the plane containing both the pointer (e.g., pen stylus) axis and
    the Y axis.
    
    `PointerEvent.tiltY` Read only
    
        
    
    The plane angle (in degrees, in the range of `-90` to `90`) between the X–Z
    plane and the plane containing both the pointer (e.g., pen stylus) axis and
    the X axis.
    
    `PointerEvent.twist` Read only
    
        
    
    The clockwise rotation of the pointer (e.g., pen stylus) around its major axis
    in degrees, with a value in the range `0` to `359`.
    
    `PointerEvent.pointerType` Read only
    
        
    
    Indicates the device type that caused the event (mouse, pen, touch, etc.).
    
    `PointerEvent.isPrimary` Read only
    
        
    
    Indicates if the pointer represents the primary pointer of this pointer type.
    
    ## Preventing default actions
    
    For the vast majority of browsers that map middle click to opening a link in a
    new tab, including Firefox, it is possible to cancel this behavior by calling
    `preventDefault()` from within an `auxclick` event handler.
    
    When listening for `auxclick` events originating on elements that do not
    support input or navigation, you will often want to explicitly prevent other
    default actions mapped to the down action of the middle mouse button. On
    Windows this is usually autoscroll, and on macOS and Linux this is usually
    clipboard paste. This can be done by preventing the default behavior of the
    `mousedown` or `pointerdown` event.
    
    Additionally, you may need to avoid opening a system context menu after a
    right click. Due to timing differences between operating systems, this too is
    not a preventable default behavior of `auxclick`. Instead, this can be done by
    preventing the default behavior of the `contextmenu` event.
    
    ## Examples
    
    In this example we define functions for two event handlers — `onclick` and
    `onauxclick`. The former changes the color of the button background, while the
    latter changes the button foreground (text) color. You also can see the two
    functions in action by trying the demo out with a multi-button mouse (see it
    live on GitHub; also see the source code).
    
    ### JavaScript
    
        
        
        let button = document.querySelector("button");
        let html = document.querySelector("html");
        
        function random(number) {
          return Math.floor(Math.random() * number);
        }
        
        function randomColor() {
          return `rgb(${random(255)} ${random(255)} ${random(255)})`;
        }
        
        button.onclick = () => {
          button.style.backgroundColor = randomColor();
        };
        
        button.onauxclick = (e) => {
          e.preventDefault();
          button.style.color = randomColor();
        };
        
        button.oncontextmenu = (e) => {
          e.preventDefault();
        };
        
    
    Notice that in addition to capturing the `auxclick` event using `onauxclick`,
    the `contextmenu` event is also captured, and `preventDefault()` called on
    that event, in order to prevent the context menu from popping up after the
    color change is applied.
    
    ### HTML
    
        
        
        
        
    
    **Note:** If you are using a three-button mouse, you'll notice that the
    `onauxclick` handler is run when any of the non-left mouse buttons are clicked
    (usually including any "special" buttons on gaming mice).
    
    ## Specifications
    
    ## Browser compatibility
    
    | Desktop | Mobile  
    ---|---|---  
    | Chrome | Edge | Firefox | Opera | Safari | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet | WebView Android  
    `auxclick_event` | 55 | 79 | 53Starting in Firefox 68, the `auxclick` event is used to trigger the _new tab on middle-click_ action; previously, this had been done with the `click` event. Apps can prevent middle-click from opening new tabs (or middle-click to paste, if that feature is enabled) by intercepting `auxclick` on links, and `auxclick` event handlers can now open popups without triggering the popup blocker. | 42 | 18.2 | 55 | 53 | 42 | 18.2 | 6.0 | 55  
    `type_pointerevent` | 92 | 92 | 129 | 78 | 18.2 | 92 | 129 | 65 | 18.2 | 16.0 | 92  
      
    ## See also
    
      * Learn: Introduction to events
      * `click`
      * `contextmenu`
      * `dblclick`
      * `mousedown`
      * `mouseup`
      * `pointerdown`
      * `pointerup`
    
    # Element: before() method
    
    Baseline Widely available
    
    This feature is well established and works across many devices and browser
    versions. It’s been available across browsers since April 2018.
    
      * Learn more
      * See full compatibility
      * Report feedback
    
    The `Element.before()` method inserts a set of `Node` objects or strings in
    the children list of this `Element`'s parent, just before this `Element`.
    Strings are inserted as equivalent `Text` nodes.
    
    ## Syntax
    
        
        
        before(param1)
        before(param1, param2)
        before(param1, param2, /* …, */ paramN)
        
    
    ### Parameters
    
    `param1`, …, `paramN`
    
        
    
    A set of `Node` objects or strings to insert.
    
    ### Return value
    
    None (`undefined`).
    
    ### Exceptions
    
    `HierarchyRequestError` `DOMException`
    
        
    
    Thrown when the node cannot be inserted at the specified point in the
    hierarchy.
    
    ## Examples
    
    ### Inserting an element
    
        
        
        let container = document.createElement("div");
        let p = document.createElement("p");
        container.appendChild(p);
        let span = document.createElement("span");
        
        p.before(span);
        
        console.log(container.outerHTML);
        // "

    " ### Inserting text let container = document.createElement("div"); let p = document.createElement("p"); container.appendChild(p); p.before("Text"); console.log(container.outerHTML); // "
    Text

    " ### Inserting an element and text let container = document.createElement("div"); let p = document.createElement("p"); container.appendChild(p); let span = document.createElement("span"); p.before(span, "Text"); console.log(container.outerHTML); // "
    Text

    " ## Specifications ## Browser compatibility | Desktop | Mobile ---|---|--- | Chrome | Edge | Firefox | Opera | Safari | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet | WebView Android `before` | 54 | 17 | 49 | 39 | 10 | 54 | 49 | 41 | 10 | 6.0 | 54 ## See also * `Element.after()` * `Element.append()` * `Element.insertAdjacentElement()` * `CharacterData.before()` * `DocumentType.before()` * `Node.appendChild()` * `Node.insertBefore()` * `NodeList` # Element: beforeinput event Baseline Widely available This feature is well established and works across many devices and browser versions. It’s been available across browsers since March 2021. * Learn more * See full compatibility * Report feedback The DOM `beforeinput` event fires when the value of an `` or ` #### JavaScript const inputElement = document.querySelector('input[type="text"]'); const log = document.querySelector(".event-log-contents"); const clearLog = document.querySelector(".clear-log"); clearLog.addEventListener("click", () => { log.textContent = ""; }); function handleEvent(event) { log.textContent += `${event.type}: ${event.data}\n`; } inputElement.addEventListener("compositionstart", handleEvent); inputElement.addEventListener("compositionupdate", handleEvent); inputElement.addEventListener("compositionend", handleEvent); #### Result ## Specifications ## Browser compatibility | Desktop | Mobile ---|---|--- | Chrome | Edge | Firefox | Opera | Safari | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet | WebView Android `compositionend_event` | 15 | 12 | 9 | ≤15 | 5 | 18 | 9 | ≤14 | 5 | 1.0 | 4.4 ## See also * Related events: `compositionstart`, `compositionupdate`. # Element: compositionstart event Baseline Widely available This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015. * Learn more * See full compatibility * Report feedback The `compositionstart` event is fired when a text composition system such as an input method editor starts a new composition session. For example, this event could be fired after a user starts entering a Chinese character using a Pinyin Input method editor. ## Syntax Use the event name in methods like `addEventListener()`, or set an event handler property. addEventListener("compositionstart", (event) => { }) oncompositionstart = (event) => { } ## Event type A `CompositionEvent`. Inherits from `UIEvent` and `Event`. Event UIEvent CompositionEvent ## Event properties _This interface also inherits properties of its parent,`UIEvent`, and its ancestor — `Event`._ `CompositionEvent.data` Read only Returns the characters generated by the input method that raised the event; its varies depending on the type of event that generated the `CompositionEvent` object. `CompositionEvent.locale` Read only Deprecated Returns the locale of current input method (for example, the keyboard layout locale if the composition is associated with IME). ## Examples const inputElement = document.querySelector('input[type="text"]'); inputElement.addEventListener("compositionstart", (event) => { console.log(`generated characters were: ${event.data}`); }); ### Live example #### HTML
    #### JavaScript const inputElement = document.querySelector('input[type="text"]'); const log = document.querySelector(".event-log-contents"); const clearLog = document.querySelector(".clear-log"); clearLog.addEventListener("click", () => { log.textContent = ""; }); function handleEvent(event) { log.textContent += `${event.type}: ${event.data}\n`; } inputElement.addEventListener("compositionstart", handleEvent); inputElement.addEventListener("compositionupdate", handleEvent); inputElement.addEventListener("compositionend", handleEvent); #### Result ## Specifications ## Browser compatibility | Desktop | Mobile ---|---|--- | Chrome | Edge | Firefox | Opera | Safari | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet | WebView Android `compositionstart_event` | 15 | 12 | 9 | ≤15 | 5 | 18 | 9 | ≤14 | 5 | 1.0 | 4.4 ## See also * Related events: `compositionend`, `compositionupdate`. # Element: compositionupdate event Baseline Widely available This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015. * Learn more * See full compatibility * Report feedback The `compositionupdate` event is fired when a new character is received in the context of a text composition session controlled by a text composition system such as an input method editor. For example, this event could be fired while a user enters a Chinese character using a Pinyin Input method editor. ## Syntax Use the event name in methods like `addEventListener()`, or set an event handler property. addEventListener("compositionupdate", (event) => { }) oncompositionupdate = (event) => { } ## Event type A `CompositionEvent`. Inherits from `UIEvent` and `Event`. Event UIEvent CompositionEvent ## Event properties _This interface also inherits properties of its parent,`UIEvent`, and its ancestor — `Event`._ `CompositionEvent.data` Read only Returns the characters generated by the input method that raised the event; its varies depending on the type of event that generated the `CompositionEvent` object. `CompositionEvent.locale` Read only Deprecated Returns the locale of current input method (for example, the keyboard layout locale if the composition is associated with IME). ## Examples const inputElement = document.querySelector('input[type="text"]'); inputElement.addEventListener("compositionupdate", (event) => { console.log(`generated characters were: ${event.data}`); }); ### Live example #### HTML
    #### JavaScript const inputElement = document.querySelector('input[type="text"]'); const log = document.querySelector(".event-log-contents"); const clearLog = document.querySelector(".clear-log"); clearLog.addEventListener("click", () => { log.textContent = ""; }); function handleEvent(event) { log.textContent += `${event.type}: ${event.data}\n`; } inputElement.addEventListener("compositionstart", handleEvent); inputElement.addEventListener("compositionupdate", handleEvent); inputElement.addEventListener("compositionend", handleEvent); #### Result ## Specifications ## Browser compatibility | Desktop | Mobile ---|---|--- | Chrome | Edge | Firefox | Opera | Safari | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet | WebView Android `compositionupdate_event` | 18 | 12 | 9 | 15 | 5 | 18 | 9 | 14 | 5 | 1.0 | 4.4 ## See also * Related events: `compositionstart`, `compositionend`. # Element: computedStyleMap() method Limited availability This feature is not Baseline because it does not work in some of the most widely-used browsers. * Learn more * See full compatibility * Report feedback The `computedStyleMap()` method of the `Element` interface returns a `StylePropertyMapReadOnly` interface which provides a read-only representation of a CSS declaration block that is an alternative to `CSSStyleDeclaration`. ## Syntax computedStyleMap() ### Parameters None. ### Return value A `StylePropertyMapReadOnly` object. Unlike `Window.getComputedStyle`, the return value contains computed values, not resolved values. For most properties, they are the same, except a few layout-related properties, where the resolved value is the used value instead of the computed value. See the comparison with `getComputedStyle()` example for details. ## Examples ### Getting default styles We start with some simple HTML: a paragraph with a link, and a definition list to which we will add all the CSS Property / Value pairs.

    Link

    We add a little bit of CSS a { --color: red; color: var(--color); } We add JavaScript to grab our link and return back a definition list of all the CSS property values using `computedStyleMap()`. // get the element const myElement = document.querySelector("a"); // get the
    we'll be populating const stylesList = document.querySelector("#regurgitation"); // Retrieve all computed styles with computedStyleMap() const allComputedStyles = myElement.computedStyleMap(); // iterate through the map of all the properties and values, adding a
    and
    for each for (const [prop, val] of allComputedStyles) { // properties const cssProperty = document.createElement("dt"); cssProperty.appendChild(document.createTextNode(prop)); stylesList.appendChild(cssProperty); // values const cssValue = document.createElement("dd"); cssValue.appendChild(document.createTextNode(val)); stylesList.appendChild(cssValue); } In browsers that support `computedStyleMap()`, you'll see a list of all the CSS properties and values. In other browsers you'll just see a link. Did you realize how many default CSS properties a link had? Update the `document.querySelector("a")` to `document.querySelector("p")`, and you'll notice a difference in the `margin-top` and `margin-bottom` default computed values. ### Comparison with getComputedStyle() `Window.getComputedStyle()` returns resolved values, while `computedStyleMap()` returns computed values. These are usually the same, but for some properties, the resolved value is the used value instead of the computed value. For example, percentage values for widths are resolved to pixel values _post-layout_ , so the used values are in pixels, while the computed values are still in percentages. Note that the way we present it makes the two APIs seem more similar than they are. `computedStyleMap()` contains CSS Typed OM objects, while `getComputedStyle()` contains strings. The former presents the same information in a more structured and processable way. In this example, the `width` property is specified as a percentage, so the computed value is given as a percentage, but the resolved value is given in pixels. The `height` is always in pixels. The `background-color` is a named color, but it is computed to an RGB value.
    
        
        
        
        .container {
          width: 200px;
          height: 200px;
        }
        
        .item {
          width: 50%;
          height: 100px;
          background-color: tomato;
        }
        
        
        
        const item = document.querySelector(".item");
        const result = document.querySelector("#result");
        const resolvedValues = getComputedStyle(item);
        const computedValues = item.computedStyleMap();
        
        result.textContent = `resolvedValues.width = ${resolvedValues.width}
        computedValues.get("width") = ${computedValues.get("width")}
        
        resolvedValues.height = ${resolvedValues.height}
        computedValues.get("height") = ${computedValues.get("height")}
        
        resolvedValues.backgroundColor = ${resolvedValues.backgroundColor}
        computedValues.get("background-color") = ${computedValues.get(
          "background-color",
        )}`;
        
    
    ## Specifications
    
    ## Browser compatibility
    
    | Desktop | Mobile  
    ---|---|---  
    | Chrome | Edge | Firefox | Opera | Safari | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet | WebView Android  
    `computedStyleMap` | 66 | 79 | No | 53 | 16.4 | 66 | No | 47 | 16.4 | 9.0 | 66  
      
    ## See also
    
      * `Window.getComputedStyle()`
    
    # Element: contentvisibilityautostatechange event
    
    Baseline 2024
    
    Newly available
    
    Since September 2024, this feature works across the latest devices and browser
    versions. This feature might not work in older devices or browsers.
    
      * Learn more
      * See full compatibility
      * Report feedback
    
    The `contentvisibilityautostatechange` event fires on any element with
    `content-visibility: auto` set on it when it starts or stops being relevant to
    the user and skipping its contents.
    
    While the element is not relevant (between the start and end events), the user
    agent skips an element's rendering, including layout and painting, which can
    significantly improve page rendering speed. The
    `contentvisibilityautostatechange` event provides a way for an app's code to
    also start or stop rendering processes (e.g., drawing on a ``) when
    they are not needed, thereby conserving processing power.
    
    Note that even when hidden from view, element contents will remain
    semantically relevant (e.g., to assistive technology users), so this signal
    should not be used to skip significant semantic DOM updates.
    
    ## Syntax
    
    Use the event name in methods like `addEventListener()`, or set an event
    handler property.
    
        
        
        addEventListener("contentvisibilityautostatechange", (event) => { })
        
        oncontentvisibilityautostatechange = (event) => { }
        
    
    ## Event type
    
    A `ContentVisibilityAutoStateChangeEvent`.
    
    ## Examples
    
        
        
        const canvasElem = document.querySelector("canvas");
        
        canvasElem.addEventListener("contentvisibilityautostatechange", stateChanged);
        canvasElem.style.contentVisibility = "auto";
        
        function stateChanged(event) {
          if (event.skipped) {
            stopCanvasUpdates(canvasElem);
          } else {
            startCanvasUpdates(canvasElem);
          }
        }
        
        // Call this when the canvas updates need to start.
        function startCanvasUpdates(canvas) {
          // …
        }
        
        // Call this when the canvas updates need to stop.
        function stopCanvasUpdates(canvas) {
          // …
        }
        
    
    ## Specifications
    
    ## Browser compatibility
    
    | Desktop | Mobile  
    ---|---|---  
    | Chrome | Edge | Firefox | Opera | Safari | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet | WebView Android  
    `contentvisibilityautostatechange_event` | 108 | 108 | 130124–130The `oncontentvisibilityautostatechange` event handler property is not supported. | 94 | 18 | 108 | 130124–130The `oncontentvisibilityautostatechange` event handler property is not supported. | 73 | 18 | 21.0 | 108  
      
    ## See also
    
      * `ContentVisibilityAutoStateChangeEvent`
      * CSS Containment
      * The `content-visibility` property
      * The `contain` property
    
    # Element: contextmenu event
    
    Limited availability
    
    This feature is not Baseline because it does not work in some of the most
    widely-used browsers.
    
      * Learn more
      * See full compatibility
      * Report feedback
    
    The `contextmenu` event fires when the user attempts to open a context menu.
    This event is typically triggered by clicking the right mouse button, or by
    pressing the context menu key.
    
    In the latter case, the context menu is displayed at the bottom left of the
    focused element, unless the element is a tree, in which case the context menu
    is displayed at the bottom left of the current row.
    
    Any right-click event that is not disabled (by calling the click event's
    `preventDefault()` method) will result in a `contextmenu` event being fired at
    the targeted element.
    
    **Note:** An exception to this in Firefox: if the user holds down the `Shift`
    key while right-clicking, then the context menu will be shown without a
    `contextmenu` event being fired.
    
    ## Syntax
    
    Use the event name in methods like `addEventListener()`, or set an event
    handler property.
    
        
        
        addEventListener("contextmenu", (event) => { })
        
        oncontextmenu = (event) => { }
        
    
    ## Event type
    
    A `PointerEvent`. Inherits from `MouseEvent`.
    
    Event  UIEvent  MouseEvent  PointerEvent
    
    **Note:** In earlier versions of the specification, the event type for this
    event was a `MouseEvent`. Check browser compatibility for more information.
    
    ## Event properties
    
    _This interface inherits properties from`MouseEvent` and `Event`._
    
    `PointerEvent.altitudeAngle` Read only Experimental
    
        
    
    Represents the angle between a transducer (a pointer or stylus) axis and the
    X-Y plane of a device screen.
    
    `PointerEvent.azimuthAngle` Read only Experimental
    
        
    
    Represents the angle between the Y-Z plane and the plane containing both the
    transducer (a pointer or stylus) axis and the Y axis.
    
    `PointerEvent.pointerId` Read only
    
        
    
    A unique identifier for the pointer causing the event.
    
    `PointerEvent.width` Read only
    
        
    
    The width (magnitude on the X axis), in CSS pixels, of the contact geometry of
    the pointer.
    
    `PointerEvent.height` Read only
    
        
    
    The height (magnitude on the Y axis), in CSS pixels, of the contact geometry
    of the pointer.
    
    `PointerEvent.pressure` Read only
    
        
    
    The normalized pressure of the pointer input in the range `0` to `1`, where
    `0` and `1` represent the minimum and maximum pressure the hardware is capable
    of detecting, respectively.
    
    `PointerEvent.tangentialPressure` Read only
    
        
    
    The normalized tangential pressure of the pointer input (also known as barrel
    pressure or cylinder stress) in the range `-1` to `1`, where `0` is the
    neutral position of the control.
    
    `PointerEvent.tiltX` Read only
    
        
    
    The plane angle (in degrees, in the range of `-90` to `90`) between the Y–Z
    plane and the plane containing both the pointer (e.g., pen stylus) axis and
    the Y axis.
    
    `PointerEvent.tiltY` Read only
    
        
    
    The plane angle (in degrees, in the range of `-90` to `90`) between the X–Z
    plane and the plane containing both the pointer (e.g., pen stylus) axis and
    the X axis.
    
    `PointerEvent.twist` Read only
    
        
    
    The clockwise rotation of the pointer (e.g., pen stylus) around its major axis
    in degrees, with a value in the range `0` to `359`.
    
    `PointerEvent.pointerType` Read only
    
        
    
    Indicates the device type that caused the event (mouse, pen, touch, etc.).
    
    `PointerEvent.isPrimary` Read only
    
        
    
    Indicates if the pointer represents the primary pointer of this pointer type.
    
    ## Examples
    
    ### Canceling the `contextmenu` event
    
    In this example, the default action of the `contextmenu` event is canceled
    using `preventDefault()` when the `contextmenu` event is fired at the first
    paragraph. As a result, the first paragraph will do nothing when right-
    clicked, while the second paragraph will show the standard context menu
    offered by your browser.
    
    **Note:** In Firefox, if you hold down the `Shift` key while right-clicking,
    then the context menu is shown without the `contextmenu` event being fired.
    Therefore, canceling the event does not stop the context menu from being
    shown.
    
    #### HTML
    
        
        
        

    The context menu has been disabled on this paragraph.

    But it has not been disabled on this one.

    #### JavaScript const noContext = document.getElementById("noContextMenu"); noContext.addEventListener("contextmenu", (e) => { e.preventDefault(); }); #### Result ## Specifications ## Browser compatibility | Desktop | Mobile ---|---|--- | Chrome | Edge | Firefox | Opera | Safari | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet | WebView Android `contextmenu_event` | 1 | 12 | 6 | 10.5 | 3 | 18 | 6 | 11.1 | No | 1.0 | 4.4 `type_pointerevent` | 92 | 92 | 129 | 78 | 18.2 | 92 | 129 | 65 | No | 16.0 | 92 ## See also * Learn: Introduction to events * `auxclick` * `click` * `dblclick` * `mousedown` * `mouseup` * `pointerdown` * `pointerup` # Element: copy event Baseline Widely available This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015. * Learn more * See full compatibility * Report feedback The `copy` event of the Clipboard API fires when the user initiates a copy action through the browser's user interface. The event's default action is to copy the selection (if any) to the clipboard. A handler for this event can _modify_ the clipboard contents by calling `setData(format, data)` on the event's `ClipboardEvent.clipboardData` property, and cancelling the event's default action using `event.preventDefault()`. However, the handler cannot _read_ the clipboard data. It's possible to construct and dispatch a synthetic `copy` event, but this will not affect the system clipboard. This event bubbles up the DOM tree, eventually to `Document` and `Window`, is cancelable and is composed. ## Syntax Use the event name in methods like `addEventListener()`, or set an event handler property. addEventListener("copy", (event) => { }) oncopy = (event) => { } ## Event type A `ClipboardEvent`. Inherits from `Event`. Event ClipboardEvent ## Examples ### Live example #### HTML
    Copy text from this box.
    And paste it into this one.
    #### JavaScript const source = document.querySelector("div.source"); source.addEventListener("copy", (event) => { const selection = document.getSelection(); event.clipboardData.setData("text/plain", selection.toString().toUpperCase()); event.preventDefault(); }); #### Result ## Specifications ## Browser compatibility | Desktop | Mobile ---|---|--- | Chrome | Edge | Firefox | Opera | Safari | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet | WebView Android `copy_event` | 1 | 12 | 22 | ≤12.1 | 3 | 18 | 22 | ≤12.1 | 3 | 1.0 | 4.4 ## See also * `cut` event * `paste` event # Element: currentCSSZoom property Limited availability This feature is not Baseline because it does not work in some of the most widely-used browsers. * Learn more * See full compatibility * Report feedback The `currentCSSZoom` read-only property of the `Element` interface provides the "effective" CSS `zoom` of an element, taking into account the zoom applied to the element and all its parent elements. The value calculated by multiplying the CSS `zoom` values of the element and all of its parents. For example, if three elements with zoom values of 2, 1.5, and 3, are nested within each other, the most deeply nested element will have a `currentCSSZoom` value of 9. If the element doesn't have a CSS box, for example because `display: none` is set on the element or one of its parents, then the `currentCSSZoom` is set to 1. Note that some methods, such as `Element.getBoundingClientRect()`, return dimensions and position that are relative to the viewport, and hence include the effects of CSS `zoom`. Other properties and methods return values that are relative to the element itself, and do not include the effects of zooming. These include, for example, `client*` properties such as `Element.clientHeight`, `scroll*()` methods like `Element.scroll()`, and `offset*` properties such as `HTMLElement.offsetHeight`. The `currentCSSZoom` property can be used to scale these values to adjust for the effects of zooming. ## Value A number indicating the effective CSS zoom on the element, or 1 if the element is not rendered. ## Examples This example demonstrates how the `currentCSSZoom` is calculated. First we define a nested structure of `
    ` elements where the "parent" is unzoomed and contains a nested element "child1" that has `zoom: 2` applied, which in turn contains a nested element "child2" with `zoom: 3` applied. The "child2" element contains two nested elements, one of which is not rendered, and neither of which have the zoom property applied.
    parent
    child1 (zoom: 2)
    child2 (zoom: 3)
    child3_rendered
    The JavaScript code logs the zoom value applied at each level along with its `currentCSSZoom` value. if ("currentCSSZoom" in Element.prototype) { const parent = document.querySelector("#parent"); log(`parent (unzoomed). currentCSSZoom: ${parent.currentCSSZoom}`); const child1 = document.querySelector("#child1"); log(`child1 (zoom: 2). currentCSSZoom: ${child1.currentCSSZoom}`); const child2 = document.querySelector("#child2"); log(`child2 (zoom: 2). currentCSSZoom: ${child2.currentCSSZoom}`); const top_child3_rendered = document.querySelector("#child3_rendered"); log( `child3_rendered (unzoomed). currentCSSZoom: ${child3_rendered.currentCSSZoom}`, ); const top_child3_notRendered = document.querySelector("#child3_not-rendered"); log( `child3_notRendered (not rendered): ${child3_notRendered.currentCSSZoom}`, ); } else { log("Element.currentCSSZoom not supported in this browser"); } The resulting rendered `
    ` structure and log are shown below. First note that the parent, child1 and child2 have zoom levels 1, 2, and 3, respectively, and render at 1, 2 and 6 times the size of the parent text. This is reflected by the logged `currentCSSZoom` values. The `
    ` with id `child3_rendered` does not have `zoom` set but inherits the `currentCSSZoom` value of 6 as shown in the log. The final `
    ` is not rendered and therefore has a `currentCSSZoom` value of 1. ## Specifications ## Browser compatibility | Desktop | Mobile ---|---|--- | Chrome | Edge | Firefox | Opera | Safari | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet | WebView Android `currentCSSZoom` | 128 | 128 | 126 | 114 | No | 128 | 126 | 85 | No | No | 128 ## See also * CSS `zoom` # Element: cut event Baseline Widely available This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015. * Learn more * See full compatibility * Report feedback The `cut` event of the Clipboard API is fired when the user has initiated a "cut" action through the browser's user interface. If the user attempts a cut action on uneditable content, the `cut` event still fires but the event object contains no data. The event's default action is to copy the current selection (if any) to the system clipboard and remove it from the document. A handler for this event can _modify_ the clipboard contents by calling `setData(format, data)` on the event's `ClipboardEvent.clipboardData` property, and cancelling the default action using `event.preventDefault()`. Note though that cancelling the default action will also prevent the document from being updated. So an event handler which wants to emulate the default action for "cut" while modifying the clipboard must also manually remove the selection from the document. The handler cannot _read_ the clipboard data. It's possible to construct and dispatch a synthetic `cut` event, but this will not affect the system clipboard or the document's contents. This event bubbles up the DOM tree, eventually to `Document` and `Window`, is cancelable and is composed. ## Syntax Use the event name in methods like `addEventListener()`, or set an event handler property. addEventListener("cut", (event) => { }) oncut = (event) => { } ## Event type A `ClipboardEvent`. Inherits from `Event`. Event ClipboardEvent ## Examples ### Live example #### HTML
    Cut text from this box.
    And paste it into this one.
    #### JavaScript const source = document.querySelector("div.source"); source.addEventListener("cut", (event) => { const selection = document.getSelection(); event.clipboardData.setData("text/plain", selection.toString().toUpperCase()); selection.deleteFromDocument(); event.preventDefault(); }); #### Result ## Specifications ## Browser compatibility | Desktop | Mobile ---|---|--- | Chrome | Edge | Firefox | Opera | Safari | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet | WebView Android `cut_event` | 1 | 12 | 22 | ≤12.1 | 3 | 18 | 22 | ≤12.1 | 3 | 1.0 | 4.4 ## See also * `copy` event * `paste` event # Element: dblclick event Baseline Widely available This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015. * Learn more * See full compatibility * Report feedback The `dblclick` event fires when a pointing device button (such as a mouse's primary button) is double-clicked; that is, when it's rapidly clicked twice on a single element within a very short span of time. `dblclick` fires after two `click` events (and by extension, after two pairs of `mousedown` and `mouseup` events). ## Syntax Use the event name in methods like `addEventListener()`, or set an event handler property. addEventListener("dblclick", (event) => { }) ondblclick = (event) => { } ## Event type A `MouseEvent`. Inherits from `UIEvent` and `Event`. Event UIEvent MouseEvent ## Event properties _This interface also inherits properties of its parents,`UIEvent` and `Event`._ `MouseEvent.altKey` Read only Returns `true` if the `alt` key was down when the mouse event was fired. `MouseEvent.button` Read only The button number that was pressed (if applicable) when the mouse event was fired. `MouseEvent.buttons` Read only The buttons being pressed (if any) when the mouse event was fired. `MouseEvent.clientX` Read only The X coordinate of the mouse pointer in viewport coordinates. `MouseEvent.clientY` Read only The Y coordinate of the mouse pointer in viewport coordinates. `MouseEvent.ctrlKey` Read only Returns `true` if the `control` key was down when the mouse event was fired. `MouseEvent.layerX` Non-standard Read only Returns the horizontal coordinate of the event relative to the current layer. `MouseEvent.layerY` Non-standard Read only Returns the vertical coordinate of the event relative to the current layer. `MouseEvent.metaKey` Read only Returns `true` if the `meta` key was down when the mouse event was fired. `MouseEvent.movementX` Read only The X coordinate of the mouse pointer relative to the position of the last `mousemove` event. `MouseEvent.movementY` Read only The Y coordinate of the mouse pointer relative to the position of the last `mousemove` event. `MouseEvent.offsetX` Read only The X coordinate of the mouse pointer relative to the position of the padding edge of the target node. `MouseEvent.offsetY` Read only The Y coordinate of the mouse pointer relative to the position of the padding edge of the target node. `MouseEvent.pageX` Read only The X coordinate of the mouse pointer relative to the whole document. `MouseEvent.pageY` Read only The Y coordinate of the mouse pointer relative to the whole document. `MouseEvent.relatedTarget` Read only The secondary target for the event, if there is one. `MouseEvent.screenX` Read only The X coordinate of the mouse pointer in screen coordinates. `MouseEvent.screenY` Read only The Y coordinate of the mouse pointer in screen coordinates. `MouseEvent.shiftKey` Read only Returns `true` if the `shift` key was down when the mouse event was fired. `MouseEvent.mozInputSource` Non-standard Read only The type of device that generated the event (one of the `MOZ_SOURCE_*` constants). This lets you, for example, determine whether a mouse event was generated by an actual mouse or by a touch event (which might affect the degree of accuracy with which you interpret the coordinates associated with the event). `MouseEvent.webkitForce` Non-standard Read only The amount of pressure applied when clicking. `MouseEvent.x` Read only Alias for `MouseEvent.clientX`. `MouseEvent.y` Read only Alias for `MouseEvent.clientY`. ## Examples This example toggles the size of a card when you double click on it. ### JavaScript const card = document.querySelector("aside"); card.addEventListener("dblclick", (e) => { card.classList.toggle("large"); }); ### HTML ### CSS aside { background: #fe9; border-radius: 1em; display: inline-block; padding: 1em; transform: scale(0.9); transform-origin: 0 0; transition: transform 0.6s; user-select: none; } .large { transform: scale(1.3); } ### Result ## Specifications ## Browser compatibility | Desktop | Mobile ---|---|--- | Chrome | Edge | Firefox | Opera | Safari | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet | WebView Android `dblclick_event` | 1 | 12 | 6Starting in Firefox 68, `dblclick` events are only sent for the primary mouse button, per the specification. | 11.6 | 3 | 18 | 6 | 12.1 | 1 | 1.0 | 4.4 ## See also * Learn: Introduction to events * `auxclick` * `click` * `contextmenu` * `mousedown` * `mouseup` * `pointerdown` * `pointerup` # Element: DOMActivate event **Deprecated:** This feature is no longer recommended. Though some browsers might still support it, it may have already been removed from the relevant web standards, may be in the process of being dropped, or may only be kept for compatibility purposes. Avoid using it, and update existing code if possible; see the compatibility table at the bottom of this page to guide your decision. Be aware that this feature may cease to work at any time. The `DOMActivate` event is fired at an element when it becomes active, such as when it is clicked on using the mouse or a keypress is used to navigate to it. ## Syntax Use the event name in methods like `addEventListener()`, or set an event handler property. addEventListener("DOMActivate", (event) => { }) onDOMActivate = (event) => { } ## Event type A `MouseEvent`. Inherits from `UIEvent` and `Event`. Event UIEvent MouseEvent ## Event properties [...] ## Examples Example: invoke an JavaScript function from a DOMActivate event change(evt); Activate the circle to change its size ## Specifications ## Browser compatibility | Desktop | Mobile ---|---|--- | Chrome | Edge | Firefox | Opera | Safari | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet | WebView Android `DOMActivate_event` | 1 | 79 | 1 | 15 | 1 | 18 | 4 | 14 | 1 | 1.0 | 4.4 ## See also * `MouseEvent` * `mousedown` * `mouseup` * `mousemove` # Element: DOMMouseScroll event **Deprecated:** This feature is no longer recommended. Though some browsers might still support it, it may have already been removed from the relevant web standards, may be in the process of being dropped, or may only be kept for compatibility purposes. Avoid using it, and update existing code if possible; see the compatibility table at the bottom of this page to guide your decision. Be aware that this feature may cease to work at any time. **Non-standard:** This feature is not standardized. We do not recommend using non-standard features in production, as they have limited browser support, and may change or be removed. However, they can be a suitable alternative in specific cases where no standard option exists. The DOM `DOMMouseScroll` event is fired asynchronously when mouse wheel or similar device is operated and the accumulated scroll amount is over 1 line or 1 page since last event. It's represented by the `MouseScrollEvent` interface. This event was only implemented by Firefox. You should instead use the standard `wheel` event. If you want to prevent the default action of mouse wheel events, it's not enough to handle only this event on Gecko because If scroll amount by a native mouse wheel event is less than 1 line (or less than 1 page when the system setting is by page scroll), other mouse wheel events may be fired without this event. On Gecko 17 (Firefox 17) or later, you need to call `preventDefault()` of `wheel` events which must be fired for every native event. Use the standardized `wheel` event if available. ## Syntax Use the event name in methods like `addEventListener()`, or set an event handler property. addEventListener("DOMMouseScroll", (event) => { }) onDOMMouseScroll = (event) => { } ## Event type A `WheelEvent`. Inherits from `MouseEvent`, `UIEvent` and `Event`. Event UIEvent MouseEvent WheelEvent ## Event properties The event has only one additional property beyond standard events. ### detail The `detail` property describes the scroll more precisely, with positive values indicating scrolling downward and negative values indicating scrolling upward. If the event represents scrolling up by a page, the value of `detail` is -32768. If the event indicates scrolling down by a page, the value is +32768. Any other value represents the number of lines to scroll, with the direction indicated by the value's sign. **Note:** Trusted events are never sent with a value of 0 for `detail`. Trusted events are never fired with 0. **Note:** If the platform's native mouse wheel events only provide scroll distance by pixels, or if the speed can be customized by the user, the value is computed using the line height of the nearest scrollable ancestor element of the event's target. If that element's font size is smaller than `mousewheel.min_line_scroll_amount`, that preference's value is used as the line height. ## Browser compatibility | Desktop | Mobile ---|---|--- | Chrome | Edge | Firefox | Opera | Safari | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet | WebView Android `DOMMouseScroll_event` | No | No | 1 | No | No | No | 4 | No | No | No | No ## See also * `MouseScrollEvent` * Gecko's legacy pixel scroll event: `MozMousePixelScroll` * Non-Gecko browsers' legacy mouse wheel event: `mousewheel` * Standardized wheel event: `wheel` # Element: elementTiming property Limited availability This feature is not Baseline because it does not work in some of the most widely-used browsers. * Learn more * See full compatibility * Report feedback **Experimental:** **This is an experimental technology** Check the Browser compatibility table carefully before using this in production. The `elementTiming` property of the `Element` interface identifies elements for observation in the `PerformanceElementTiming` API. The `elementTiming` property reflects the value of the `elementtiming` attribute. ## Value A string. ## Examples ### Logging the value of `elementTiming` In this example, adding the `elementtiming` attribute to the `` element sets the image to be observed. a nice image You can get the string value of the `elementtiming` HTML attribute by calling `el.elementTiming`. const el = document.getElementById("myImage"); console.log(el.elementTiming); // "big-image" For a more complete example on how to use the Element Timing API, see `PerformanceElementTiming`. ## Specifications ## Browser compatibility | Desktop | Mobile ---|---|--- | Chrome | Edge | Firefox | Opera | Safari | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet | WebView Android `elementTiming` | 77 | 79 | No | 64 | No | 77 | No | 55 | No | 12.0 | 77 ## See also * `PerformanceElementTiming` * `elementtiming` HTML attribute # Element: firstElementChild property Baseline Widely available This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015. * Learn more * See full compatibility * Report feedback The `Element.firstElementChild` read-only property returns an element's first child `Element`, or `null` if there are no child elements. `Element.firstElementChild` includes only element nodes. To get all child nodes, including non-element nodes like text and comment nodes, use `Node.firstChild`. ## Value An `Element` object, or `null`. ## Examples
    • First (1)
    • Second (2)
    • Third (3)
    ## Specifications ## Browser compatibility | Desktop | Mobile ---|---|--- | Chrome | Edge | Firefox | Opera | Safari | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet | WebView Android `firstElementChild` | 2 | 12 | 3.5 | 10 | 4 | 18 | 4 | 10.1 | 3 | 1.0 | 4.4 ## See also * `Element.nextElementSibling` * `Element.lastElementChild` # Element: focus event Baseline Widely available This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015. * Learn more * See full compatibility * Report feedback The `focus` event fires when an element has received focus. The event does not bubble, but the related `focusin` event that follows does bubble. The opposite of `focus` is the `blur` event, which fires when the element has _lost_ focus. The `focus` event is not cancelable. ## Syntax Use the event name in methods like `addEventListener()`, or set an event handler property. addEventListener("focus", (event) => { }) onfocus = (event) => { } ## Event type A `FocusEvent`. Inherits from `UIEvent` and `Event`. Event UIEvent FocusEvent ## Event properties _This interface also inherits properties from its parent`UIEvent`, and indirectly from `Event`._ `FocusEvent.relatedTarget` The element losing focus, if any. ## Examples ### Simple example #### HTML
    #### JavaScript const password = document.querySelector('input[type="password"]'); password.addEventListener("focus", (event) => { event.target.style.background = "pink"; }); password.addEventListener("blur", (event) => { event.target.style.background = ""; }); #### Result ### Event delegation There are two ways of implementing event delegation for this event: by using the `focusin` event, or by setting the `useCapture` parameter of `addEventListener()` to `true`. #### HTML
    #### JavaScript const form = document.getElementById("form"); form.addEventListener( "focus", (event) => { event.target.style.background = "pink"; }, true, ); form.addEventListener( "blur", (event) => { event.target.style.background = ""; }, true, ); #### Result ## Specifications ## Browser compatibility | Desktop | Mobile ---|---|--- | Chrome | Edge | Firefox | Opera | Safari | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet | WebView Android `focus_event` | 1 | 12 | 246–24The interface for this event is `Event`, not `FocusEvent`. | 11.6 | 3.1 | 18 | 246–24The interface for this event is `Event`, not `FocusEvent`. | 12.1 | 2 | 1.0 | 4.4 ## See also * The `HTMLElement.focus()` method * Related events: `blur`, `focusin`, `focusout` * This event on `Window` targets: `focus` event * Focusing: focus/blur # Element: focusin event Limited availability This feature is not Baseline because it does not work in some of the most widely-used browsers. * Learn more * See full compatibility * Report feedback The `focusin` event fires when an element has received focus, after the `focus` event. The two events differ in that `focusin` bubbles, while `focus` does not. The opposite of `focusin` is the `focusout` event, which fires when the element has lost focus. The `focusin` event is not cancelable. ## Syntax Use the event name in methods like `addEventListener()`. addEventListener("focusin", (event) => { }) **Note:** There is no `onfocusin` event handler property for this event. ## Event type A `FocusEvent`. Inherits from `UIEvent` and `Event`. Event UIEvent FocusEvent ## Event properties _This interface also inherits properties from its parent`UIEvent`, and indirectly from `Event`_. `FocusEvent.relatedTarget` The element losing focus, if any. ## Examples ### Live example #### HTML
    #### JavaScript const form = document.getElementById("form"); form.addEventListener("focusin", (event) => { event.target.style.background = "pink"; }); form.addEventListener("focusout", (event) => { event.target.style.background = ""; }); #### Result ## Specifications **Note:** The _UI Events_ specification describes an order of focus events that's different from what current browsers implement. ## Browser compatibility | Desktop | Mobile ---|---|--- | Chrome | Edge | Firefox | Opera | Safari | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet | WebView Android `focusin_event` | 1The `onfocusin` event handler property is not supported. To listen to this event, use `element.addEventListener('focusin', function() {});`. | 12The `onfocusin` event handler property is not supported. To listen to this event, use `element.addEventListener('focusin', function() {});`. | 52The `onfocusin` event handler property is not supported. To listen to this event, use `element.addEventListener('focusin', function() {});`. | 11.6 | 5 | 18The `onfocusin` event handler property is not supported. To listen to this event, use `element.addEventListener('focusin', function() {});`. | 52The `onfocusin` event handler property is not supported. To listen to this event, use `element.addEventListener('focusin', function() {});`. | 12.1 | 4.2 | 1.0The `onfocusin` event handler property is not supported. To listen to this event, use `element.addEventListener('focusin', function() {});`. | 4.4The `onfocusin` event handler property is not supported. To listen to this event, use `element.addEventListener('focusin', function() {});`. ## See also * Related events: `blur`, `focus`, `focusout` * Focusing: focus/blur # Element: focusout event Limited availability This feature is not Baseline because it does not work in some of the most widely-used browsers. * Learn more * See full compatibility * Report feedback The `focusout` event fires when an element has lost focus, after the `blur` event. The two events differ in that `focusout` bubbles, while `blur` does not. The opposite of `focusout` is the `focusin` event, which fires when the element has received focus. The `focusout` event is not cancelable. ## Syntax Use the event name in methods like `addEventListener()`. addEventListener("focusout", (event) => { }) **Note:** There is no `onfocusout` event handler property for this event. ## Event type A `FocusEvent`. Inherits from `UIEvent` and `Event`. Event UIEvent FocusEvent ## Event properties _This interface also inherits properties from its parent`UIEvent`, and indirectly from `Event`_. `FocusEvent.relatedTarget` The element receiving focus, if any. ## Examples ### Live example #### HTML
    #### JavaScript const form = document.getElementById("form"); form.addEventListener("focusin", (event) => { event.target.style.background = "pink"; }); form.addEventListener("focusout", (event) => { event.target.style.background = ""; }); #### Result ## Specifications **Note:** The _UI Events_ specification describes an order of focus events that's different from what current browsers implement. ## Browser compatibility | Desktop | Mobile ---|---|--- | Chrome | Edge | Firefox | Opera | Safari | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet | WebView Android `focusout_event` | 1The `onfocusout` event handler property is not supported. To listen to this event, use `element.addEventListener('focusout', function() {});`. | 12The `onfocusout` event handler property is not supported. To listen to this event, use `element.addEventListener('focusout', function() {});`. | 52The `onfocusout` event handler property is not supported. To listen to this event, use `element.addEventListener('focusout', function() {});`. | 11.6 | 5 | 18The `onfocusout` event handler property is not supported. To listen to this event, use `element.addEventListener('focusout', function() {});`. | 52The `onfocusout` event handler property is not supported. To listen to this event, use `element.addEventListener('focusout', function() {});`. | 12.1 | 4.2 | 1.0The `onfocusout` event handler property is not supported. To listen to this event, use `element.addEventListener('focusout', function() {});`. | 4.4The `onfocusout` event handler property is not supported. To listen to this event, use `element.addEventListener('focusout', function() {});`. ## See also * Related events: `blur`, `focus`, `focusin` * Focusing: focus/blur # Element: fullscreenchange event Limited availability This feature is not Baseline because it does not work in some of the most widely-used browsers. * Learn more * See full compatibility * Report feedback The `fullscreenchange` event is fired immediately after an `Element` switches into or out of fullscreen mode. This event is sent to the `Element` which is transitioning into or out of fullscreen mode. To find out whether the `Element` is entering or exiting fullscreen mode, check the value of `Document.fullscreenElement`: if this value is `null` then the element is exiting fullscreen mode, otherwise it is entering fullscreen mode. This event is not cancelable. ## Syntax Use the event name in methods like `addEventListener()`, or set an event handler property. addEventListener("fullscreenchange", (event) => { }) onfullscreenchange = (event) => { } ## Event type A generic `Event`. ## Examples In this example, a handler for the `fullscreenchange` event is added to the element whose ID is `fullscreen-div`. If the user clicks on the "Toggle Fullscreen Mode" button, the `click` handler will toggle fullscreen mode for the `div`. If `document.fullscreenElement` has a value it will exit fullscreen mode. If not, the div will be placed into fullscreen mode. Remember that by the time the `fullscreenchange` event is handled, the status of the element has already changed. So if the change is to fullscreen mode, `document.fullscreenElement` will point to the element that is now in fullscreen mode. On the other hand, if `document.fullscreenElement` is `null`, fullscreen mode has been canceled. What that means to the example code is that, if an element is currently in fullscreen mode, the `fullscreenchange` handler logs the `id` of the fullscreen element to the console. If `document.fullscreenElement` is `null`, the code logs a message that the change is to leave fullscreen mode. ### HTML

    fullscreenchange event example

    ### JavaScript function fullscreenchangeHandler(event) { // document.fullscreenElement will point to the element that // is in fullscreen mode if there is one. If not, the value // of the property is null. if (document.fullscreenElement) { console.log( `Element: ${document.fullscreenElement.id} entered fullscreen mode.`, ); } else { console.log("Leaving fullscreen mode."); } } const el = document.getElementById("fullscreen-div"); el.addEventListener("fullscreenchange", fullscreenchangeHandler); // or el.onfullscreenchange = fullscreenchangeHandler; // When the toggle button is clicked, enter/exit fullscreen document .getElementById("toggle-fullscreen") .addEventListener("click", (event) => { if (document.fullscreenElement) { // exitFullscreen is only available on the Document object. document.exitFullscreen(); } else { el.requestFullscreen(); } }); ## Specifications ## Browser compatibility | Desktop | Mobile ---|---|--- | Chrome | Edge | Firefox | Opera | Safari | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet | WebView Android `fullscreenchange_event` | 7115 | 791212–14 | 6410 | 581512.1–15 | 16.45.1 | 7118 | 6410 | 501412.1–14 | 16.4["Only available on iPad, not on iPhone.", "Shows an overlay button which can not be disabled. Swiping down exits fullscreen mode, making it unsuitable for some use cases like games."]12Only available on iPad, not on iPhone. | 10.01.0 | 714.4 ## See also * Document: fullscreenchange event * Element: fullscreenerror event * Fullscreen API * Guide to the Fullscreen API # Element: fullscreenerror event Limited availability This feature is not Baseline because it does not work in some of the most widely-used browsers. * Learn more * See full compatibility * Report feedback The `fullscreenerror` event is fired when the browser cannot switch to fullscreen mode. As with the `fullscreenchange` event, two `fullscreenerror` events are fired; the first is sent to the `Element` which failed to change modes, and the second is sent to the `Document` which owns that element. For some reasons that switching into fullscreen mode might fail, see the guide to the Fullscreen API. This event is not cancelable. ## Syntax Use the event name in methods like `addEventListener()`, or set an event handler property. addEventListener("fullscreenerror", (event) => { }) onfullscreenerror = (event) => { } ## Event type A generic `Event`. ## Examples const requestor = document.querySelector("div"); function handleError(event) { console.error("an error occurred changing into fullscreen"); console.log(event); } requestor.addEventListener("fullscreenerror", handleError); // or requestor.onfullscreenerror = handleError; requestor.requestFullscreen(); ## Specifications ## Browser compatibility | Desktop | Mobile ---|---|--- | Chrome | Edge | Firefox | Opera | Safari | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet | WebView Android `fullscreenerror_event` | 7118 | 791212–14 | 6410 | 581512.1–15 | 16.46 | 7118 | 6410 | 501412.1–14 | 16.4["Only available on iPad, not on iPhone.", "Shows an overlay button which can not be disabled. Swiping down exits fullscreen mode, making it unsuitable for some use cases like games."]12Only available on iPad, not on iPhone. | 10.01.0 | 714.4 ## See also * `fullscreenchange` * Fullscreen API * Guide to the Fullscreen API # Element: gesturechange event **Non-standard:** This feature is not standardized. We do not recommend using non-standard features in production, as they have limited browser support, and may change or be removed. However, they can be a suitable alternative in specific cases where no standard option exists. The `gesturechange` event is fired when digits move during a touch gesture. It is a proprietary event specific to WebKit. ## Syntax Use the event name in methods like `addEventListener()`, or set an event handler property. addEventListener("gesturechange", (event) => { }) ongesturechange = (event) => { } ## Event type A `GestureEvent`. Inherits from `Event`. ## Event properties _This interface also inherits properties of its parents,`UIEvent` and `Event`._ `GestureEvent.rotation` Read only Change in rotation (in degrees) since the event's beginning. Positive values indicate clockwise rotation; negative values indicate counterclockwise rotation. Initial value: `0.0`. `GestureEvent.scale` Read only Distance between two digits since the event's beginning. Expressed as a floating-point multiple of the initial distance between the digits at the beginning of the gesture. Values below 1.0 indicate an inward pinch (zoom out). Values above 1.0 indicate an outward unpinch (zoom in). Initial value: `1.0`. ## Specifications Not part of any specification. ## Browser compatibility | Desktop | Mobile ---|---|--- | Chrome | Edge | Firefox | Opera | Safari | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet | WebView Android `gesturechange_event` | No | No | No | No | No | No | No | No | 2 | No | No ## See also * GestureEventClassReference at the Safari Developer Library # Element: gestureend event **Non-standard:** This feature is not standardized. We do not recommend using non-standard features in production, as they have limited browser support, and may change or be removed. However, they can be a suitable alternative in specific cases where no standard option exists. The `gestureend` event is fired when there are no longer multiple fingers contacting the touch surface, thus ending the gesture. It is a proprietary event specific to WebKit. ## Syntax Use the event name in methods like `addEventListener()`, or set an event handler property. addEventListener("gestureend", (event) => { }) ongestureend = (event) => { } ## Event type A `GestureEvent`. Inherits from `Event`. ## Event properties _This interface also inherits properties of its parents,`UIEvent` and `Event`._ `GestureEvent.rotation` Read only Change in rotation (in degrees) since the event's beginning. Positive values indicate clockwise rotation; negative values indicate counterclockwise rotation. Initial value: `0.0`. `GestureEvent.scale` Read only Distance between two digits since the event's beginning. Expressed as a floating-point multiple of the initial distance between the digits at the beginning of the gesture. Values below 1.0 indicate an inward pinch (zoom out). Values above 1.0 indicate an outward unpinch (zoom in). Initial value: `1.0`. ## Specifications Not part of any specification. ## Browser compatibility | Desktop | Mobile ---|---|--- | Chrome | Edge | Firefox | Opera | Safari | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet | WebView Android `gestureend_event` | No | No | No | No | No | No | No | No | 2 | No | No ## See also * GestureEventClassReference at the Safari Developer Library # Element: gesturestart event **Non-standard:** This feature is not standardized. We do not recommend using non-standard features in production, as they have limited browser support, and may change or be removed. However, they can be a suitable alternative in specific cases where no standard option exists. The `gesturestart` event is fired when multiple fingers contact the touch surface, thus starting a new gesture. During the gesture, `gesturechange` events will be fired. When the gesture has ended, a `gestureend` event will be fired. It is a proprietary event specific to WebKit. ## Syntax Use the event name in methods like `addEventListener()`, or set an event handler property. addEventListener("gesturestart", (event) => { }) ongesturestart = (event) => { } ## Event type A `GestureEvent`. Inherits from `Event`. ## Event properties _This interface also inherits properties of its parents,`UIEvent` and `Event`._ `GestureEvent.rotation` Read only Change in rotation (in degrees) since the event's beginning. Positive values indicate clockwise rotation; negative values indicate counterclockwise rotation. Initial value: `0.0`. `GestureEvent.scale` Read only Distance between two digits since the event's beginning. Expressed as a floating-point multiple of the initial distance between the digits at the beginning of the gesture. Values below 1.0 indicate an inward pinch (zoom out). Values above 1.0 indicate an outward unpinch (zoom in). Initial value: `1.0`. ## Specifications Not part of any specification. ## Browser compatibility | Desktop | Mobile ---|---|--- | Chrome | Edge | Firefox | Opera | Safari | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet | WebView Android `gesturestart_event` | No | No | No | No | No | No | No | No | 2 | No | No ## See also * GestureEventClassReference at the Safari Developer Library # Element: getAnimations() method Baseline Widely available This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2020. * Learn more * See full compatibility * Report feedback The `getAnimations()` method of the `Element` interface (specified on the `Animatable` mixin) returns an array of all `Animation` objects affecting this element or which are scheduled to do so in future. It can optionally return `Animation` objects for descendant elements too. **Note:** This array includes CSS Animations, CSS Transitions, and Web Animations. ## Syntax getAnimations() getAnimations(options) ### Parameters `options` Optional An options object containing the following property: `subtree` A boolean value which, if `true`, causes animations that target descendants of _Element_ to be returned as well. This includes animations that target any CSS pseudo-elements attached to _Element_ or one of its descendants. Defaults to `false`. ### Return value An `Array` of `Animation` objects, each representing an animation currently targeting the `Element` on which this method is called, or one of its descendant elements if `{ subtree: true }` is specified. ## Examples The following code snippet will wait for all animations on `elem` and its descendants to finish before removing the element from the document. Promise.all( elem.getAnimations({ subtree: true }).map((animation) => animation.finished), ).then(() => elem.remove()); ## Specifications ## Browser compatibility | Desktop | Mobile ---|---|--- | Chrome | Edge | Firefox | Opera | Safari | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet | WebView Android `getAnimations` | 84 | 84 | 75 | 70 | 13.1 | 84 | 79 | 60 | 13.4 | 14.0 | 84 ## See also * Web Animations API * CSS Animations * CSS Transitions * `Document.getAnimations()` \- Fetch all animations in the document * `Animation` # Element: getAttribute() method Baseline Widely available This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015. * Learn more * See full compatibility * Report feedback The `getAttribute()` method of the `Element` interface returns the value of a specified attribute on the element. If the given attribute does not exist, the value returned will be `null`. If you need to inspect the `Attr` node's properties, you can use the `getAttributeNode()` method instead. ## Syntax getAttribute(attributeName) ### Parameters `attributeName` The name of the attribute whose value you want to get. ### Return value A string containing the value of `attributeName` if the attribute exists, otherwise `null`. ## Examples
    Hi Champ!
    const div1 = document.getElementById("div1"); //
    Hi Champ!
    const exampleAttr = div1.getAttribute("id"); // "div1" const align = div1.getAttribute("align"); // null ## Description ### Lower casing When called on an HTML element in a DOM flagged as an HTML document, `getAttribute()` lower-cases its argument before proceeding. ### Retrieving nonce values For security reasons, CSP nonces from non-script sources, such as CSS selectors, and `.getAttribute("nonce")` calls are hidden. let nonce = script.getAttribute("nonce"); // returns empty string Instead of retrieving the nonce from the content attribute, use the `nonce` property: let nonce = script.nonce; ## Specifications ## Browser compatibility | Desktop | Mobile ---|---|--- | Chrome | Edge | Firefox | Opera | Safari | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet | WebView Android `getAttribute` | 1 | 12 | 1 | 8 | 1 | 18 | 4 | 10.1 | 1 | 1.0 | 4.4 ## See also * `Element.hasAttribute()` * `Element.setAttribute()` * `Element.removeAttribute()` * `Element.toggleAttribute()` # Element: getAttributeNames() method Baseline Widely available This feature is well established and works across many devices and browser versions. It’s been available across browsers since October 2018. * Learn more * See full compatibility * Report feedback The `getAttributeNames()` method of the `Element` interface returns the attribute names of the element as an `Array` of strings. If the element has no attributes it returns an empty array. Using `getAttributeNames()` along with `getAttribute()`, is a memory-efficient and performant alternative to accessing `Element.attributes`. The names returned by `getAttributeNames()` are _qualified_ attribute names, meaning that attributes with a namespace prefix have their names returned with that namespace prefix (_not_ the actual namespace), followed by a colon, followed by the attribute name (for example, `xlink:href`), while any attributes which have no namespace prefix have their names returned as-is (for example, `href`). ## Syntax getAttributeNames() ### Parameters None. ### Return value An (`Array`) of strings. ## Examples The following example shows how: * For an attribute which has a namespace prefix, `getAttributeNames()` returns that namespace prefix along with the attribute name. * For an attribute which has no namespace prefix, `getAttributeNames()` returns just the attribute name, as-is. It's important to understand that: 1. An attribute can be present in the DOM with a namespace but lacking a namespace prefix. 2. For an attribute in the DOM that has a namespace but lacks a namespace prefix, `getAttributeNames()` will return just the attribute name, with no indication that the attribute is in a namespace. The example below includes such a "namespaced but without a namespace prefix" case. const element = document.createElement("a"); // set "href" attribute with no namespace and no namespace prefix element.setAttribute("href", "https://example.com"); // set "href" attribute with namespace and also "xlink" namespace prefix element.setAttributeNS( "http://www.w3.org/1999/xlink", "xlink:href", "https://example.com", ); // set "show" attribute with namespace but no namespace prefix element.setAttributeNS("http://www.w3.org/1999/xlink", "show", "new"); // Iterate over element's attributes for (const name of element.getAttributeNames()) { const value = element.getAttribute(name); console.log(name, value); } // logs: // href https://example.com // xlink:href https://example.com // show new ## Specifications ## Browser compatibility | Desktop | Mobile ---|---|--- | Chrome | Edge | Firefox | Opera | Safari | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet | WebView Android `getAttributeNames` | 61 | 18 | 45 | 48 | 10.1 | 61 | 45 | 45 | 10.3 | 8.0 | 61 # Element: getAttributeNode() method Baseline Widely available This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015. * Learn more * See full compatibility * Report feedback Returns the specified attribute of the specified element, as an `Attr` node. This method is useful if you need the attribute's instance properties. If you only need the attribute's value, you can use the `getAttribute()` method instead. ## Syntax getAttributeNode(attrName) ### Parameters `attrName` A string containing the name of the attribute. ### Return value An `Attr` node for the attribute. ## Examples // html:
    let t = document.getElementById("top"); let idAttr = t.getAttributeNode("id"); alert(idAttr.value === "top"); ## Notes When called on an HTML element in a DOM flagged as an HTML document, `getAttributeNode` lower-cases its argument before proceeding. The `Attr` node inherits from `Node`, but is not considered a part of the document tree. Common `Node` attributes like parentNode, previousSibling, and nextSibling are `null` for an `Attr` node. You can, however, get the element to which the attribute belongs with the `ownerElement` property. ## Specifications ## Browser compatibility | Desktop | Mobile ---|---|--- | Chrome | Edge | Firefox | Opera | Safari | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet | WebView Android `getAttributeNode` | 1 | 12 | 1 | ≤12.1 | 1 | 18 | 4 | ≤12.1 | 1 | 1.0 | 4.4 ## See also * `Document.createAttribute()` * `Element.setAttributeNode()` * `Element.removeAttributeNode()` # Element: getAttributeNodeNS() method Baseline Widely available This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015. * Learn more * See full compatibility * Report feedback The `getAttributeNodeNS()` method of the `Element` interface returns the namespaced `Attr` node of an element. This method is useful if you need the namespaced attribute's instance properties. If you only need the namespaced attribute's value, you can use the `getAttributeNS()` method instead. If you need the `Attr` node of an element in HTML documents and the attribute is not namespaced, use the `getAttributeNode()` method instead. ## Syntax getAttributeNodeNS(namespace, nodeName) ### Parameters `namespace` A string specifying the namespace of the attribute. `nodeName` A string specifying the name of the attribute. ### Return value The node for specified attribute. ## Notes `getAttributeNodeNS` is more specific than getAttributeNode in that it allows you to specify attributes that are part of a particular namespace. The corresponding setter method is setAttributeNodeNS. ## Specifications ## Browser compatibility | Desktop | Mobile ---|---|--- | Chrome | Edge | Firefox | Opera | Safari | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet | WebView Android `getAttributeNodeNS` | 1 | 12 | 1 | ≤12.1 | 1 | 18 | 4 | ≤12.1 | 1 | 1.0 | 4.4 ## See also * `Document.createAttribute()` * `Document.createAttributeNS()` * `Element.setAttributeNodeNS()` # Element: getAttributeNS() method Baseline Widely available This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015. * Learn more * See full compatibility * Report feedback The `getAttributeNS()` method of the `Element` interface returns the string value of the attribute with the specified namespace and name. If the named attribute does not exist, the value returned will either be `null` or `""` (the empty string); see Notes for details. If you are working with HTML documents and you don't need to specify the requested attribute as being part of a specific namespace, use the `getAttribute()` method instead. ## Syntax getAttributeNS(namespace, name) ### Parameters `namespace` The namespace in which to look for the specified attribute. `name` The name of the attribute to look for. ### Return value The string value of the specified attribute. If the attribute doesn't exist, the result is `null`. **Note:** Earlier versions of the DOM specification had this method described as returning an empty string for non-existent attributes, but it was not typically implemented this way since null makes more sense. The DOM4 specification now says this method should return null for non-existent attributes. ## Examples The following SVG document reads the value of the `foo` attribute in a custom namespace. In an HTML document, the attribute has to be accessed with `test:foo` since namespaces are not supported. getAttributeNS() test page ## Notes `getAttributeNS()` differs from `getAttribute()` in that it allows you to further specify the requested attribute as being part of a particular namespace, as in the example above, where the attribute is part of the fictional "test" namespace. Prior to the DOM4 specification, this method was specified to return an empty string rather than null for non-existent attributes. However, most browsers instead returned null. Starting with DOM4, the specification now says to return null. However, some older browsers return an empty string. For that reason, you should use `hasAttributeNS()` to check for an attribute's existence prior to calling `getAttributeNS()` if it is possible that the requested attribute does not exist on the specified element. ## Specifications ## Browser compatibility | Desktop | Mobile ---|---|--- | Chrome | Edge | Firefox | Opera | Safari | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet | WebView Android `getAttributeNS` | 1 | 12 | 1Starting in Firefox 13, `null` is always returned instead of the empty string, as per the DOM4 specification. Previously, there were cases in which an empty string could be returned. | ≤12.1 | 1 | 18 | 4Starting in Firefox for Android 14, `null` is always returned instead of the empty string, as per the DOM4 specification. Previously, there were cases in which an empty string could be returned. | ≤12.1 | 1 | 1.0 | 4.4 ## See also * `Element.hasAttributeNS()` * `Element.setAttributeNS()` * `Element.removeAttributeNS()` # Element: getBoundingClientRect() method Baseline Widely available This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015. * Learn more * See full compatibility * Report feedback The `Element.getBoundingClientRect()` method returns a `DOMRect` object providing information about the size of an element and its position relative to the viewport. ## Syntax getBoundingClientRect() ### Parameters None. ### Return value The returned value is a `DOMRect` object which is the smallest rectangle which contains the entire element, including its padding and border-width. The `left`, `top`, `right`, `bottom`, `x`, `y`, `width`, and `height` properties describe the position and size of the overall rectangle in pixels. Properties other than `width` and `height` are relative to the top-left of the viewport. The `width` and `height` properties of the `DOMRect` object returned by the method include the `padding` and `border-width`, not only the content width/height. In the standard box model, this would be equal to the `width` or `height` property of the element + `padding` \+ `border-width`. But if `box- sizing: border-box` is set for the element this would be directly equal to its `width` or `height`. The returned value can be thought of as the union of the rectangles returned by `getClientRects()` for the element, i.e., the CSS border-boxes associated with the element. Empty border-boxes are completely ignored. If all the element's border-boxes are empty, then a rectangle is returned with a `width` and `height` of zero and where the `top` and `left` are the top-left of the border-box for the first CSS box (in content order) for the element. The amount of scrolling that has been done of the viewport area (or any other scrollable element) is taken into account when computing the bounding rectangle. This means that the rectangle's boundary edges (`top`, `right`, `bottom`, `left`) change their values every time the scrolling position changes (because their values are relative to the viewport and not absolute). If you need the bounding rectangle relative to the top-left corner of the document, just add the current scrolling position to the `top` and `left` properties (these can be obtained using `window.scrollY` and `window.scrollX`) to get a bounding rectangle which is independent from the current scrolling position. ## Examples ### Basic This simple example retrieves the `DOMRect` object representing the bounding client rect of a simple `
    ` element, and prints out its properties below it.
    div { width: 400px; height: 200px; padding: 20px; margin: 50px auto; background: purple; } let elem = document.querySelector("div"); let rect = elem.getBoundingClientRect(); for (const key in rect) { if (typeof rect[key] !== "function") { let para = document.createElement("p"); para.textContent = `${key} : ${rect[key]}`; document.body.appendChild(para); } } Notice how the `width`/`height` are equal to its `width`/`height` \+ `padding`. Also note how the values of `x`/`left`, `y`/`top`, `right`, and `bottom` are equal to the absolute distance from the relevant edge of the viewport to that side of the element, in each case. ### Scrolling This example demonstrates how bounding client rect is changing when document is scrolled.
    div#example { width: 400px; height: 200px; padding: 20px; margin: 50px auto; background: purple; } body { padding-bottom: 1000px; } p { margin: 0; } function update() { const container = document.getElementById("controls"); const elem = document.getElementById("example"); const rect = elem.getBoundingClientRect(); container.textContent = ""; for (const key in rect) { if (typeof rect[key] !== "function") { let para = document.createElement("p"); para.textContent = `${key} : ${rect[key]}`; container.appendChild(para); } } } document.addEventListener("scroll", update); update(); ## Specifications ## Browser compatibility | Desktop | Mobile ---|---|--- | Chrome | Edge | Firefox | Opera | Safari | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet | WebView Android `getBoundingClientRect` | 2 | 12 | 3 | 9.5 | 4 | 18 | 4 | 10.1 | 3.2Safari for iOS will modify the effective viewport based on the user zoom. This results in incorrect values whenever the user has zoomed. | 1.0 | 2 ## See also * `getClientRects()` # Element: getClientRects() method Baseline Widely available This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015. * Learn more * See full compatibility * Report feedback The `getClientRects()` method of the `Element` interface returns a collection of `DOMRect` objects that indicate the bounding rectangles for each CSS border box in a client. Most elements only have one border box each, but a multiline inline-level element (such as a multiline `` element, by default) has a border box around each line. ## Syntax getClientRects() ### Parameters None. ### Return value The returned value is a collection of `DOMRect` objects, one for each CSS border box associated with the element. Each `DOMRect` object describes the border box, in pixels, with the top-left relative to the top-left of the viewport. For tables with captions, the caption is included even though it's outside the border box of the table. When called on SVG elements other than an outer-``, the "viewport" that the resulting rectangles are relative to is the viewport that the element's outer-`` establishes (and to be clear, the rectangles are also transformed by the outer-``'s `viewBox` transform, if any). The amount of scrolling that has been done of the viewport area (or any other scrollable element) is taken into account when computing the rectangles. The returned rectangles do not include the bounds of any child elements that might happen to overflow. For HTML `` elements, SVG elements that do not render anything themselves, `display:none` elements, and generally any elements that are not directly rendered, an empty list is returned. Rectangles are returned even for CSS boxes that have empty border-boxes. The `left`, `top`, `right`, and `bottom` coordinates can still be meaningful. Fractional pixel offsets are possible. ## Examples These examples draw client rects in various colors. Note that the JavaScript function that paints the client rects is connected to the markup via the class `withClientRectsOverlay`. ### HTML Example 1: This HTML creates three paragraphs with a `` inside, each embedded in a `
    ` block. Client rects are painted for the paragraph in the second block, and for the `` element in the third block.

    A paragraph with a span inside

    Both the span and the paragraph have a border set. The client rects are in red. Note that the p has only one border box, while the span has multiple border boxes.

    Original

    Paragraph that spans multiple lines

    p's rect

    Paragraph that spans multiple lines

    span's rect

    Paragraph that spans multiple lines

    Example 2: This HTML creates three ordered lists. Client rects are painted for the `
      ` in the second block, and for each `
    1. ` element in the third block.

      A list

      Note that the border box doesn't include the number, so neither do the client rects.

      Original
      1. Item 1
      2. Item 2
      ol's rect
      1. Item 1
      2. Item 2
      each li's rect
      1. Item 1
      2. Item 2
      Example 3: This HTML creates two tables with captions. Client rects are painted for the `
    ` in the second block.

    A table with a caption

    Although the table's border box doesn't include the caption, the client rects do include the caption.

    Original
    caption
    thead
    tbody
    table's rect
    caption
    thead
    tbody
    ### CSS The CSS draws borders around the paragraph and the `` inside each `
    ` block for the first example, around the `
      ` and `
    1. ` for the second example, and around ``, `
      `, and `` elements for the third example. strong { text-align: center; } div { display: inline-block; width: 150px; } div p, ol, table { border: 1px solid blue; } span, li, th, td { border: 1px solid green; } ### JavaScript The JavaScript code draws the client rects for all HTML elements that have CSS class `withClientRectsOverlay` assigned. function addClientRectsOverlay(elt) { /* Absolutely position a div over each client rect so that its border width is the same as the rectangle's width. Note: the overlays will be out of place if the user resizes or zooms. */ const rects = elt.getClientRects(); for (const rect of rects) { const tableRectDiv = document.createElement("div"); tableRectDiv.style.position = "absolute"; tableRectDiv.style.border = "1px solid red"; const scrollTop = document.documentElement.scrollTop || document.body.scrollTop; const scrollLeft = document.documentElement.scrollLeft || document.body.scrollLeft; tableRectDiv.style.margin = tableRectDiv.style.padding = "0"; tableRectDiv.style.top = `${rect.top + scrollTop}px`; tableRectDiv.style.left = `${rect.left + scrollLeft}px`; // We want rect.width to be the border width, so content width is 2px less. tableRectDiv.style.width = `${rect.width - 2}px`; tableRectDiv.style.height = `${rect.height - 2}px`; document.body.appendChild(tableRectDiv); } } (() => { /* Call function addClientRectsOverlay(elt) for all elements with assigned class "withClientRectsOverlay" */ const elems = document.getElementsByClassName("withClientRectsOverlay"); for (const elem of elems) { addClientRectsOverlay(elem); } })(); ### Result ## Specifications ## Browser compatibility | Desktop | Mobile ---|---|--- | Chrome | Edge | Firefox | Opera | Safari | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet | WebView Android `getClientRects` | 2 | 12 | 3 | 9.5 | 4 | 18 | 4 | 10.1 | 3.2 | 1.0 | 2 ## See also * `Element.getBoundingClientRect()` # Element: getElementsByClassName() method Baseline Widely available This feature is well established and works across many devices and browser versions. It’s been available across browsers since October 2017. * Learn more * See full compatibility * Report feedback The `Element` method `getElementsByClassName()` returns a live `HTMLCollection` which contains every descendant element which has the specified class name or names. The method `getElementsByClassName()` on the `Document` interface works essentially the same way, except it acts on the entire document, starting at the document root. ## Syntax getElementsByClassName(names) ### Parameters `names` A string containing one or more class names to match on, separated by whitespace. ### Return value An `HTMLCollection` providing a live-updating list of every element which is a member of every class in `names`. ## Usage notes As always, the returned collection is _live_ , meaning that it always reflects the current state of the DOM tree rooted at the element on which the function was called. As new elements that match `names` are added to the subtree, they immediately appear in the collection. Similarly, if an existing element that doesn't match `names` has its set of classes adjusted so that it matches, it immediately appears in the collection. The opposite is also true; as elements no longer match the set of names, they are immediately removed from the collection. **Note:** In quirks mode, the class names are compared in a case-insensitive fashion. Otherwise, they're case sensitive. ## Examples ### Matching a single class To look for elements that include among their classes a single specified class, we just provide that class name when calling `getElementsByClassName()`: element.getElementsByClassName("test"); This example finds all elements that have a class of `test`, which are also a descendant of the element that has the `id` of `main`: document.getElementById("main").getElementsByClassName("test"); ### Matching multiple classes To find elements whose class lists include both the `red` and `test` classes: element.getElementsByClassName("red test"); ### Examining the results You can use either the `item()` method on the returned `HTMLCollection` or standard array syntax to examine individual elements in the collection. However, the following code will not work as one might expect because `"matches"` will change as soon as any `"color-box"` class is removed. const matches = element.getElementsByClassName("color-box"); for (let i = 0; i < matches.length; i++) { matches[i].classList.remove("color-box"); matches.item(i).classList.add("hue-frame"); } Instead, use another method, such as: const matches = element.getElementsByClassName("color-box"); while (matches.length > 0) { matches.item(0).classList.add("hue-frame"); matches[0].classList.remove("color-box"); } This code finds descendant elements with the `"color-box"` class, adds the class `"hue-frame"`, by calling `item(0)`, then removes `"color-box"` (using array notation). Another element (if any are left) will then become `item(0)`. ### Filtering the results using array methods We can also use `Array` methods on any `HTMLCollection` by passing the `HTMLCollection` as the method's `this` value. Here we'll find all `
      ` elements that have a class of `test`: const testElements = document.getElementsByClassName("test"); const testDivs = Array.prototype.filter.call( testElements, (testElement) => testElement.nodeName === "DIV", ); ## Specifications ## Browser compatibility | Desktop | Mobile ---|---|--- | Chrome | Edge | Firefox | Opera | Safari | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet | WebView Android `getElementsByClassName` | 1 | 1612–16Only supported for `HTMLElement`, not all `Element` objects, such as `SVGElement`. | 3Before Firefox 19, this method was returning a `NodeList`; it was then changed to reflect the change in the spec. | 9.5 | 3.1 | 18 | 4 | 10.1 | 2 | 1.0 | 4.4 # Element: getElementsByTagName() method Baseline Widely available This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015. * Learn more * See full compatibility * Report feedback The `Element.getElementsByTagName()` method returns a live `HTMLCollection` of elements with the given tag name. All descendants of the specified element are searched, but not the element itself. The returned list is _live_ , which means it updates itself with the DOM tree automatically. Therefore, there is no need to call `Element.getElementsByTagName()` with the same element and arguments repeatedly if the DOM changes in between calls. When called on an HTML element in an HTML document, `getElementsByTagName` lower-cases the argument before searching for it. This is undesirable when trying to match camel-cased SVG elements (such as ``) in an HTML document. Instead, use `Element.getElementsByTagNameNS()`, which preserves the capitalization of the tag name. `Element.getElementsByTagName` is similar to `Document.getElementsByTagName()`, except that it only searches for elements that are descendants of the specified element. ## Syntax getElementsByTagName(tagName) ### Parameters `tagName` The qualified name to look for. The special string `"*"` represents all elements. For compatibility with XHTML, lower-case should be used. ### Return value A _live_ `HTMLCollection` of elements with a matching tag name, in the order they appear. If no elements are found, the `HTMLCollection` is empty. ## Examples // Check the status of each data cell in a table const table = document.getElementById("forecast-table"); const cells = table.getElementsByTagName("td"); for (const cell of cells) { const status = cell.getAttribute("data-status"); if (status === "open") { // Grab the data } } ## Specifications ## Browser compatibility | Desktop | Mobile ---|---|--- | Chrome | Edge | Firefox | Opera | Safari | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet | WebView Android `getElementsByTagName` | 1Initially, this method was returning a `NodeList`; it was then changed to reflect the spec change. | 12 | 1Before Firefox 19, this method was returning a `NodeList`; it was then changed to reflect the change in the spec. | 8Initially, this method was returning a `NodeList`; it was then changed to reflect the spec change. | 1Initially, this method was returning a `NodeList`; it was then changed to reflect the spec change. | 18Initially, this method was returning a `NodeList`; it was then changed to reflect the spec change. | 4Before Firefox for Android 19, this method was returning a `NodeList`; it was then changed to reflect the change in the spec. | 10.1 | 1Initially, this method was returning a `NodeList`; it was then changed to reflect the spec change. | 1.0Initially, this method was returning a `NodeList`; it was then changed to reflect the spec change. | 4.4Initially, this method was returning a `NodeList`; it was then changed to reflect the spec change. `all_elements_selector` | 1 | 12 | 1 | ≤15 | 1 | 18 | 4 | ≤14 | 1 | 1.0 | 4.4 # Element: getElementsByTagNameNS() method Baseline Widely available This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015. * Learn more * See full compatibility * Report feedback The `Element.getElementsByTagNameNS()` method returns a live `HTMLCollection` of elements with the given tag name belonging to the given namespace. It is similar to `Document.getElementsByTagNameNS`, except that its search is restricted to descendants of the specified element. ## Syntax getElementsByTagNameNS(namespaceURI, localName) ### Parameters `namespaceURI` The namespace URI of elements to look for (see `Element.namespaceURI` and `Attr.namespaceURI`). For example, if you need to look for XHTML elements, use the XHTML namespace URI, `http://www.w3.org/1999/xhtml`. `localName` Either the local name of elements to look for or the special value `"*"`, which matches all elements (see `Element.localName` and `Attr.localName`). ### Return value A live `HTMLCollection` of found elements in the order they appear in the tree. ## Examples // Check the alignment on a number of cells in a table in an XHTML document. const table = document.getElementById("forecast-table"); const cells = table.getElementsByTagNameNS( "http://www.w3.org/1999/xhtml", "td", ); for (const cell of cells) { const axis = cell.getAttribute("axis"); if (axis === "year") { // Grab the data } } ## Specifications ## Browser compatibility | Desktop | Mobile ---|---|--- | Chrome | Edge | Firefox | Opera | Safari | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet | WebView Android `getElementsByTagNameNS` | 1Initially, this method was returning a `NodeList`; it was then changed to reflect the spec change. | 12 | 1["The behavior of `element.getElementsByTagNameNS` changed between Firefox 3.5 and Firefox 3.6. In Firefox 3.5 and before, this function would automatically case-fold any queries so that a search for \"foo\" would match \"Foo\" or \"foo\". In Firefox 3.6 and later this function is now case-sensitive so that a query for \"foo\" will only match \"foo\" and not \"Foo\". For more background on this, please see the comment from Henri Sivonen about the change. You can also look at the relevant part of the standard, which states which parts of the API are case-sensitive and which parts aren't.", "Before Firefox 19, this method was returning a `NodeList`; it was then changed to reflects the spec change."] | ≤12.1Initially, this method was returning a `NodeList`; it was then changed to reflect the spec change. | 1Initially, this method was returning a `NodeList`; it was then changed to reflect the spec change. | 18Initially, this method was returning a `NodeList`; it was then changed to reflect the spec change. | 4Before Firefox 19, this method was returning a `NodeList`; it was then changed to reflects the spec change. | ≤12.1Initially, this method was returning a `NodeList`; it was then changed to reflect the spec change. | 1Initially, this method was returning a `NodeList`; it was then changed to reflect the spec change. | 1.0Initially, this method was returning a `NodeList`; it was then changed to reflect the spec change. | 4.4Initially, this method was returning a `NodeList`; it was then changed to reflect the spec change. `all_elements_selector` | 1 | 12 | 1 | ≤15 | 1 | 18 | 4 | ≤14 | 1 | 1.0 | 4.4 # Element: getHTML() method Baseline 2024 Newly available Since September 2024, this feature works across the latest devices and browser versions. This feature might not work in older devices or browsers. * Learn more * See full compatibility * Report feedback The `getHTML()` method of the `Element` interface is used to serialize an element's DOM to an HTML string. The method provides an options argument that enables the serialization of child nodes that are shadow roots. The options can be used to include nested shadow roots that have been set as `serializable`, and/or a specified array of `ShadowRoot` objects, which may be either open or closed. Without arguments, child nodes that are shadow roots are not serialized, and this method behaves in the same way as reading the value of `Element.innerHTML`. Note that some browsers serialize the `<` and `>` characters as `<` and `>` when they appear in attribute values (see Browser compatibility). This is to prevent a potential security vulnerability (mutation XSS) in which an attacker can craft input that bypasses a sanitization function, enabling a cross-site scripting (XSS) attack. ## Syntax getHTML(options) ### Parameters `options` Optional An options object with the following optional parameters: `serializableShadowRoots` A boolean value that specifies whether to include `serializable` shadow roots. The default value is `false`. `shadowRoots` An array of `ShadowRoot` objects to serialize. These are included regardless of whether they are marked as `serializable`, or if they are open or closed. The default value is an empty array. ### Return value A string that represents the HTML serialization of the element. ### Exceptions None. ## Specifications ## Browser compatibility | Desktop | Mobile ---|---|--- | Chrome | Edge | Firefox | Opera | Safari | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet | WebView Android `getHTML` | 125 | 125 | 128 | 111 | 18 | 125 | 128 | 83 | 18 | 27.0 | 125 `escapes_lt_gt_in_attributes` | 114 | 114 | 140 | 100 | preview | 114 | 140 | No | No | No | No ## See Also * `ShadowRoot.getHTML()` * `Element.innerHTML` * `Element.setHTMLUnsafe()` * `ShadowRoot.setHTMLUnsafe()` # Element: gotpointercapture event Baseline Widely available This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2020. * Learn more * See full compatibility * Report feedback The `gotpointercapture` event is fired when an element captures a pointer using `setPointerCapture()`. ## Syntax Use the event name in methods like `addEventListener()`, or set an event handler property. addEventListener("gotpointercapture", (event) => { }) ongotpointercapture = (event) => { } ## Event type A `PointerEvent`. Inherits from `Event`. Event UIEvent MouseEvent PointerEvent ## Event properties _This interface inherits properties from`MouseEvent` and `Event`._ `PointerEvent.altitudeAngle` Read only Experimental Represents the angle between a transducer (a pointer or stylus) axis and the X-Y plane of a device screen. `PointerEvent.azimuthAngle` Read only Experimental Represents the angle between the Y-Z plane and the plane containing both the transducer (a pointer or stylus) axis and the Y axis. `PointerEvent.persistentDeviceId` Read only Experimental A unique identifier for the pointing device generating the `PointerEvent`. `PointerEvent.pointerId` Read only A unique identifier for the pointer causing the event. `PointerEvent.width` Read only The width (magnitude on the X axis), in CSS pixels, of the contact geometry of the pointer. `PointerEvent.height` Read only The height (magnitude on the Y axis), in CSS pixels, of the contact geometry of the pointer. `PointerEvent.pressure` Read only The normalized pressure of the pointer input in the range `0` to `1`, where `0` and `1` represent the minimum and maximum pressure the hardware is capable of detecting, respectively. `PointerEvent.tangentialPressure` Read only The normalized tangential pressure of the pointer input (also known as barrel pressure or cylinder stress) in the range `-1` to `1`, where `0` is the neutral position of the control. `PointerEvent.tiltX` Read only The plane angle (in degrees, in the range of `-90` to `90`) between the Y–Z plane and the plane containing both the pointer (e.g., pen stylus) axis and the Y axis. `PointerEvent.tiltY` Read only The plane angle (in degrees, in the range of `-90` to `90`) between the X–Z plane and the plane containing both the pointer (e.g., pen stylus) axis and the X axis. `PointerEvent.twist` Read only The clockwise rotation of the pointer (e.g., pen stylus) around its major axis in degrees, with a value in the range `0` to `359`. `PointerEvent.pointerType` Read only Indicates the device type that caused the event (mouse, pen, touch, etc.). `PointerEvent.isPrimary` Read only Indicates if the pointer represents the primary pointer of this pointer type. ## Examples This example gets a `

      ` element and listens for the `gotpointercapture` event. It then calls `setPointerCapture()` on the element on a `pointerdown` event, which will trigger `gotpointercapture`. const para = document.querySelector("p"); para.addEventListener("gotpointercapture", () => { console.log("I've been captured!"); }); para.addEventListener("pointerdown", (event) => { para.setPointerCapture(event.pointerId); }); The same example, using the `ongotpointercapture` event handler property: const para = document.querySelector("p"); para.ongotpointercapture = () => { console.log("I've been captured!"); }; para.addEventListener("pointerdown", (event) => { para.setPointerCapture(event.pointerId); }); ## Specifications ## Browser compatibility | Desktop | Mobile ---|---|--- | Chrome | Edge | Firefox | Opera | Safari | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet | WebView Android `gotpointercapture_event` | 57 | 17 | 59 | 44 | 13 | 57 | 79 | 43 | 13 | 7.0 | 57 ## See also * Related events * `lostpointercapture` * `pointerover` * `pointerenter` * `pointerdown` * `pointermove` * `pointerup` * `pointercancel` * `pointerout` * `pointerleave` * `pointerrawupdate` # Element: hasAttribute() method Baseline Widely available This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015. * Learn more * See full compatibility * Report feedback The `Element.hasAttribute()` method returns a **Boolean** value indicating whether the specified element has the specified attribute or not. ## Syntax hasAttribute(name) ### Parameters `name` is a string representing the name of the attribute. ### Return value A boolean. ## Examples const foo = document.getElementById("foo"); if (foo.hasAttribute("bar")) { // do something } ## Specifications ## Browser compatibility | Desktop | Mobile ---|---|--- | Chrome | Edge | Firefox | Opera | Safari | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet | WebView Android `hasAttribute` | 1 | 12 | 1 | 8 | 1 | 18 | 4 | 10.1 | 1 | 1.0 | 4.4 ## See also * `Element.hasAttributes()` * `Element.getAttribute()` * `Element.setAttribute()` * `Element.removeAttribute()` * `Element.toggleAttribute()` # Element: hasAttributeNS() method Baseline Widely available This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015. * Learn more * See full compatibility * Report feedback The `hasAttributeNS()` method of the `Element` interface returns a boolean value indicating whether the current element has the specified attribute with the specified namespace. If you are working with HTML documents and you don't need to specify the requested attribute as being part of a specific namespace, use the `hasAttribute()` method instead. ## Syntax hasAttributeNS(namespace,localName) ### Parameters `namespace` A string specifying the namespace of the attribute. `localName` The name of the attribute. ### Return value A boolean. ## Examples // Check that the attribute exists before you set a value const d = document.getElementById("div1"); if ( d.hasAttributeNS("http://www.mozilla.org/ns/specialspace/", "special-align") ) { d.setAttribute("align", "center"); } ## Specifications ## Browser compatibility | Desktop | Mobile ---|---|--- | Chrome | Edge | Firefox | Opera | Safari | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet | WebView Android `hasAttributeNS` | 1 | 12 | 1 | ≤12.1 | 1 | 18 | 4 | ≤12.1 | 1 | 1.0 | 4.4 ## See also * `Element.getAttributeNS()` * `Element.setAttributeNS()` * `Element.removeAttributeNS()` # Element: hasAttributes() method Baseline Widely available This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015. * Learn more * See full compatibility * Report feedback The `hasAttributes()` method of the `Element` interface returns a boolean value indicating whether the current element has any attributes or not. ## Syntax hasAttributes() ### Parameters None. ### Return value A boolean. ## Examples let foo = document.getElementById("foo"); if (foo.hasAttributes()) { // Do something with 'foo.attributes' } ## Specifications ## Browser compatibility | Desktop | Mobile ---|---|--- | Chrome | Edge | Firefox | Opera | Safari | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet | WebView Android `hasAttributes` | 1 | 12 | 1Before Firefox 35, it was implemented on the `Node` interface. | ≤12.1 | 1 | 18 | 4Before Firefox for Android 35, it was implemented on the `Node` interface. | ≤12.1 | 1 | 1.0 | 4.4 ## See also * `Element.attributes` * `Element.hasAttribute()` * `Element.getAttribute()` * `Element.setAttribute()` * `Element.removeAttribute()` * `Element.toggleAttribute()` # Element: hasPointerCapture() method Baseline Widely available This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2020. * Learn more * See full compatibility * Report feedback The `hasPointerCapture()` method of the `Element` interface checks whether the element on which it is invoked has pointer capture for the pointer identified by the given pointer ID. ## Syntax hasPointerCapture(pointerId) ### Parameters `pointerId` The `pointerId` of a `PointerEvent` object. ### Return value A boolean value — `true` if the element does have pointer capture for the pointer identified by the given pointer ID, `false` if it doesn't. ## Examples

      Touch this element with a pointer.
      ## Specifications ## Browser compatibility | Desktop | Mobile ---|---|--- | Chrome | Edge | Firefox | Opera | Safari | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet | WebView Android `hasPointerCapture` | 55 | 79 | 59 | 42 | 13 | 55 | 79 | 42 | 13 | 6.0 | 55 ## See also * `Element.setPointerCapture()` * `Element.releasePointerCapture()` * Pointer Events # Element: id property Baseline Widely available This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015. * Learn more * See full compatibility * Report feedback The `id` property of the `Element` interface represents the element's identifier, reflecting the `id` global attribute. If the `id` value is not the empty string, it must be unique in a document. The `id` is often used with `getElementById()` to retrieve a particular element. Another common case is to use an element's ID as a selector when styling the document with CSS. **Note:** Identifiers are case-sensitive, but you should avoid creating IDs that differ only in the capitalization. ## Value A string. ## Specifications ## Browser compatibility | Desktop | Mobile ---|---|--- | Chrome | Edge | Firefox | Opera | Safari | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet | WebView Android `id` | 231–23Only supported for `HTMLElement`, not all `Element` objects, such as `SVGElement`. | 12 | 1 | ≤12.1 | 1 | 2518–25Only supported for `HTMLElement`, not all `Element` objects, such as `SVGElement`. | 4 | ≤12.1 | 1 | 1.51.0–1.5Only supported for `HTMLElement`, not all `Element` objects, such as `SVGElement`. | 4.4 ## See also * The DOM **id** global attribute. # Element: innerHTML property Baseline Widely available * This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015. * Some parts of this feature may have varying levels of support. * Learn more * See full compatibility * Report feedback The `innerHTML` property of the `Element` interface gets or sets the HTML or XML markup contained within the element. More precisely, `innerHTML` gets a serialization of the nested child DOM elements within the element, or sets HTML or XML that should be parsed to replace the DOM tree within the element. To insert the HTML into the document rather than replace the contents of an element, use the method `insertAdjacentHTML()`. The serialization of the DOM tree read from the property does not include shadow roots — if you want to get a HTML string that includes shadow roots, you must instead use the `Element.getHTML()` or `ShadowRoot.getHTML()` methods. Similarly, when setting element content using `innerHTML`, the HTML string is parsed into DOM elements that do not contain shadow roots. So for example `