contain-intrinsic-size

Baseline 2023
新推出

自 2023 年 9 月起,此功能可在最新的设备和浏览器版本上使用。此功能可能无法在较旧的设备或浏览器上使用。

contain-intrinsic-size CSS 简写属性用于设置当元素受尺寸限制时,浏览器用于布局的元素尺寸。

构成属性

此属性是以下 CSS 属性的简写:

语法

css
/* Keyword values */
contain-intrinsic-size: none;

/* <length> values */
contain-intrinsic-size: 1000px;
contain-intrinsic-size: 10rem;

/* width | height */
contain-intrinsic-size: 1000px 1.5em;

/* auto <length> */
contain-intrinsic-size: auto 300px;
contain-intrinsic-size: auto none;

/* auto width | auto height */
contain-intrinsic-size: auto 300px auto 4rem;

/* Global values */
contain-intrinsic-size: inherit;
contain-intrinsic-size: initial;
contain-intrinsic-size: revert;
contain-intrinsic-size: revert-layer;
contain-intrinsic-size: unset;

contain-intrinsic-size 属性可以指定以下值:

none

元素在指定维度上没有固有尺寸。

<length>

元素在指定维度上具有指定的 <length>

auto [<length> | none]

如果存在“正常渲染”的元素尺寸的记忆值,并且元素正在跳过其内容(例如,当它在屏幕外时),则使用该记忆值;否则使用指定的 <length>。在 0px 固定长度与 none 表现不同的情况下(例如在多列或网格布局中),可以使用关键字 none 代替 <length>

如果提供一个值作为关键字、一个长度或一个 auto [<length> | none] 对,它将同时应用于宽度和高度。

可以指定两个长度值,它们按顺序分别应用于宽度和高度。如果指定了两个 auto [<length> | none] 对,则第一对应用于宽度,第二对应用于高度。

描述

该属性通常与可以触发尺寸限制的元素一起使用,例如 contain: sizecontent-visibility

尺寸限制允许用户代理像布局一个具有固定尺寸的元素一样布局它,通过避免为确定实际尺寸而重新渲染子元素来防止不必要的回流(从而改善用户体验)。默认情况下,尺寸限制将元素视为没有内容,并可能以与内容没有宽度或高度相同的方式折叠布局。contain-intrinsic-size 属性允许开发者指定一个适当的值用作布局尺寸。

auto <length> 值允许在元素“正常渲染”(即包含其子元素)时存储其尺寸,然后在元素跳过其内容时使用该尺寸,而不是使用指定的长度。这使得设置了 content-visibility: auto 的屏幕外元素能够从尺寸限制中受益,而开发者无需在估计元素尺寸时那么精确。如果子元素正在被渲染,则不会使用记忆值(如果启用了尺寸限制,将使用 <length>)。

在网格和多列布局中,显式尺寸的处理方式与隐式的基于内容的尺寸不同。元素的布局可能会与其简单地用内容填充到那个高度时的布局有很大不同。auto none 值允许在没有记忆值的情况下,元素回退到 contain-intrinsic-size: none,这将允许元素像没有内容一样进行布局。在网格和多列布局中,这几乎总是比将固有尺寸设置为 0px 更好,因为在这种情况下,受限元素可能会溢出其父元素,并可能导致意外的页面布局。

正式定义

初始值作为简写中的每个属性
应用于可应用尺寸限制的元素
继承性
百分比作为简写中的每个属性
计算值作为简写中的每个属性
动画类型作为简写中的每个属性

正式语法

contain-intrinsic-size = 
[ auto? [ none | <length> ] ]{1,2}

示例

为固有尺寸使用 auto 值对

此示例演示了 contain-intrinsic-size: auto <length>contain-intrinsic-size: auto none,其布局中垂直显示了许多元素,这些元素既有准确的也有不正确的固有尺寸估计。使用 content-visibility: auto 会在元素位于屏幕外时跳过渲染,因此该属性非常适合与 contain-intrinsic-size 结合使用,以提高渲染性能并最小化回流

contain-intrinsic-size: auto 500px 值对告诉浏览器,当元素位于屏幕外且页面正在布局时,使用 500px 作为元素的“占位符”尺寸(宽度和高度)。当用户滚动到该元素并需要显示时,浏览器将计算该元素及其内容的实际尺寸。如果占位符尺寸和计算出的尺寸之间存在差异,这可能会强制进行新的布局,并伴随着侧边栏位置的更改。

一旦浏览器获得了元素的实际尺寸信息,当该元素再次滚动到屏幕外时,它会记住这个尺寸,并在布局计算中使用这个记忆的尺寸,而不是占位符值。这样做的好处是浏览器不需要重复渲染元素内容来计算其尺寸,这在内容复杂或依赖网络资源或 JavaScript 时尤其有用。

HTML

html
<div id="container">
  <div id="auto-length-note">
    <p>
      Your browser does not support
      <code>contain-intrinsic-size: auto &lt;length&gt;</code>.
    </p>
  </div>
  <div class="auto-length">
    <p>Item one</p>
  </div>
  <div class="auto-length">
    <p>Item two</p>
  </div>
  <div class="auto-length large-intrinsic-size">
    <p class="small">Item three</p>
  </div>
  <div class="auto-length large-intrinsic-size">
    <p class="small">Item four</p>
  </div>
  <div id="auto-none-note">
    <p>
      Your browser does not support
      <code>contain-intrinsic-size: auto none</code>.
    </p>
  </div>
  <div class="auto-length none">
    <p>Item five</p>
  </div>
  <div class="auto-length none">
    <p>Item six</p>
  </div>
</div>

CSS

css
p {
  height: 500px;
  width: 500px;
  border: 4px dotted;
  background: lightblue;
}

.auto-length {
  content-visibility: auto;
  contain-intrinsic-size: auto 500px;
  background-color: linen;
  outline: 4px dotted blue;
}

.large-intrinsic-size {
  /* Setting an inaccurate intrinsic size for the element */
  contain-intrinsic-size: auto 5000px;
  background-color: lightgray;
  outline: 4px dotted red;
}

.small {
  /* This element is a lot smaller than expected */
  height: 100px;
  width: 100px;
}

.none {
  background-color: papayawhip;
  contain-intrinsic-size: auto none;
  outline: 4px dotted red;
}

结果

  • 前两个盒子的固有尺寸与其真实尺寸相符,所以当它们滚动进入视图时,布局会重新计算,但我们看不到滚动条或滚动位置有任何变化。

  • 第三和第四个盒子的固有尺寸非常大,所以浏览器最初计算的布局过大,我们把这些盒子做得更小,以便当你到达某个点时,能明显看到布局发生了剧烈变化。

    当第三和第四个盒子滚动进入视图时,尺寸会被重新计算,使得盒子及其父元素的高度变小。效果是滚动条会向下跳(我们实际上滚过了比我们预估的更多的盒子内容),并且滚动条会变长,因为整个页面比我们预估的高度要小。

  • 最后的盒子设置了 auto none,所以它们的预估尺寸为零。当它们滚动进入视图时,元素及其父元素的尺寸被重新计算为大得多,所以滚动条的尺寸会减小并向上移动。

一直滚动到底部后,你可以随后平滑地上下滚动,因为使用 content-visibility: auto 会保存元素的实际渲染尺寸,以便下次显示时使用。

设置固有尺寸

此示例提供了选择列表,可用于修改元素上的 contain-intrinsic-sizecontent-visibilitycontain,以便观察不同设置的效果。

CSS

css
#contained_element {
  border: 2px solid green;
  width: 120px;
}
.child_element {
  border: 1px solid red;
  background: blue;
  height: 50px;
  width: 150px;
}

JavaScript

以下代码根据所选选项为容器元素添加和移除样式。

js
const containedElement = document.querySelector("#contained_element");
const intrinsicSizeSelector = document.querySelector(
  "#contain_intrinsic_size_selector",
);
const containSelector = document.querySelector("#contain_selector");
const contentVisibilitySelector = document.querySelector(
  "#content_visibility_selector",
);

containedElement.style["contain-intrinsic-size"] =
  intrinsicSizeSelector.options[intrinsicSizeSelector.selectedIndex].text;
containedElement.style["contain"] =
  containSelector.options[containSelector.selectedIndex].text;
containedElement.style["content-visibility"] =
  contentVisibilitySelector.options[
    contentVisibilitySelector.selectedIndex
  ].text;

intrinsicSizeSelector.addEventListener("change", () => {
  containedElement.style["contain-intrinsic-size"] =
    intrinsicSizeSelector.options[intrinsicSizeSelector.selectedIndex].text;
});

containSelector.addEventListener("change", () => {
  containedElement.style["contain"] =
    containSelector.options[containSelector.selectedIndex].text;
});

contentVisibilitySelector.addEventListener("change", () => {
  containedElement.style["content-visibility"] =
    contentVisibilitySelector.options[
      contentVisibilitySelector.selectedIndex
    ].text;
});

HTML

HTML 定义了两个按钮和一个通过 content-visibility 属性受限的容器元素。

html
<p>
  <label for="contain_intrinsic_size_selector">contain-intrinsic-size:</label>
  <select id="contain_intrinsic_size_selector">
    <option>none</option>
    <option>40px 130px</option>
    <option>auto 40px auto 130px</option></select
  >;<br />

  <label for="contain_selector">contain:</label>
  <select id="contain_selector">
    <option>none</option>
    <option>size</option>
    <option>strict</option></select
  >;<br />

  <label for="content_visibility_selector">content-visibility:</label>
  <select id="content_visibility_selector">
    <option>visible</option>
    <option>auto</option>
    <option>hidden</option></select
  >;
</p>

<div id="contained_element">
  <div class="child_element"></div>
</div>

结果

使用选择器将给定的样式应用于包含的 div 元素。请注意,当 content-visibilityvisibleauto 时,更改 contain-intrinsic-size 不会产生任何影响。但是,如果内容是隐藏的,将 contain-intrinsic-size 设置为 none 会使父元素折叠,就好像其子元素没有尺寸一样。

规范

规范
CSS Box Sizing Module Level 4
# propdef-contain-intrinsic-size

浏览器兼容性

另见