diff --git a/files/en-us/web/api/csscontainerrule/conditions/index.md b/files/en-us/web/api/csscontainerrule/conditions/index.md new file mode 100644 index 000000000000000..768c20ed023360a --- /dev/null +++ b/files/en-us/web/api/csscontainerrule/conditions/index.md @@ -0,0 +1,167 @@ +--- +title: "CSSContainerRule: conditions property" +short-title: conditions +slug: Web/API/CSSContainerRule/conditions +page-type: web-api-instance-property +browser-compat: api.CSSContainerRule.conditions +--- + +{{ APIRef("CSSOM") }} + +The read-only **`conditions`** property of the {{domxref("CSSContainerRule")}} interface represents an associated CSS {{cssxref("@container")}} at-rule as an array of objects, where each object represents a single container condition. + +## Value + +An array of objects where each object has the form: + +```js +{ name: "", query: "" }; +``` + +Either the `name` or `query` may be the empty string, but not both. + +## Description + +The **`conditions`** property represents an associated CSS {{cssxref("@container")}} at-rule as an array of objects. + +Each object represents a container condition as a `name` string property and a `query` string property, either of which may be the empty string if not defined. +The `name` represents the name of a container, and the `query` string represents the set of feature tests that must be true for the particular container condition to match. + +For example, given the following {{cssxref("@container")}}: + +```css +@container sidebar (width >= 700px), (height >= 400px) { + /* Styles */ +} +``` + +The `conditions` would be an array like this: + +```js +[ + { name: "sidebar", query: "(width >= 700px)" }, + { name: "", query: "(height >= 400px)" }, +]; +``` + +## Examples + +See also [Examples](/en-US/docs/Web/API/CSSContainerRule#examples) in `CSSContainerRule`. + +### Basic usage + +The example shows how multiple container conditions are represented in the `conditions` property. + +Note that we've hidden the logging code, as it is not relevant. + +```html hidden +

+```
+
+```js hidden
+const logElement = document.querySelector("#log");
+function log(text) {
+  logElement.innerText = `${logElement.innerText}${text}\n`;
+  logElement.scrollTop = logElement.scrollHeight;
+}
+```
+
+```css hidden
+#log {
+  height: 100px;
+  overflow: scroll;
+  padding: 0.5rem;
+  border: 1px solid black;
+}
+```
+
+#### HTML
+
+First, we define the HTML for a `card` contained within a `post`.
+These are represented by two nested {{htmlelement("div")}} elements.
+
+```html
+
+
+

Card title

+

Card content

+
+
+``` + +#### CSS + +The CSS for the container element specifies the type of the container, and may also specify a name. +The card has a default font size, which is overridden when it is contained inside a `sidebar` `@container` when its width is greater than or equal to `700px`, or when it is inside a container named `other-name`. +Note that this condition is contrived to demonstrate how multiple conditions are represented (`other-name` doesn't actually do anything). + +```html + +``` + +#### JavaScript + +The code below gets the {{domxref("HTMLStyleElement")}} associated with the example using its `id`, and then uses its `sheet` property to get the {{domxref("StyleSheet")}}. +From the `StyleSheet` we get the set of `cssRules` added to the sheet. +Since we added the `@container` as the third rule above, we can access the associated `CSSContainerRule` using the third entry (index "2") in the `cssRules`. + +```js +const exampleStylesheet = document.getElementById("example-styles").sheet; +const exampleRules = exampleStylesheet.cssRules; +const containerRule = exampleRules[2]; // a CSSContainerRule representing the container rule. +``` + +We then use the `containerRule` to log the value of the `conditions` property. + +```js +if ("conditions" in CSSContainerRule.prototype) { + log("CSSContainerRule.conditions:"); + containerRule.conditions.forEach((item) => { + const jsonString = JSON.stringify(item); + log(` ${jsonString}`); + }); +} else { + log("CSSContainerRule.conditions is not supported."); +} +``` + +> [!NOTE] +> On browsers that don't support `conditions`, you may be able to use {{domxref("CSSContainerRule.containerName")}} and {{domxref("CSSContainerRule.containerQuery")}}, provided that the `@container` only specifies one container condition. +> For more information, see the [Feature testing](/en-US/docs/Web/API/CSSContainerRule#feature_testing) example in `CSSContainerRule`. + +#### Results + +The example output is shown below. + +{{EmbedLiveSample("Basic usage","100%","300px")}} + +## Specifications + +{{Specifications}} + +## Browser compatibility + +{{Compat}} + +## See also + +- CSS {{cssxref("container")}} shorthand property +- [CSS containment module](/en-US/docs/Web/CSS/Guides/Containment) +- [Container queries](/en-US/docs/Web/CSS/Guides/Containment/Container_queries) +- [Using container size and style queries](/en-US/docs/Web/CSS/Guides/Containment/Container_size_and_style_queries) diff --git a/files/en-us/web/api/csscontainerrule/containername/index.md b/files/en-us/web/api/csscontainerrule/containername/index.md index a1fa0d8023c2c5b..d47ec4ba72f3ce5 100644 --- a/files/en-us/web/api/csscontainerrule/containername/index.md +++ b/files/en-us/web/api/csscontainerrule/containername/index.md @@ -8,48 +8,63 @@ browser-compat: api.CSSContainerRule.containerName {{ APIRef("CSSOM") }} -The read-only **`containerName`** property of the {{domxref("CSSContainerRule")}} interface represents the container name of the associated CSS {{cssxref("@container")}} at-rule. +The read-only **`containerName`** property of the {{domxref("CSSContainerRule")}} interface represents the name of the container condition for a container rule that only defines one container condition. +If there are multiple container conditions, the value is set to the empty string. + +## Value + +A string that contains the name of the container condition defined in a container rule, but only if it has just one container condition defined. + +If no name is defined, or if the rule defines multiple container conditions, this is the empty string (`""`). + +## Description + +This property reflects the value of the name part of the container condition in a corresponding {{cssxref("@container")}} at-rule that has just one container condition. For example, the value of `containerName` for the {{cssxref("@container")}} below is `sidebar`: ```css @container sidebar (width >= 700px) { - .card { - font-size: 2em; - } + /* Styles */ } ``` -## Value - -A string that contains the {{cssxref("container-name")}} of the {{cssxref("@container")}} associated with this {{domxref("CSSContainerRule")}}. -If the `@container` is not [named](/en-US/docs/Web/API/CSSContainerRule#unnamed_container_rule), the function returns the empty string (`""`). +> [!NOTE] +> The `containerName` value has been superseded by {{domxref("CSSContainerRule.conditions")}}, which should be used in supporting browsers. +> Browsers that do not support `conditions` cannot parse `@container` definitions with multiple container conditions. ## Examples -The example below defines a named {{cssxref("@container")}} rule, and displays the properties of the associated {{domxref("CSSContainerRule")}}. +### Basic usage + +The example below defines a {{cssxref("@container")}} rule with a single container condition, and displays the properties of the associated {{domxref("CSSContainerRule")}}. The CSS is very similar to that in the `@container` example [Creating named container contexts](/en-US/docs/Web/CSS/Reference/At-rules/@container#creating_named_container_contexts). ```html hidden -
-

Log

-
    -
    -
    +
    
     ```
     
     ```js hidden
    -// Store reference to log list
    -const logList = document.querySelector("#log ul");
    -// Function to log data from underlying source
    -function log(result) {
    -  const listItem = document.createElement("li");
    -  listItem.textContent = result;
    -  logList.appendChild(listItem);
    +const logElement = document.querySelector("#log");
    +function log(text) {
    +  logElement.innerText = `${logElement.innerText}${text}\n`;
    +  logElement.scrollTop = logElement.scrollHeight;
     }
     ```
     
    -First we define the HTML for a `card` (`
    `) contained within a `post`. +```css hidden +#log { + height: 100px; + overflow: scroll; + padding: 0.5rem; + border: 1px solid black; +} +``` + +#### HTML + +First, we define the HTML for a `card` contained within a `post`. +These are represented by two nested {{htmlelement("div")}} elements. ```html
    @@ -60,8 +75,10 @@ First we define the HTML for a `card` (`
    `) contained within a `post`.
    ``` -The CSS for the container element specifies the type of the container, and may also specify a name. -The card has a default font size, which is overridden for the `@container` named `sidebar` if the width is greater than 700px. +#### CSS + +The CSS for the container element specifies the type of the container along with a name. +The card has a default font size, which is overridden for the `@container` named `sidebar` if its `width` is greater than or equal to `700px`. ```html ``` +#### JavaScript + The code below gets the {{domxref("HTMLStyleElement")}} associated with the example using its `id`, and then uses its `sheet` property to get the {{domxref("StyleSheet")}}. From the `StyleSheet` we get the set of `cssRules` added to the sheet. -Since we added the `@container` as the third rule above, we can access the associated `CSSContainerRule` using the third entry (index "2"), in the `cssRules`. -Last of all, we log the container name and query properties (the code that does the logging is not shown). +Since we added the `@container` as the third rule above, we can access the associated `CSSContainerRule` using the third entry (index "2") in the `cssRules`. ```js const exampleStylesheet = document.getElementById("example-styles").sheet; const exampleRules = exampleStylesheet.cssRules; const containerRule = exampleRules[2]; // a CSSContainerRule representing the container rule. +``` + +We then use `containerRule` to log the name of the first container condition. +If the browser supports `CSSContainerRule.conditions`, we show the name and query from that as well. + +```js log(`CSSContainerRule.containerName: "${containerRule.containerName}"`); + +if ("conditions" in CSSContainerRule.prototype) { + log("CSSContainerRule.conditions:"); + containerRule.conditions.forEach((item) => { + const jsonString = JSON.stringify(item); + log(` ${jsonString}`); + }); +} +``` + +#### Results + +The example output is shown below. +The log section lists the name of the only container condition using `containerName`. +It also shows the name and query using the `conditions` property, if supported. + +{{EmbedLiveSample("Basic usage","100%","300px")}} + +Note that the text in the card `
    ` should double in size as the container `width` reaches `700px`, and will halve again as the `width` goes back down below `700px`. + +### Multiple container conditions + +The example below is almost exactly the same as the previous example except that the CSS specifies multiple container conditions. + +Note that we've hidden the HTML because it is the same as in the previous example. + +```html hidden +
    
    +```
    +
    +```js hidden
    +const logElement = document.querySelector("#log");
    +function log(text) {
    +  logElement.innerText = `${logElement.innerText}${text}\n`;
    +  logElement.scrollTop = logElement.scrollHeight;
    +}
    +```
    +
    +```css hidden
    +#log {
    +  height: 100px;
    +  overflow: scroll;
    +  padding: 0.5rem;
    +  border: 1px solid black;
    +}
    +```
    +
    +```html hidden
    +
    +
    +

    Card title

    +

    Card content

    +
    +
    ``` +#### CSS + +The card has a default font size, which is overridden for the `@container` named `sidebar` if its `width` is greater than `700px` or if the container has the name `other-name`. +Note that this condition is contrived to demonstrate the effect of multiple conditions (it does not affect the behavior of the example). + +```html + +``` + +#### JavaScript + +The code below gets the {{domxref("HTMLStyleElement")}} associated with the example using its `id`, and then uses its `sheet` property to get the {{domxref("StyleSheet")}}. +From the `StyleSheet` we get the set of `cssRules` added to the sheet. +Since we added the `@container` as the third rule above, we can access the associated `CSSContainerRule` using the third entry (index "2") in the `cssRules`. + +```js +const exampleStylesheet = document.getElementById("example-styles").sheet; +const exampleRules = exampleStylesheet.cssRules; +const containerRule = exampleRules[2]; // a CSSContainerRule representing the container rule. +``` + +The code is slightly different from the previous case because if multiple container conditions are not supported by the browser, the `containerRule` will be `undefined`. +We therefore only log the value of `containerName` if the browser supports multiple container conditions — it will be the empty string. + +```js +if (!containerRule) { + // Browser doesn't support multiple container conditions + log( + "No CSSContainerRule was created. This browser doesn't support @container with multiple conditions.", + ); +} else { + log(`CSSContainerRule.containerName: "${containerRule.containerName}"`); +} + +if ("conditions" in CSSContainerRule.prototype) { + log("CSSContainerRule.conditions:"); + containerRule.conditions.forEach((item) => { + const jsonString = JSON.stringify(item); + log(` ${jsonString}`); + }); +} +``` + +See [Feature testing](/en-US/docs/Web/API/CSSContainerRule#feature_testing) in `CSSContainerRule` for more information/examples. + +#### Results + The example output is shown below. -The log section lists the container name string. -The title in the card section should double in size as the width of the page goes over 700px. +Note that the rule doesn't exist at all if the browser doesn't support multiple container conditions. +If it does, then the value of `containerName` is the empty string. -{{EmbedLiveSample("Examples","100%","250px")}} +{{EmbedLiveSample("Multiple container conditions","100%","250px")}} ## Specifications diff --git a/files/en-us/web/api/csscontainerrule/containerquery/index.md b/files/en-us/web/api/csscontainerrule/containerquery/index.md index 5d95d54c3b2aa93..adee464c89ce3d2 100644 --- a/files/en-us/web/api/csscontainerrule/containerquery/index.md +++ b/files/en-us/web/api/csscontainerrule/containerquery/index.md @@ -8,49 +8,64 @@ browser-compat: api.CSSContainerRule.containerQuery {{ APIRef("CSSOM") }} -The read-only **`containerQuery`** property of the {{domxref("CSSContainerRule")}} interface returns a string representing the container conditions that are evaluated when the container changes size in order to determine if the styles in the associated {{cssxref("@container")}} are applied. +The read-only **`containerQuery`** property of the {{domxref("CSSContainerRule")}} interface represents the query part of the container condition for a container rule that only defines one container condition. +If there are multiple container conditions, the value is set to the empty string. + +## Value + +A string that contains the query part of the container condition defined in a container rule, but only if it has just one container condition defined. +Note that the value may not be identical to the original string, as normalizations such as removing whitespace may happen. + +If no query is defined, or if the rule defines multiple container conditions, this is the empty string (`""`). + +## Description + +This property reflects the value of the query part of the container condition in a corresponding {{cssxref("@container")}} at-rule that has just one container condition. For example, the value of `containerQuery` for the {{cssxref("@container")}} below is `(width >= 700px)`: ```css @container sidebar (width >= 700px) { - .card { - font-size: 2em; - } + /* Styles */ } ``` -## Value - -A string containing the container query. - -Note that the value may not be identical to the original string, as normalizations such as removing whitespace may happen. +> [!NOTE] +> The `containerQuery` value has been superseded by {{domxref("CSSContainerRule.conditions")}}, which should be used in supporting browsers. +> Browsers that do not support `conditions` cannot parse `@container` definitions with multiple container conditions. ## Examples -The example below defines an unnamed {{cssxref("@container")}} rule, and displays the properties of the associated {{domxref("CSSContainerRule")}}. -The CSS is the same as in the `@container` example [Setting styles based on a container's size](/en-US/docs/Web/CSS/Reference/At-rules/@container#setting_styles_based_on_a_containers_size). +### Basic usage + +The example below defines a {{cssxref("@container")}} rule with a single container condition, and displays the properties of the associated {{domxref("CSSContainerRule")}}. +The CSS is very similar to that in the `@container` example [Creating named container contexts](/en-US/docs/Web/CSS/Reference/At-rules/@container#creating_named_container_contexts). ```html hidden -
    -

    Log

    -
      -
      -
      +
      
       ```
       
       ```js hidden
      -// Store reference to log list
      -const logList = document.querySelector("#log ul");
      -// Function to log data from underlying source
      -function log(result) {
      -  const listItem = document.createElement("li");
      -  listItem.textContent = result;
      -  logList.appendChild(listItem);
      +const logElement = document.querySelector("#log");
      +function log(text) {
      +  logElement.innerText = `${logElement.innerText}${text}\n`;
      +  logElement.scrollTop = logElement.scrollHeight;
      +}
      +```
      +
      +```css hidden
      +#log {
      +  height: 100px;
      +  overflow: scroll;
      +  padding: 0.5rem;
      +  border: 1px solid black;
       }
       ```
       
      -First we define the HTML for a `card` (`
      `) contained within a `post`. +#### HTML + +First, we define the HTML for a `card` contained within a `post`. +These are represented by two nested {{htmlelement("div")}} elements. ```html
      @@ -61,44 +76,172 @@ First we define the HTML for a `card` (`
      `) contained within a `post`.
      ``` -The CSS for the container element specifies the type of the container. -The {{cssxref("@container")}} then applies a new width, font-size and background color to the contained element "card" if the width is less than 650px. +#### CSS + +The CSS for the container element specifies the type of the container along with a name. +The card has a default font size, which is overridden for the `@container` named `sidebar` if its width is greater than or equal to `700px`. ```html ``` -The code below gets the {{domxref("HTMLStyleElement")}} associated with the example using its id, and then uses its `sheet` property to get the {{domxref("StyleSheet")}}. +#### JavaScript + +The code below gets the {{domxref("HTMLStyleElement")}} associated with the example using its `id`, and then uses its `sheet` property to get the {{domxref("StyleSheet")}}. From the `StyleSheet` we get the set of `cssRules` added to the sheet. -Since we added the `@container` as the second rule above, we can access the associated `CSSContainerRule` using the second entry (with index "1"), in the `cssRules`. -Last of all, we log the container name and query properties. +Since we added the `@container` as the third rule above, we can access the associated `CSSContainerRule` using the third entry (index "2") in the `cssRules`. ```js const exampleStylesheet = document.getElementById("example-styles").sheet; const exampleRules = exampleStylesheet.cssRules; -const containerRule = exampleRules[1]; // a CSSContainerRule representing the container rule. +const containerRule = exampleRules[2]; // a CSSContainerRule representing the container rule. +``` + +We then use `containerRule` to log the query of the container condition. +If `CSSContainerRule.conditions` is supported in the browser, we show the name and query from that as well. + +```js log(`CSSContainerRule.containerQuery: "${containerRule.containerQuery}"`); + +if ("conditions" in CSSContainerRule.prototype) { + log("CSSContainerRule.conditions:"); + containerRule.conditions.forEach((item) => { + const jsonString = JSON.stringify(item); + log(` ${jsonString}`); + }); +} +``` + +#### Results + +The example output is shown below. +The log section lists the query of the only container condition using `containerQuery`. +It also shows the name and query using the `conditions` property, if supported. + +{{EmbedLiveSample("Basic usage","100%","320px")}} + +The text in the card `
      ` should double in size as the page width reaches `700px`, and halve as it goes below `700px` again. + +### Multiple container conditions + +The example below is almost exactly the same as the previous example except that the CSS specifies multiple container conditions. + +Note that we've hidden the HTML because it is the same as in the previous example. + +```html hidden +
      
      +```
      +
      +```js hidden
      +const logElement = document.querySelector("#log");
      +function log(text) {
      +  logElement.innerText = `${logElement.innerText}${text}\n`;
      +  logElement.scrollTop = logElement.scrollHeight;
      +}
      +```
      +
      +```css hidden
      +#log {
      +  height: 100px;
      +  overflow: scroll;
      +  padding: 0.5rem;
      +  border: 1px solid black;
      +}
      +```
      +
      +```html hidden
      +
      +
      +

      Card title

      +

      Card content

      +
      +
      +``` + +#### CSS + +The card has a default font size, which is overridden for the `@container` named `sidebar` if its width is greater than or equal to `700px` or if the container has the name `other-name`. +Note that this condition is contrived to demonstrate the effect of multiple conditions (it does not affect the behavior of the example). + +```html + +``` + +#### JavaScript + +The code below gets the {{domxref("HTMLStyleElement")}} associated with the example using its `id`, and then uses its `sheet` property to get the {{domxref("StyleSheet")}}. +From the `StyleSheet` we get the set of `cssRules` added to the sheet. +Since we added the `@container` as the third rule above, we can access the associated `CSSContainerRule` using the third entry (index "2") in the `cssRules`. + +```js +const exampleStylesheet = document.getElementById("example-styles").sheet; +const exampleRules = exampleStylesheet.cssRules; +const containerRule = exampleRules[2]; // a CSSContainerRule representing the container rule. ``` +The code is slightly different from the previous case because if multiple container conditions are not supported by the browser, the `containerRule` will be `undefined`. +We therefore only log the value of `containerQuery` if the browser supports multiple container conditions — it will be the empty string. + +```js +if (!containerRule) { + // Browser doesn't support multiple container conditions + log( + "No CSSContainerRule was created. This browser doesn't support @container with multiple conditions.", + ); +} else { + log(`CSSContainerRule.containerQuery: "${containerRule.containerQuery}"`); +} + +if ("conditions" in CSSContainerRule.prototype) { + log("CSSContainerRule.conditions:"); + containerRule.conditions.forEach((item) => { + const jsonString = JSON.stringify(item); + log(` ${jsonString}`); + }); +} +``` + +See [Feature testing](/en-US/docs/Web/API/CSSContainerRule#feature_testing) in `CSSContainerRule` for more information/examples. + +#### Results + The example output is shown below. -The log section lists the query string. -The card should change background and as the width of the page transitions through 650px. +Note that the rule doesn't exist at all if the browser doesn't support multiple container conditions. +If it does, then the value of `containerQuery` is the empty string. -{{EmbedLiveSample("Examples","100%","250px")}} +{{EmbedLiveSample("Multiple container conditions","100%","250px")}} ## Specifications @@ -110,6 +253,7 @@ The card should change background and as the width of the page transitions throu ## See also +- CSS {{cssxref("container")}} shorthand property - [CSS containment module](/en-US/docs/Web/CSS/Guides/Containment) - [Container queries](/en-US/docs/Web/CSS/Guides/Containment/Container_queries) - [Using container size and style queries](/en-US/docs/Web/CSS/Guides/Containment/Container_size_and_style_queries) diff --git a/files/en-us/web/api/csscontainerrule/index.md b/files/en-us/web/api/csscontainerrule/index.md index 273527b9d1e1adb..0921a8404e813be 100644 --- a/files/en-us/web/api/csscontainerrule/index.md +++ b/files/en-us/web/api/csscontainerrule/index.md @@ -9,53 +9,138 @@ browser-compat: api.CSSContainerRule The **`CSSContainerRule`** interface represents a single CSS {{cssxref("@container")}} rule. -An object of this type can be used to get the query conditions for the {{cssxref("@container")}}, along with the container name if one is defined. -Note that the container name and query together define the "condition text", which can be obtained using {{domxref("CSSConditionRule.conditionText")}}. - {{InheritanceDiagram}} ## Instance properties _Inherits properties from its ancestors {{domxref("CSSConditionRule")}}, {{domxref("CSSGroupingRule")}}, and {{domxref("CSSRule")}}._ +- {{domxref("CSSContainerRule.conditions")}} {{ReadOnlyInline}} + - : Returns an array of objects, each of which specifies a container condition in a {{cssxref("@container")}} rule. + The objects have a `name` string property and a `query` string property, either of which may be the empty string if not defined. + The `name` represents the name of a container, and the `query` represents the set of feature tests that must be true for the particular condition to apply. - {{domxref("CSSContainerRule.containerName")}} {{ReadOnlyInline}} - - : Returns a string representing the name of an {{cssxref("@container")}}, or an empty string. + - : Returns a string representing the name of the container condition of a {{cssxref("@container")}}, when there is just one condition. + If there are multiple container conditions, or if there is just one condition that does not specify a name, this is the empty string. - {{domxref("CSSContainerRule.containerQuery")}} {{ReadOnlyInline}} - - : Returns a string representing the set of features or "container conditions" that are evaluated to determine if the styles in the associated {{cssxref("@container")}} are applied. + - : Returns a string representing the container query for the container condition of a {{cssxref("@container")}}, when there is only one condition. + This represents a set of feature tests that must all be true for the condition to apply. + If there are multiple container conditions, or if there is just one condition that does not specify a query, this is the empty string. ## Instance methods _No specific methods; inherits methods from its ancestors {{domxref("CSSConditionRule")}}, {{domxref("CSSGroupingRule")}}, and {{domxref("CSSRule")}}._ +## Description + +A `CSSContainerRule` object represents a {{cssxref("@container")}} rule. + +A `@container` rule defines one or more comma-separated _container conditions_. +Each container condition consists of a "name" and/or a "query", where the "name" indicates the name of the container to which the condition applies and the "query" specifies one or more logically combined feature checks on a container's properties. +If any of the container conditions match a container, the indicated styles are applied. + +> [!NOTE] +> Support for multiple container conditions is indicated by the `conditions` key in the [Browser compatibility](#browser_compatibility) table (earlier versions of the specification allowed only a single container condition). +> This affects how `CSSContainerRule` and `@container` are used. + +A contrived example consisting of three conditions is shown below. +This will match a container named `main-content` if its width is between `600px` and `800px`, any container that has a height greater than `800px`, or any container named `other-content`. + +```css +@container main-content (width > 600px) and (width < 800px), (height > 800px), other-content { + /* Apply styles */ +} +``` + +In supporting browsers, the `CSSContainerRule.conditions` property represents a `@container` as an array of objects, each of which defines a single container condition. +The objects have the properties `name` and `query`, which may be the empty string (`""`). +The `conditions` property for the `@container` example above would look like this: + +```js +[ + { name: "main-content", query: "(width > 600px) and (width < 800px)" }, + { name: "", query: "(height > 800px)" }, + { name: "other-content", query: "" }, +]; +``` + +The `containerName` and `containerQuery` properties predate support for container rules with multiple container conditions. +For a container rule with a _single container condition_ they contain the name and query of that condition (mirroring the `name` and `query` properties of the object in the `conditions` array). +For a container rule with multiple conditions they are both set to the empty string. + +Note that browsers that don't support the `conditions` property only allow container rules with a single container condition. +An `@container` with multiple container conditions will not be parsed, and no corresponding `CSSContainerRule` will be created. + +You can also get the text for the whole condition using {{domxref("CSSConditionRule.conditionText")}}. + ## Examples -### Unnamed container rule +### Feature testing + +Feature testing can be complicated because you may need to handle cases where `CSSContainerRule` or `CSSContainerRule.conditions` are not supported, and also the particular case where `conditions` is not supported but multiple container conditions have been specified in the CSS. + +This code shows how you can do it, assuming that you have already obtained `containerRule`, a `CSSContainerRule` instance that corresponds to an {{cssxref("@container")}} rule defined in the page CSS (the next example shows how you might get `containerRule`). + +```js +if (typeof CSSContainerRule === "undefined") { + // Browser doesn't support CSSContainerRule (at all) + log("CSSContainerRule is not supported in this browser."); +} else if (!containerRule) { + // Browser doesn't support multiple container conditions + log( + "No CSSContainerRule was created — @container with multiple conditions may not be parsed.", + ); +} else if ("conditions" in CSSContainerRule.prototype) { + log("CSSContainerRule.conditions is supported."); + log("CSSContainerRule.conditions:"); + containerRule.conditions.forEach((item) => { + const jsonString = JSON.stringify(item); + log(` ${jsonString}`); + }); + log(`CSSContainerRule.conditionText: "${containerRule.conditionText}"`); +} else { + // @container exists but predates the multi-condition specification + log("CSSContainerRule.conditions not supported"); + log(`CSSContainerRule.containerName: "${containerRule.containerName}"`); + log(`CSSContainerRule.containerQuery: "${containerRule.containerQuery}"`); + log(`CSSContainerRule.conditionText: "${containerRule.conditionText}"`); +} +``` + +Note that if it is defined, we prefer to use the information in `CSSContainerRule.conditions` rather than `containerName` and `containerQuery`. -The example below defines an unnamed {{cssxref("@container")}} rule, and displays the properties of the associated `CSSContainerRule`. +### Unnamed container condition + +The example below defines a {{cssxref("@container")}} rule that has a single container condition with no name, and displays the properties of the associated `CSSContainerRule`. The CSS is the same as in the `@container` example [Setting styles based on a container's size](/en-US/docs/Web/CSS/Reference/At-rules/@container#setting_styles_based_on_a_containers_size). -The first part of the code simply creates a list for logging the container rule properties, along with a JavaScript `log()` method to simplify adding the properties. +Note that our code to log the results is not particularly relevant, so it has been hidden. -```html -
      -

      Log

      -
        -
        -
        +```html hidden +
        
         ```
         
        -```js
        -// Store reference to log list
        -const logList = document.querySelector("#log ul");
        -// Function to log data from underlying source
        -function log(result) {
        -  const listItem = document.createElement("li");
        -  listItem.textContent = result;
        -  logList.appendChild(listItem);
        +```js hidden
        +const logElement = document.querySelector("#log");
        +function log(text) {
        +  logElement.innerText = `${logElement.innerText}${text}\n`;
        +  logElement.scrollTop = logElement.scrollHeight;
        +}
        +```
        +
        +```css hidden
        +#log {
        +  height: 100px;
        +  overflow: scroll;
        +  padding: 0.5rem;
        +  border: 1px solid black;
         }
         ```
         
        -Then we define the HTML for a `card` (`
        `) contained within a `post`. +#### HTML + +First, we define the HTML for a `card` contained within a `post`. +These are represented by two nested {{htmlelement("div")}} elements. ```html
        @@ -66,9 +151,11 @@ Then we define the HTML for a `card` (`
        `) contained within a `post`.
        ``` +#### CSS + The CSS for the example is shown below. -As described in the corresponding {{cssxref("@container")}} example, the CSS for the container element specifies the type of the container. -The {{cssxref("@container")}} then applies a new width, font-size and background color to the card if the width is less than 650px. +The CSS first specifies the {{cssxref("container-type")}} for the container element (`post`). +The `@container` rule then applies a new `width`, `background-color`, and `font-size` to the card if the width is less than `650px`. ```html ``` -The code below gets the {{domxref("HTMLStyleElement")}} associated with the example using its id, and then uses its `sheet` property to get the {{domxref("StyleSheet")}}. +> [!NOTE] +> The styles in these examples are defined in an inline HTML {{htmlelement("style")}} element with an `id`, to make it easy for the code to find the correct style sheet. +> You might also locate the correct style sheet for each example by indexing against the number of style sheets contained in the document, that is, the `length` of the `styleSheets` property (for example, `document.styleSheets[document.styleSheets.length-1]`), but that makes working out the correct sheet for each example more complicated. + +#### JavaScript + +The code below gets the {{domxref("HTMLStyleElement")}} associated with the example using its `id`, and then uses its `sheet` property to get the {{domxref("StyleSheet")}}. From the `StyleSheet` we get the set of `cssRules` added to the sheet. -Since we added the `@container` as the second rule above, we can access the associated `CSSContainerRule` using the second entry, with index "1", in the `cssRules`. -Last of all, we log the `containerName`, `containerQuery` and `conditionText` (inherited) properties. +Since we added the `@container` as the second rule above, we can access the associated `CSSContainerRule` using the second entry, with index "1" in the `cssRules`. ```js const exampleStylesheet = document.getElementById("example-styles").sheet; const exampleRules = exampleStylesheet.cssRules; const containerRule = exampleRules[1]; // a CSSContainerRule representing the container rule. -log(`CSSContainerRule.containerName: "${containerRule.containerName}"`); -log(`CSSContainerRule.containerQuery: "${containerRule.containerQuery}"`); -log(`CSSContainerRule.conditionText: "${containerRule.conditionText}"`); ``` -> [!NOTE] -> The styles for this example are defined in an inline HTML `style` element with an id in order to make it easy for the code to find the correct sheet. -> You might also locate the correct sheets for each example from the document by indexing against the length (e.g., `document.styleSheets[document.styleSheets.length-1]` but that makes working out correct sheet for each example more complicated). +Next, we use our feature testing code from the previous example to find and log the information we want to display. + +```js +if (typeof CSSContainerRule === "undefined") { + // Browser doesn't support CSSContainerRule (at all) + log("CSSContainerRule is not supported in this browser."); +} else if (!containerRule) { + // Browser doesn't support multiple container conditions + log( + "No CSSContainerRule was created. This browser doesn't support @container with multiple conditions.", + ); +} else if ("conditions" in CSSContainerRule.prototype) { + log("CSSContainerRule.conditions is supported."); + log("CSSContainerRule.conditions:"); + containerRule.conditions.forEach((item) => { + const jsonString = JSON.stringify(item); + log(` ${jsonString}`); + }); + log(`CSSContainerRule.conditionText: "${containerRule.conditionText}"`); +} else { + // @container exists but predates the multi-condition specification + log("CSSContainerRule.conditions not supported"); + log(`CSSContainerRule.containerName: "${containerRule.containerName}"`); + log(`CSSContainerRule.containerQuery: "${containerRule.containerQuery}"`); + log(`CSSContainerRule.conditionText: "${containerRule.conditionText}"`); +} +``` + +#### Results The example output is shown below. -The log section lists the `containerName`, which is an empty string as no name has been defined. -The `containerQuery` and `conditionText` strings are also logged, and have the same value because there is no name defined. -The card should change background and as the width of the page transitions through 650px. +This lists the condition using either the `conditions` property if it is supported or `containerName`/`containerQuery` if it is not. + +{{EmbedLiveSample("Unnamed container condition","100%","300px")}} -{{EmbedLiveSample("Unnamed container rule","100%","300px")}} +Note that the card's `background-color` should change when the container width becomes smaller or larger than `650px`. -### Named container rule +### Named container condition + +The example below defines a {{cssxref("@container")}} rule that includes a name and a query, and displays the properties of the associated `CSSContainerRule`. -The example below defines a named {{cssxref("@container")}} rule, and displays the properties of the associated `CSSContainerRule`. The CSS is very similar to that in the `@container` example [Creating named container contexts](/en-US/docs/Web/CSS/Reference/At-rules/@container#creating_named_container_contexts). +Note that we've hidden the HTML, logging code, and feature checking code, as they are the same as in the previous example. ```html hidden -
        -

        Log

        -
          -
          -
          +
          
           ```
           
           ```js hidden
          -// Store reference to log list
          -const logList = document.querySelector("#log ul");
          -// Function to log data from underlying source
          -function log(result) {
          -  const listItem = document.createElement("li");
          -  listItem.textContent = result;
          -  logList.appendChild(listItem);
          +const logElement = document.querySelector("#log");
          +function log(text) {
          +  logElement.innerText = `${logElement.innerText}${text}\n`;
          +  logElement.scrollTop = logElement.scrollHeight;
           }
           ```
           
          -First we define the HTML for a `card` (`
          `) contained within a `post` (the example does not show the logging code, as this is the same as in the previous example). +```css hidden +#log { + height: 100px; + overflow: scroll; + padding: 0.5rem; + border: 1px solid black; +} +``` -```html +```html hidden

          Card title

          @@ -148,8 +265,10 @@ First we define the HTML for a `card` (`
          `) contained within a `post` (the e
          ``` -As described in {{cssxref("@container")}}, the CSS for the container element specifies the type of the container, and may also specify a name for the container. -The card has a default font size, which is overridden for the `@container` named `sidebar` if the minimum width is greater than 700px. +#### CSS + +In this example, the {{cssxref("@container")}} specifies a container name, `sidebar`, as well as the container type. +The card has a default font size, which is overridden when it is contained inside a `sidebar` `@container` when its width is greater than or equal to `700px`. ```html ``` -The code for getting the sheet and rules is almost identical to the previous example. -The only difference is that in this example we have three CSS rules, so to get the associated `CSSContainerRule` we get the third entry in the `cssRules`. - -```js +```js hidden const exampleStylesheet = document.getElementById("example-styles").sheet; const exampleRules = exampleStylesheet.cssRules; const containerRule = exampleRules[2]; // a CSSContainerRule representing the container rule. -log(`CSSContainerRule.containerName: "${containerRule.containerName}"`); -log(`CSSContainerRule.containerQuery: "${containerRule.containerQuery}"`); -log(`CSSContainerRule.conditionText: "${containerRule.conditionText}"`); + +if (typeof CSSContainerRule === "undefined") { + // Browser doesn't support CSSContainerRule (at all) + log("CSSContainerRule is not supported in this browser."); +} else if (!containerRule) { + // Browser doesn't support multiple container conditions + log( + "No CSSContainerRule was created. This browser doesn't support @container with multiple conditions.", + ); +} else if ("conditions" in CSSContainerRule.prototype) { + log("CSSContainerRule.conditions is supported."); + log("CSSContainerRule.conditions:"); + containerRule.conditions.forEach((item) => { + const jsonString = JSON.stringify(item); + log(` ${jsonString}`); + }); + log(`CSSContainerRule.conditionText: "${containerRule.conditionText}"`); +} else { + // @container exists but predates the multi-condition specification + log("CSSContainerRule.conditions not supported"); + log(`CSSContainerRule.containerName: "${containerRule.containerName}"`); + log(`CSSContainerRule.containerQuery: "${containerRule.containerQuery}"`); + log(`CSSContainerRule.conditionText: "${containerRule.conditionText}"`); +} ``` +#### Results + The example output is shown below. -The log section lists the `containerName` and `containerQuery` strings. +This lists the condition using either the `conditions` property if it is supported or `containerName`/`containerQuery` if it is not. The `conditionText` is also logged, and shows the combination of these two strings. -The title in the card section should double in size as the width of the page goes over 700px. -{{EmbedLiveSample("Named container rule","100%","300px")}} +{{EmbedLiveSample("Named container condition","100%","300px")}} + +The text in the card `
          ` should double in size as the page width reaches `700px`, and halve as it goes below `700px` again. + +### Multiple container conditions + +The example below defines a {{cssxref("@container")}} rule that includes multiple container conditions, and displays the properties of the associated `CSSContainerRule`. + +Note that we've hidden the HTML, logging code, and feature checking code, as they are the same as in the previous example. + +```html hidden +
          
          +```
          +
          +```js hidden
          +const logElement = document.querySelector("#log");
          +function log(text) {
          +  logElement.innerText = `${logElement.innerText}${text}\n`;
          +  logElement.scrollTop = logElement.scrollHeight;
          +}
          +```
          +
          +```css hidden
          +#log {
          +  height: 100px;
          +  overflow: scroll;
          +  padding: 0.5rem;
          +  border: 1px solid black;
          +}
          +```
          +
          +```html hidden
          +
          +
          +

          Card title

          +

          Card content

          +
          +
          +``` + +#### CSS + +The `@container` declaration here defines two container conditions; it will match a container if either condition is true. + +```html + +``` + +```js hidden +const exampleStylesheet = document.getElementById("example-styles").sheet; +const exampleRules = exampleStylesheet.cssRules; +const containerRule = exampleRules[2]; // a CSSContainerRule representing the container rule. + +if (typeof CSSContainerRule === "undefined") { + // Browser doesn't support CSSContainerRule (at all) + log("CSSContainerRule is not supported in this browser."); +} else if (!containerRule) { + // Browser doesn't support multiple container conditions + log( + "No CSSContainerRule was created — @container with multiple conditions may not be parsed.", + ); +} else if ("conditions" in CSSContainerRule.prototype) { + log("CSSContainerRule.conditions is supported."); + log("CSSContainerRule.conditions:"); + containerRule.conditions.forEach((item) => { + const jsonString = JSON.stringify(item); + log(` ${jsonString}`); + }); + log(`CSSContainerRule.conditionText: "${containerRule.conditionText}"`); +} else { + // @container exists but predates the multi-condition specification + log("CSSContainerRule.conditions not supported"); + log(`CSSContainerRule.containerName: "${containerRule.containerName}"`); + log(`CSSContainerRule.containerQuery: "${containerRule.containerQuery}"`); + log(`CSSContainerRule.conditionText: "${containerRule.conditionText}"`); +} +``` + +#### Results + +The example output is shown below. +Browsers that support the `conditions` property will show both conditions. +Those that do not will log a note indicating that multiple conditions cannot be parsed. + +{{EmbedLiveSample("Multiple container conditions","100%","300px")}} ## Specifications