Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

zh-CN: Translate "CSS Containment" #12810

Merged
merged 3 commits into from
Apr 19, 2023
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
130 changes: 87 additions & 43 deletions files/zh-cn/web/css/css_containment/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,124 +4,168 @@ slug: Web/CSS/CSS_Containment
---

{{CSSRef}}
CSS Containment 主要是通过允许开发者将某些子树从页面中独立出来,从而提高页面的性能。如果浏览器知道页面中的某部分是独立的,就能够优化渲染并获得性能提升。这个定义通过一个 CSS 属性 {{cssxref("contain")}}来实现。本文阐述了这个定义的基础用法。

CSS 局限规范的目标在于通过允许浏览器从页面的其余部分中隔离出页面子树而改善性能。若浏览器知道页面的某一部分为独立的,则可优化渲染并改善性能。

此外,此规范允许开发者标示元素究竟是否应当渲染其内容,以及在屏外时是否应当渲染其内容。由此允许用户代理在恰当的时候在元素上应用局限,并有望将布局和渲染推迟至需要时再进行。

此规范定义了 CSS 属性 {{CSSXref("contain")}} 和 {{CSSXref("content-visibility")}}。本文档描述了此规范的基本目标。CSS 容器查询的细节见 [CSS 容器查询](/zh-CN/docs/Web/CSS/CSS_Container_Queries)。

## 基本示例

大多数的网页都包含了一些独立于网页中其他部分的区块。比如一个包含文章标题和内容的列表,如下:
许多网页包含若干互相独立的部分,例如下列标记代码中所罗列的文章标题和内容。

```html
<h1>My blog</h1>
<h1>我的博客</h1>
<article>
<h2>Heading of a nice article</h2>
<p>Content here.</p>
<h2>好文标题</h2>
<p>此处为内容。</p>
</article>
<article>
<h2>Another heading of another article</h2>
<p>More content here.</p>
<h2>另一文章的另一标题</h2>
<p>此处为更多的内容。</p>
</article>
```

每个 article 区块的 CSS 中都有 {{cssxref("contain")}} 属性,其值为 content.
在 CSS 中,每篇文章有应用了带 `content` 值的 {{CSSXref("contain")}} 属性

```css
article {
contain: content;
}
```

在这个页面中,每个 article 都独立于其他的 article,所以,他们都被设置了 `contain: content` 属性,为了告诉浏览器他们相互独立。浏览器就可以通过这个信息来确定,如何渲染这些内容。比如,他可能不会渲染超出视图范围外的内容
每篇文章均与页面上的其他文章相独立,因此给了这些文章 `contain: content` 向浏览器标示此情况,然后浏览器可以据此决定如何渲染内容。例如浏览器可能不会渲染可见区域之外的文章

如果我们给每个 `<article>` 节点都设置其 `contain` 属性为 `content`,当新的内容被加入到该节点中时,浏览器就知道不用重排和重绘节点以外的页面内容,但如果 `<article>` 设置了其 CSS 属性能让其大小根据其内容改变(比如 `height: auto`),浏览器依旧会进行其大小的计算
如果给每个 `<article>` 带 `content` 值的 `contain` 属性,那么在插入新元素时,浏览器无需重新计算布局或重绘包含元素子树之外的任意区域。如果 `<article>` 的样式尺寸取决于其内容(如有 `height: auto`),那么浏览器可能需要考虑到其尺寸的变化

我们通过 `contain` 属性告诉浏览器,这些节点是独立的
我们通过 `contain` 属性说明了每篇文章都是独立的

`content` 其实是 `contain: layout paint` 的缩写。他告诉浏览器,该节点内部的渲染和排版完全独立于外部的其他内容,并且所有的内容渲染都只限定在其节点边界内部,溢出的部分不会显示
`content` 值为 `contain: layout paint style` 的简写。此值告诉浏览器元素的内部布局与页面其余部分完全分离,且元素的方方面面均绘制在其边界的内部,不会出现可见溢出

“节点的独立性”这个信息对于开发者来说,其实是事先知道的。但浏览器却不能够从你的内容里推测出哪些部分会是独立的。因此,这个属性给予了浏览器知晓这个信息的能力,并且允许其通过这个信息来进行一些可观的性能优化
创建页面的 web 开发者通常知晓这一(其实相当显然的)信息。然而浏览器无法猜测你的意图,不能假设文章将完全自成一体。因此此属性让你可以向浏览器说明这一点,并允许浏览器据此做出性能优化

## 关键概念和术语

这个规范的定义只有一个属性, {{cssxref("contain")}}。他的值表明你想用何种方式控制其 containment。
### `contain` 的值

### Layout containment
{{CSSXref("contain")}} 属性的值标示了你想应用于元素的局限类型。

#### 布局局限

```css
article {
contain: layout;
}
```

布局的影响通常是整个页面的,比如你移动了某个节点,不论你是把它移动到哪儿,浏览器都会重新计算整个页面的布局。通过使用 `contain: layout` 你可以告诉浏览器,它只会影响到该节点内部的布局,所有内部的改变都不会影响外部页面的布局,这个容器建立了一个独立的格式化上下文
布局的作用域通常为整个文档,即若移动一个元素,则需视为整个文档的所有元素均可被移动至任意位置。通过使用 `contain: layout` 可以告诉浏览器只需检查此元素——元素内任意内容的作用域均被限制为此元素,不会影响页面的其余部分,且包含盒将建立独立的格式化上下文

额外注意
此外

- `float` 布局会独立存在
- 布局边界不会存在边距塌陷
- 该布局容器会成为 `absolute`/`fixed` 定位的
- 容器会创建一个栈式上下文,因此可以使用 {{cssxref("z-index")}}。
- 浮动(`float`)布局将独立进行
- 外边距将不会越过布局局限边界发生折叠
- 布局容器将作为绝对(`absolute`)或相对(`fixed`)定位后代的包含区块
- 包含盒将创建层叠上下文,故可使用 {{CSSXref("z-index")}}。

### Paint containment
#### 绘制局限

```css
article {
contain: paint;
}
```

Paint containment essentially clips the box to the padding edge of the principal box. There can be no visible overflow. The same things are true for `paint` containment as `layout` containment (see above).
绘制局限主要将盒子裁剪至主盒的内边距边,不会出现可见溢出。关于布局(`layout`)局限的描述(见上文)也适用于绘制(`paint`)局限。

Another advantage is that if the containing box is offscreen, the browser does not need to paint its contained elements — these must also be offscreen as they are contained completely by that box.
另一优点在于若包含盒在屏外,则浏览器无需绘制其被局限的元素——这些元素因为被完全局限于此盒故必然也在屏外。

### Size containment
#### 尺寸局限

```css
article {
contain: size;
}
```

Size containment does not offer much in the way of performance optimizations when used on its own. However, it means that the size of the element's children cannot affect the size of the element itself — its size is computed as if it had no children.
尺寸局限在单独使用时不会提供较大的性能优化。然而此局限意味着此元素的子元素尺寸无法影响元素本身的尺寸——计算其尺寸时视为无子元素。

If you turn on `contain: size` you need to also specify the size of the element you have applied this to. It will end up being zero-sized in most cases, if you don't manually give it a size.
若启用 `contain: size`,则还需使用 {{CSSXref("contain-intrinsic-size")}}(或等价的全称属性)指定应用此值的元素的尺寸。若不手动给予其尺寸,则多数时候元素尺寸将变为零。

### Style containment
#### 样式局限

```css
article {
contain: style;
}
```

Despite the name, style containment does not provide scoped styles such as you would get with the [Shadow DOM](/zh-CN/docs/Web/API/Web_components/Using_shadow_DOM). The main use case is to prevent situations where a [CSS Counter](/zh-CN/docs/Web/CSS/CSS_Lists_and_Counters/Using_CSS_counters) could be changed in an element, which could then affect the rest of the tree.

Using `contain: style` would ensure that the {{cssxref("counter-increment")}} and {{cssxref("counter-set")}} properties created new counters scoped to that subtree only.
尽管名称如此,但是样式局限不提供如由 [Shadow DOM](/zh-CN/docs/Web/API/Web_components/Using_shadow_DOM) 可得的域限(scoped)样式。其主要用途为防止 [CSS 计数器](/zh-CN/docs/Web/CSS/CSS_Counter_Styles/Using_CSS_counters)可在元素中被更改的情形出现,此情形可影响树的其余部分。

> **备注:** `style` containment is "at-risk" in the spec and may not be supported everywhere (it's not currently supported in Firefox).
使用 `contain: style` 将确保由 {{CSSXref("counter-increment")}} 和 {{CSSXref("counter-set")}} 属性所创建的新计数器的作用域被限制为此子树。

### 特殊值
#### 特殊值

存在两个特殊的值
`contain` 有两个特殊值

- `content`
- `strict`

We encountered the first in the example above. Using `contain: content` turns on `layout` and `paint` containment. The specification describes this value as being "reasonably safe to apply widely". It does not apply `size` containment, so you would not be at risk of a box ending up zero-sized due to a reliance on the size of its children.
在上述示例中见到了第一个值。使用 `contain: content` 将启用布局(`layout`)和绘制(`paint`)局限。规范将此值描述为“对于广泛应用而言相当保险”。由于此值不应用尺寸(`size`)局限,故不会面临盒子尺寸因为依赖于其子元素尺寸而变为零的风险。

To gain as much containment as possible use `contain: strict`, which behaves the same as `contain: size layout paint`, or perhaps the following to also add `style` containment in browsers that support it:
为获得尽可能多的局限,请使用 `contain: strict`,此值效果与 `contain: size layout paint style` 相同:

```css
contain: strict;
contain: strict style;
```

## 引用
### `content-visibility`

{{CSSXref("content-visibility")}} 控制元素是否渲染其内容,以及施加一组强局限,由此允许用户代理有机会在不需要时省略大片的布局和渲染工作。此属性使用户代理得以在不需要时跳过元素的渲染工作(包括布局和绘制)——由此使页面的初始加载明显变快。

其可取值为:

- `visible`:默认行为——元素内容照常进行布局和渲染。
- `hidden`:元素跳过其内容。被跳过的内容必须不可被例如页内查找和 tab 键顺序导航等用户代理特性访问,亦不可被选中或获得焦点。
- `auto`:元素启用布局局限、样式局限和绘制局限。若元素不与用户相关,则元素还跳过其内容。与 `hidden` 不同的是,被跳过的内容必须仍可照常被例如页内查找和 tab 键顺序导航等用户代理特性访问,且必须照常可获得焦点或被选中。

### 与用户相关

此规范提及了[与用户相关](https://w3c.github.io/csswg-drafts/css-contain/#relevant-to-the-user)这一概念。与用户相关的元素因为可见或用户正在交互所以应被渲染。

确切而言,若下列任意条件为真则元素与用户相关:

- 元素出现于视口或视口周围由用户代理所定义的外边距(视口尺度的 50%,给予应用在元素可见性改变时做准备的时间)内。
- 元素或其内容获得焦点。
- 元素或其内容被选中,例如用鼠标光标在文本上拖拽或进行其他突显操作。
- 元素或其内容被置于[顶层](https://w3c.github.io/csswg-drafts/css-position-4/#top-layer)。

### 跳过其内容

此规范提及了[跳过其内容](https://w3c.github.io/csswg-drafts/css-contain/#skips-its-contents)这一概念。此概念意味着所指元素与用户无关,且为改善性能将不被渲染。

确切而言,在元素跳过其内容时:

- 元素启用布局、样式、绘制和尺寸局限。
- 不绘制其内容,视为设置了 {{CSSXref("visibility", "visibility: hidden")}}。
- 其内容不接收指示器事件,视为设置了 {{CSSXref("pointer-events", "pointer-events: none")}}。

## 参考

### CSS 属性

- {{CSSXref("contain")}}
- {{CSSXref("content-visibility")}}

## 规范

{{Specifications}}

### CSS Properties
## 浏览器兼容性

- {{cssxref("contain")}}
{{Compat}}

## 外部资源
## 参见

- [An Introduction to CSS Containment](https://blogs.igalia.com/mrego/2019/01/11/an-introduction-to-css-containment/)
- [Everything You Need to Know About the CSS `will-change` Property](https://dev.opera.com/articles/css-will-change-property)
- [CSS 局限介绍](https://blogs.igalia.com/mrego/2019/01/11/an-introduction-to-css-containment/)
- {{DOMXref("element/contentvisibilityautostatechange_event", "contentvisibilityautostatechange")}} 事件