diff --git a/files/en-us/mozilla/firefox/releases/101/index.md b/files/en-us/mozilla/firefox/releases/101/index.md index 5628905ec48ca15..16095a1610524e6 100644 --- a/files/en-us/mozilla/firefox/releases/101/index.md +++ b/files/en-us/mozilla/firefox/releases/101/index.md @@ -39,7 +39,7 @@ No notable changes. - [`DOMException`](/en-US/docs/Web/API/DOMException) is now a {{Glossary("serializable object")}}, so it can be cloned with {{domxref("structuredClone()")}} or copied between [workers](/en-US/docs/Web/API/Worker) using {{domxref("Worker.postMessage()", "postMessage()")}} ({{bug(1561357)}}). - _Constructable stylesheets_ are now supported, making it much easier to create reusable stylesheets for use with [Shadow DOM](/en-US/docs/Web/Web_Components/Using_shadow_DOM). - The update includes the addition of a [`CSSStyleSheet()` constructor](/en-US/docs/Web/API/CSSStyleSheet/CSSStyleSheet) for creating new stylesheets, and the {{domxref("CSSStyleSheet.replace()")}} and {{domxref("CSSStyleSheet.replaceSync()")}} methods that can be used to add CSS rules to them. + The update includes the addition of a [`CSSStyleSheet()` constructor](/en-US/docs/Web/API/CSSStyleSheet/CSSStyleSheet) for creating new stylesheets, the {{domxref("CSSStyleSheet.replace()")}} and {{domxref("CSSStyleSheet.replaceSync()")}} methods that can be used to add/replace CSS rules in the sheet, and the [`Document.adoptedStyleSheets`](/en-US/docs/Web/API/Document/adoptedStyleSheets) and [`ShadowRoot.adoptedStyleSheets`](/en-US/docs/Web/API/ShadowRoot/adoptedStyleSheets) properties that are used to share sheets to a document and its shadow DOM subtrees. See {{bug(1520690)}} for more information. #### Media, WebRTC, and Web Audio diff --git a/files/en-us/web/api/cssstylesheet/cssstylesheet/index.md b/files/en-us/web/api/cssstylesheet/cssstylesheet/index.md index 9053f6165b9747d..4a03f9a3187274e 100644 --- a/files/en-us/web/api/cssstylesheet/cssstylesheet/index.md +++ b/files/en-us/web/api/cssstylesheet/cssstylesheet/index.md @@ -13,7 +13,11 @@ browser-compat: api.CSSStyleSheet.CSSStyleSheet The **`CSSStyleSheet()`** constructor creates a new {{domxref("CSSStyleSheet")}} object which represents a single [Stylesheet](/en-US/docs/Glossary/Stylesheet). -After constructing a stylesheet the {{domxref("CSSStyleSheet.replace()")}} or {{domxref("CSSStyleSheet.replaceSync()")}} methods can be used to add rules to the new stylesheet. +After constructing a stylesheet the {{domxref("CSSStyleSheet.replace()")}}, {{domxref("CSSStyleSheet.replaceSync()")}}, {{domxref("CSSStyleSheet.insertRule()")}}, and {{domxref("CSSStyleSheet.deleteRule()")}} methods can be used to modify the rules of the new stylesheet. + +A stylesheet created using this method is referred to as a "constructed stylesheet". +A constructed stylesheet can be shared between a document and its shadow DOM subtrees using {{domxref("ShadowRoot.adoptedStyleSheets")}} and {{domxref("Document.adoptedStyleSheets")}}. + ## Syntax @@ -37,13 +41,47 @@ new CSSStyleSheet(options) ## Examples -In the following example a new {{domxref("CSSStyleSheet")}} is constructed, with a media rule of `"print"`. Printing {{domxref("StyleSheet.media")}} to the console returns a {{domxref("MediaList")}} with a single entry for this print rule. +In the following example, a new {{domxref("CSSStyleSheet")}} is constructed with a media rule of `"print"`. +Printing {{domxref("StyleSheet.media")}} to the console returns a {{domxref("MediaList")}} with a single entry for this print rule. ```css let stylesheet = new CSSStyleSheet({media: 'print'}); console.log(stylesheet.media); ``` +### Sharing stylesheets with a shadow DOM + +The code below shows the sheet being constructed and then {{domxref("CSSStyleSheet.replaceSync()")}} is called to add a rule to the sheet. + +```js +// Create an empty "constructed" stylesheet +const sheet = new CSSStyleSheet(); +// Apply a rule to the sheet +sheet.replaceSync('a { color: red; }'); +``` + +We then create a {{domxref("ShadowRoot")}} and pass the sheet object to the {{domxref("ShadowRoot.adoptedStyleSheets")}} property inside an array. + +```js +// Create an element in the document and then create a shadow root: +const node = document.createElement('div'); +const shadow = node.attachShadow({ mode: 'open' }); + +//Adopt the sheet into the shadow DOM +shadow.adoptedStyleSheets = [sheet]; +``` + +We can modify the stylesheets after they have been added to the array. +Below we append a new rule to the same sheet using {{domxref("CSSStyleSheet.insertRule()")}}. + +```js + sheet.insertRule("* { background-color: blue; }"); + // The document will now have blue background. +``` + +The same sheet can be shared with multiple shadow subtrees in the same document. +For more exmaples see {{domxref("ShadowRoot.adoptedStyleSheets")}}. + ## Specifications {{Specifications}} diff --git a/files/en-us/web/api/cssstylesheet/deleterule/index.md b/files/en-us/web/api/cssstylesheet/deleterule/index.md index e721b88a9841eb7..2887c858987637d 100644 --- a/files/en-us/web/api/cssstylesheet/deleterule/index.md +++ b/files/en-us/web/api/cssstylesheet/deleterule/index.md @@ -60,5 +60,6 @@ This example removes the first rule from the stylesheet `myStyles`. ## See also - [CSS Object Model](/en-US/docs/Web/API/CSS_Object_Model) +- [Constructable Stylesheets](https://web.dev/constructable-stylesheets/) (web.dev) - [Using dynamic styling information](/en-US/docs/Web/API/CSS_Object_Model/Using_dynamic_styling_information) - {{domxref("CSSStyleSheet.insertRule", "insertRule()")}} diff --git a/files/en-us/web/api/cssstylesheet/insertrule/index.md b/files/en-us/web/api/cssstylesheet/insertrule/index.md index 2203fe2a9469e47..b0f7d84fe5b6418 100644 --- a/files/en-us/web/api/cssstylesheet/insertrule/index.md +++ b/files/en-us/web/api/cssstylesheet/insertrule/index.md @@ -199,5 +199,4 @@ instead of {{domxref("CSSStyleSheet.deleteRule","deleteRule()")}} and ## See also - {{domxref("CSSStyleSheet.deleteRule")}} -- [Cross-Browser CSS-rules ordering (CSS1)](https://www-archive.mozilla.org/docs/web-developer/css1technote/css1tojs.html#priority) -- [Quirksmode - CSS](https://www.quirksmode.org/dom/w3c_css.html) +- [Constructable Stylesheets](https://web.dev/constructable-stylesheets/) (web.dev) diff --git a/files/en-us/web/api/cssstylesheet/replace/index.md b/files/en-us/web/api/cssstylesheet/replace/index.md index e3a3d79d41a7a54..7257bb011405f2f 100644 --- a/files/en-us/web/api/cssstylesheet/replace/index.md +++ b/files/en-us/web/api/cssstylesheet/replace/index.md @@ -27,7 +27,7 @@ replace(text) - `text` - : A string containing the style rules to replace the content of the stylesheet. If the string does not contain a parseable list of rules, then the value will be set to an empty string. -> **Note:** If any of the rules passed in `text` are an external stylesheet imported with the {{cssxref("@import")}} rule, those rules will be removed, and a warning printed to the console. + > **Note:** If any of the rules passed in `text` are an external stylesheet imported with the {{cssxref("@import")}} rule, those rules will be removed, and a warning printed to the console. ### Return value diff --git a/files/en-us/web/api/cssstylesheet/replacesync/index.md b/files/en-us/web/api/cssstylesheet/replacesync/index.md index f5386f3e145a0f0..2ac80814b93459f 100644 --- a/files/en-us/web/api/cssstylesheet/replacesync/index.md +++ b/files/en-us/web/api/cssstylesheet/replacesync/index.md @@ -27,11 +27,11 @@ replaceSync(text) - `text` - : A string containing the style rules to replace the content of the stylesheet. If the string does not contain a parseable list of rules, then the value will be set to an empty string. -> **Note:** If any of the rules passed in `text` are an external stylesheet imported with the {{cssxref("@import")}} rule, those rules will be removed, and a warning printed to the console. + > **Note:** If any of the rules passed in `text` are an external stylesheet imported with the {{cssxref("@import")}} rule, those rules will be removed, and a warning printed to the console. ### Return value -Undefined. +None (`undefined`). ### Exceptions diff --git a/files/en-us/web/api/document/adoptedstylesheets/index.md b/files/en-us/web/api/document/adoptedstylesheets/index.md new file mode 100644 index 000000000000000..d5effbf99ae87c6 --- /dev/null +++ b/files/en-us/web/api/document/adoptedstylesheets/index.md @@ -0,0 +1,109 @@ +--- +title: Document.adoptedStyleSheets +slug: Web/API/Document/adoptedStyleSheets +tags: + - API + - Document + - Property + - Reference + - Stylesheets + - adoptedStyleSheets +page-type: web-api-instance-property +browser-compat: api.Document.adoptedStyleSheets +--- +{{APIRef("CSSOM")}} + +The **`adoptedStyleSheets`** property of the {{domxref("Document")}} interface is used for setting an array of constructed stylesheets to be used by the document. + +> **Note:** A constructed stylesheet is a stylesheet created programmatically using the [`CSSStyleSheet()` constructor](/en-US/docs/Web/API/CSSStyleSheet/CSSStyleSheet) (as compared to one created by a user-agent when importing a stylesheet from a script, imported using {{HTMLElement('style')}} and {{CSSXref('@import')}}, or linked to via {{HTMLElement('link')}}). + +The same constructed stylesheets can also be shared with one or more {{domxref("ShadowRoot")}} instances using the [`ShadowRoot.adoptedStyleSheets`](/en-US/docs/Web/API/ShadowRoot/adoptedStyleSheets) property. +Changing an adopted stylesheet will affect all the objects that adopt it. + +Stylesheets in the property are evaluated along with the document's other stylesheets using the [CSS cascade algorithm](/en-US/docs/Web/CSS/Cascade). +Where the resolution of rules considers stylesheet order, `adoptedStyleSheets` are assumed to be ordered after those in [`Document.styleSheets`](/en-US/docs/Web/API/Document/styleSheets). + +Only stylesheets created using the [`CSSStyleSheet()` constructor](/en-US/docs/Web/API/CSSStyleSheet/CSSStyleSheet) within the context of the current {{domxref("Document")}} may be adopted. + + +## Value + +The value is an array of {{domxref("CSSStyleSheet()")}} instances that must have been created using the {{domxref("CSSStyleSheet.CSSStyleSheet()", "CSSStyleSheet()")}} constructor within the context of the same {{domxref("Document")}}. + +If the array needs to be modified, then a new array must be assigned (in-place mutations like `push()` will throw an exception). +Note however that the {{domxref("CSSStyleSheet()")}} instances themselves can be modified, and these changes will apply wherever the stylesheet is adopted. + + +### Exceptions + +- `NotAllowedError` {{domxref("DOMException")}} + - : One of the {{domxref("CSSStyleSheet")}} instances in the array was not created using the [`CSSStyleSheet()` constructor](/en-US/docs/Web/API/CSSStyleSheet/CSSStyleSheet) or was constructed in a different document than the current document, such as one in a frame. + + +## Examples + +### Adopting a stylesheet + +The code below shows a stylesheet being constructed, and then {{domxref("CSSStyleSheet.replaceSync()")}} is called to add a rule to the sheet. +The stylesheet is then added to an array and assigned to the `adoptedStyleSheets` property. + +```js +// Create an empty "constructed" stylesheet +const sheet = new CSSStyleSheet(); +// Apply a rule to the sheet +sheet.replaceSync('a { color: red; }'); + +// Apply the stylesheet to a document +document.adoptedStyleSheets = [sheet]; +``` + +We can append a new rule to the stylesheet using {{domxref("CSSStyleSheet.insertRule()")}}. + +```js + sheet.insertRule("* { background-color: blue; }"); + // The document will now have blue background. +``` + +### Append a new stylesheet + +To append a whole new stylesheet to the `adoptedStyleSheets` property we have to create and assign a new combined array. +This is demonstrated below using spread-syntax: + +```js +const extraSheet = new CSSStyleSheet(); +sheet.replaceSync('p { color: green; }'); + +// Combine the existing sheets and new one +document.adoptedStyleSheets = [...document.adoptedStyleSheets, extraSheet]; +``` + +## Sharing a stylesheet with a shadow DOM + +We can share a stylesheet to a shadow root in a similar way. + +```js +// Create an element in the document and then create a shadow root: +const node = document.createElement('div'); +const shadow = node.attachShadow({ mode: 'open' }); + +//Adopt the same sheet into the shadow DOM +shadow.adoptedStyleSheets = [sheet]; +``` + +## Specifications + +{{Specifications}} + +## Browser compatibility + +{{Compat}} + +## See also + +- [Constructable Stylesheets](https://web.dev/constructable-stylesheets/) (web.dev) +- [Using the Shadow DOM](/en-US/docs/Web/Web_Components/Using_shadow_DOM) +- [`CSSStyleSheet()` constructor](/en-US/docs/Web/API/CSSStyleSheet/CSSStyleSheet) +- {{domxref("CSSStyleSheet.replaceSync()")}} +- {{domxref("CSSStyleSheet.replace()")}} +- {{domxref("CSSStyleSheet.insertRule()")}} +- {{domxref("CSSStyleSheet.deleteRule()")}} diff --git a/files/en-us/web/api/document/index.md b/files/en-us/web/api/document/index.md index 1802f445807c947..a82201ea7344048 100644 --- a/files/en-us/web/api/document/index.md +++ b/files/en-us/web/api/document/index.md @@ -31,6 +31,9 @@ _This interface also inherits from the {{DOMxRef("Node")}} and {{DOMxRef("EventT - {{DOMxRef("Document.activeElement")}} {{ReadOnlyInline}} - : Returns the {{DOMxRef('Element')}} that currently has focus. +- {{DOMxRef("Document.adoptedStyleSheets")}} + - : Add an array of constructed stylesheets to be used by the document. + These stylesheets may also be shared with shadow DOM subtrees of the same document. - {{DOMxRef("Document.body")}} - : Returns the {{HTMLElement("body")}} or {{htmlelement("frameset")}} node of the current document. - {{DOMxRef("Document.characterSet")}}{{ReadOnlyInline}} diff --git a/files/en-us/web/api/shadowroot/adoptedstylesheets/index.md b/files/en-us/web/api/shadowroot/adoptedstylesheets/index.md new file mode 100644 index 000000000000000..724511216b45cdb --- /dev/null +++ b/files/en-us/web/api/shadowroot/adoptedstylesheets/index.md @@ -0,0 +1,97 @@ +--- +title: ShadowRoot.adoptedStyleSheets +slug: Web/API/ShadowRoot/adoptedStyleSheets +tags: + - API + - ShadowRoot + - Property + - Reference + - Stylesheets + - adoptedStyleSheets +page-type: web-api-instance-property +browser-compat: api.ShadowRoot.adoptedStyleSheets +--- +{{APIRef("CSSOM")}} + +The **`adoptedStyleSheets`** property of the {{domxref("ShadowRoot")}} interface sets an array of constructed stylesheets to be used by the shadow DOM subtree. + +> **Note:** A constructed stylesheet is a stylesheet created programmatically using the [`CSSStyleSheet()` constructor](/en-US/docs/Web/API/CSSStyleSheet/CSSStyleSheet) (as compared to one created by a user-agent when importing a stylesheet from a script, imported using {{HTMLElement('style')}} and {{CSSXref('@import')}}, or linked to via {{HTMLElement('link')}}). + +The same constructed stylesheet can be adopted by multiple {{domxref("ShadowRoot")}} instances, and by the parent document (using the {{domxref("Document.adoptedStyleSheets")}} property). +Changing an adopted stylesheet will affect all the adopting objects. + +Stylesheets in the `adoptedStyleSheets` property are considered along with the shadow DOM's other stylesheets. +For the purpose of determining the final computed CSS of any element, they are considered to have been added _after_ the other stylesheets in the shadow DOM ([`ShadowRoot.styleSheets`](/en-US/docs/Web/API/Document/styleSheets)). + +Only stylesheets created using the [`CSSStyleSheet()` constructor](/en-US/docs/Web/API/CSSStyleSheet/CSSStyleSheet), and from within the same parent {{domxref("Document")}} as the shadow root, may be adopted. + + +## Value + +The value is an array of {{domxref("CSSStyleSheet()")}} instances that must have been created using the {{domxref("CSSStyleSheet.CSSStyleSheet()", "CSSStyleSheet()")}} constructor within the context of the shadow root's parent {{domxref("Document")}}. + +If the array needs to be modified, then a new array must be assigned (in-place mutations like `push()` will throw an exception). +Note, however, that the {{domxref("CSSStyleSheet()")}} instances themselves can be modified, and these changes will apply wherever the stylesheet is adopted. + +## Examples + +### Adopting a stylesheet + +The code below first shows a stylesheet being constructed, and then {{domxref("CSSStyleSheet.replaceSync()")}} is called to add a rule to the sheet. + +```js +// Create an empty "constructed" stylesheet +const sheet = new CSSStyleSheet(); +// Apply a rule to the sheet +sheet.replaceSync('a { color: red; }'); +``` + +We then create a {{domxref("ShadowRoot")}} and pass the sheet object to `adoptedStyleSheets` inside an array. + +```js +// Create an element in the document and then create a shadow root: +const node = document.createElement('div'); +const shadow = node.attachShadow({ mode: 'open' }); + +//Adopt the sheet into the shadow DOM +shadow.adoptedStyleSheets = [sheet]; +``` + +We can still modify the stylesheets after they have been added to the array. +Below we append a new rule to the same sheet using {{domxref("CSSStyleSheet.insertRule()")}}. + +```js + sheet.insertRule("* { background-color: blue; }"); + // The document will now have blue background. +``` + +### Append a new stylesheet + +To _append_ a stylesheet to the `adoptedStyleSheets` property we have to create and assign a new array that contains both the original stylesheets in the property and the new style sheet. +This is demonstrated for our shadow root object below using spread-syntax: + +```js +const extraSheet = new CSSStyleSheet(); +sheet.replaceSync('p { color: green; }'); + +// Combine the existing sheets and new one +shadow.adoptedStyleSheets = [...document.adoptedStyleSheets, extraSheet]; +``` + +## Specifications + +{{Specifications}} + +## Browser compatibility + +{{Compat}} + +## See also + +- [Constructable Stylesheets](https://web.dev/constructable-stylesheets/) (web.dev) +- [Using the Shadow DOM](/en-US/docs/Web/Web_Components/Using_shadow_DOM) +- [`CSSStyleSheet()` constructor](/en-US/docs/Web/API/CSSStyleSheet/CSSStyleSheet) +- {{domxref("CSSStyleSheet.replaceSync()")}} +- {{domxref("CSSStyleSheet.replace()")}} +- {{domxref("CSSStyleSheet.insertRule()")}} +- {{domxref("CSSStyleSheet.deleteRule()")}} diff --git a/files/en-us/web/api/shadowroot/index.md b/files/en-us/web/api/shadowroot/index.md index 224a3ab374a7df1..8ee046675df0814 100644 --- a/files/en-us/web/api/shadowroot/index.md +++ b/files/en-us/web/api/shadowroot/index.md @@ -23,6 +23,9 @@ You can retrieve a reference to an element's shadow root using its {{domxref("El - {{domxref("ShadowRoot.activeElement")}} {{readonlyInline}} - : Returns the {{domxref('Element')}} within the shadow tree that has focus. +- {{domxref("ShadowRoot.adoptedStyleSheets")}} + - : Add an array of constructed stylesheets to be used by the shadow DOM subtree. + These may be shared with other DOM subtrees that share the same parent {{domxref("Document")}} node, and the document itself. - {{domxref("ShadowRoot.delegatesFocus")}} {{readonlyinline}} {{non-standard_inline}} {{deprecated_inline}} - : Returns a boolean that indicates whether `delegatesFocus` was set when the shadow was attached (see {{domxref("Element.attachShadow()")}}). - {{DOMxRef("ShadowRoot.fullscreenElement")}} {{ReadOnlyInline}}