recursal/MDN huggingface dataset:
Introduction to formatting contexts 格式化上下文简介
============================================


 本文介绍格式化上下文的概念，其中有几种类型，包括块格式化上下文 block formatting contexts、内联格式化上下文 inline formatting contexts 和灵活格式化上下文 flex formatting contexts。还介绍了它们的基本行为以及如何利用这些行为。
 页面上的所有内容都是**格式化上下文 formatting context** 的一部分，或者是一个以特定方式显示的区域。\*\*块格式上下文（BFC）\*\*将根据块布局规则布局子元素，**灵活格式上下文 flex formatting context** 将其子元素布局为灵活项flex items等。每个格式上下文在其上下文中都有特定的布局规则。
Block formatting contexts 块格式化上下文
---------------------------------

文档最外层元素使用块布局规则或称为**初始块格式上下文**。这意味着`<html>`元素块中的每个元素都是按照正常流程遵循块和内联布局规则进行布局的。参与 BFC 的元素使用 CSS 框模型概述的规则，该模型定义了元素的边距、边框和填充如何与同一上下文中的其他块交互。

### 创建新的块格式上下文

`<html>` 元素不是唯一能够创建块格式上下文的元素。任何块级元素都可以通过应用某些 CSS 属性来创建一个 BFC

除了文档的根元素 (`<html>`) 之外，还将在以下情况下创建一个新的 BFC：

* 使用`float` 使其浮动的元素
* 绝对定位的元素 (包含 `position: fixed` 或`position: sticky`
* 使用以下属性的元素 `display: inline-block`
* 表格单元格或使用 `display: table-cell`, 包括使用 `display: table-*` 属性的所有表格单元格
* 表格标题或使用 `display: table-caption` 的元素
* 块级元素的 overflow 属性不为 `visible`
* 元素属性为 `display: flow-root` 或 `display: flow-root list-item`
* 元素属性为 `contain: layout`, `content`, 或 `strict`
* flex items
* 网格布局元素
* multicol containers
* 元素属性 `column-span` 设置为 `all`

这很有用，因为新的 BFC 的行为与最外层的文档非常相似，它在主布局中创造了一个小布局。BFC 包含其内部的所有内容，`float` 和 `clear` 仅适用于同一格式上下文中的项目，而页边距仅在同一格式上下文中的元素之间折叠。

### BFC 创建例子

让我们看看几个例子，来理解创建 BFC 的效果。

在下面的示例中，我们在应用了边框的 `<div>` 中有一个浮动元素。该 `div` 的内容与浮动元素一起浮动。由于 float 的内容比它旁边的内容高，所以现在 DIV 的边框贯穿了 float。如流入和流出元素指南guide to in-flow and out of flow elements中所述，浮动已脱离文档流，因此 DIV 的背景和边框仅包含内容，而不包含浮动。

创建一个新的 BFC 将包含该浮动。在过去，一种典型的方法是设置 `overflow: auto` 或设置其他不是 `overflow: visible` 的值。

 设置 `overflow: auto` 会自动创建包含浮动的新 BFC。现在，我们的 DIV 在布局中变成了一个迷你布局。任何子元素都将包含在其中。

使用 `overflow` 创建新的 BFC 的问题在于， `overflow` 属性用于告诉浏览器你希望如何处理溢出的内容。在某些情况下，当你纯粹使用此属性创建 BFC 时，你会发现不需要的滚动条或剪切阴影。另外，对于未来的开发人员来说，它可能不太可读，因为不能显式地表明为什么要使用溢出来实现这一目的。如果你使用了这个方法，最好对代码进行注释以便他人理解。

### 使用 display:flow-root 显式创建 BFC

使用 `display: flow-root` （或 `display: flow-root list-item`）将创建一个新的 BFC，而不会产生任何其他潜在的问题副作用。

使用 `<div>`上的 `display: flow-root` ，该容器内的所有内容都参与该容器的块格式上下文，并且浮动不会从元素底部弹出。

`flow-root` 关键字的意义是，创建的内容本质上类似于一个新的根元素（如 `<html>`所做），并确定这个新的上下文如何创建及其流布局如何实现。

行内格式化上下文
--------

内联格式上下文存在于其他格式上下文中，可以将其视为段落的上下文。段落创建了一个内联格式上下文，其中在文本中使用诸如 `<strong>`、`<a>`或 `<span>` 元素等内容。

box model 不完全适用于参与内联格式上下文。在水平书写模式行中，水平填充、边框和边距将应用于元素，并左右移动文本。但是，元素上方和下方边距将不适用。应用垂直填充和边框可能会在内容的上方和下方重叠，因为在内联格式上下文中，填充和边框不会将行框撑开。

其他格式上下文
-------

本指南涵盖了流式布局，因此不涉及其他可能的格式上下文。因此，了解创建任何类型的格式上下文都将改变该格式上下文中元素的行为方式是很有用的。这种行为总是在规范中描述的，在 MDN 中也有描述。

总结
--

在本指南中，我们更详细地介绍了块和内联格式上下文以及创建块格式上下文（BFC）的重要主题。在下一个指南中，我们将了解正常流如何与不同的写入模式交互 how normal flow interacts with different writing modes。

另请参见
----

* Block formatting context
* Visual Formatting Model
* CSS Box Model
流布局和溢出
======

当容器中的内容超过可容纳的范围时，就会发生溢出情况。了解溢出的行为对于处理 CSS 中大小受限的任何元素都很重要。本指南解释了使用正常流时溢出是如何工作的。

什么是溢出？
------

为元素赋予固定的高度和宽度，然后向框中添加重要内容，将创建一个基本的溢出示例：

内容将进入框中。一旦填充了该框，它将继续以可见的方式溢出，在框外显示内容，可能在随后的内容下显示。控制溢出行为的属性是初始值为 `visible` 的 `overflow` 属性。这就是为什么我们可以看到溢出内容。

控制溢出
----

还有其他值控制溢出内容的行为。要隐藏溢出的内容，请使用值 `hidden`。这可能会导致某些内容不可见。

使用值 `scroll` 包含其框中的内容，并添加滚动条以启用查看。即使内容适合该框，也将添加滚动条。

如果内容适合方框，则使用值 auto 将显示不带滚动条的内容。如果它不适合，则会添加滚动条。将下一个示例与溢出示例进行比较：当溢出滚动只需要垂直滚动时，你应该看到它有水平滚动条和垂直滚动条。下面的自动示例只在我们需要滚动的直接位置添加滚动条。

正如我们已经了解的，使用这些值中的任何一个，而不是默认的 `visible`，都会创建一个新的块级格式化上下文。

注意：在 Overflow Level 3 的工作草案中，还有一个附加值 `overflow: clip`。这将类似于 `overflow: hidden`，但不允许编程滚动，框将变为不可滚动。此外，它不会创建块格式上下文。

实际上，overflow 属性是 `overflow-x` 和 `overflow-y` 属性的简写。如果只为溢出指定一个值，则此值用于两个轴。但是，你可以指定两个值，在这种情况下，第一个值用于 `overflow-x`，因此是水平方向，第二个值用于 `overflow-y` 和垂直方向。在下面的示例中，我只指定了 `overflow-y: scroll`，这样我们就不会得到不需要的水平滚动条。

流相对属性
-----

在书写模式和流布局指南中，我们研究了 `block-size` 和 `inline-size` 这两个较新的属性，这些属性在使用不同的编写模式时比将布局与屏幕的物理尺寸联系起来更有意义。3 级溢出模块还包括溢出——`overflow-block` 和 `overflow-inline` 的流相关属性。这些对应于 `overflow-x` 和 `overflow-y`，但映射取决于文档的书写模式。

这些属性当前在浏览器中没有实现，因此你需要在当前使用物理属性并根据你的书写模式进行调整。

指示溢出
----

在 3 级溢出规范中，我们有一些属性可以帮助改进溢出情况下内容的外观。

### 行轴溢出

`text-overflow` 属性处理行方的文本溢出。它采用两个值 `clip` 中的一个值，在这种情况下，内容在溢出时被剪裁，这是初始值，因此是默认行为。我们还有一个省略号，它呈现了一个省略号，可以用一个更好的字符来替换使用中的语言或书写模式。

### 块轴溢出

还有一个关于块溢出属性的建议，尽管在编写名称时仍有待讨论。此建议将允许在块维度中文本溢出时添加省略号。

例如，在有文章列表的情况下，这很有用，并且在固定高度框中显示列表，而固定高度框只接受有限的文本量。对于读者来说，当单击框或标题时，可能不太明显有更多的内容需要单击。省略号清楚地表明有更多的内容。规范允许插入一个内容字符串或常规省略号。

总结
--

无论你是在 Web 上的连续媒体中，还是在页面媒体格式（如 print 或 epub）中，了解在处理任何布局方法时内容溢出是如何有用的。通过了解正常流中溢出的工作方式，你应该会发现更容易理解布局方法（如网格和弹性盒子）中溢出内容的含义。
流布局和书写模式
========

CSS 2.1 规范详细描述了正常流的行为，它采用了水平书写模式。布局属性在垂直写入模式中的工作方式应该相同。在本指南中，我们将研究流布局在与不同的文档写入模式一起使用时的行为。

这不是 CSS 中书写模式使用的全面指南，这里的目的是以可能未预料到的方式记录流布局与书写模式交互的区域。本文档的参见章节链接了更多书写模式的资源。

书写模式规范
------

CSS 编写模式级别 3 规范定义了文档编写模式更改对流布局的影响。在书写模式介绍中，规范提到：

> 
> “CSS 中的书写模式由 `writing-mode`、`direction` 和 `text-orientation` 属性决定。它主要是根据其内联基础方向和块流方向来定义的。”
> 
> 
> 

规范将*行基本方向*定义为内容在行上的排序方向。这定义了内联方向的开始和结束。开始是句子开始的地方，结束是一行文本在开始换行之前结束的地方。

*块流方向*是框（例如段落）以该写入模式堆叠的方向。CSS 写入模式属性控制块流方向。如果要将页面或页面的一部分更改为 `vertical-lr`，则可以在元素上设置 `writing-mode: vertical-lr`，这将更改块的方向，因此也会更改行的方向。

虽然某些语言将使用特定的书写模式或文本方向，但我们也可以使用这些属性来产生创造性效果，例如垂直运行标题。

`writing-mode` 属性和块流
--------------------

`writing-mode` 属性接受以下值：`horizontal-tb`、`vertical-rl` 和 `vertical-lr`。这些值控制阻止页面流动的方向。初始值是 `horizontal-tb`，这是一个顶部到底部的块流方向，具有水平的行方向。从左到右的语言，如英语和从右到左的语言。如阿拉伯语，都是 `horizontal-tb`。

下面的示例显示了使用 `horizontal-tb` 的块。

`horizontal-tb` 值为你提供了一个从右到左的块流方向和一个垂直的内联方向，如下一个示例所示。

最后一个示例演示了第三个可能的 `writing-mode` 值——`vertical-lr`。这将为你提供一个从左到右的块流方向和一个垂直的行方向。

对父级具有不同写入模式的框
-------------

当一个嵌套框被分配给它的父级的不同的写入模式时，一个行级别的框将显示，就好像它有 `display: inline-block` 一样。

块级别的框将建立一个新的块格式上下文，这意味着如果其内部显示类型为 `flow`，则它将获得 `flow-root` 的计算显示类型。这在下一个示例中显示，其中显示为 `horizontal-tb` 的框包含一个浮动，该浮动是由于其父级建立了一个新的 BFC 而包含的。

替换的元素
-----

替换的元素（如图像）不会根据“写入模式”属性更改其方向。但是，替换的元素（如包含文本的表单控件）应与使用中的写入模式匹配。

逻辑属性和值
------

一旦你在书写模式（而不是 `horizontal-tb`）时，许多映射到屏幕物理维度的属性和值看起来很奇怪。例如，如果为一个框提供 100px 的宽度，以水平 tb 表示，它将控制行方向的大小。在 `vertical-lr` 中，它控制块方向的大小，因为它不随文本旋转。

因此，我们有了 `block-size` 和 `inline-size` 的新属性。如果我们给块一个 100px 的 `inline-size`，不管我们是处于水平还是垂直写入模式，`inline-size` 总是指行方向的大小。

CSS 逻辑属性和值规范包括用于控制页边距、填充和边框的属性的逻辑版本，以及用于我们通常使用物理方向指定的内容的其他映射。

总结
--

在大多数情况下，流程布局的工作方式与你在更改文档或文档部分的写入模式时所期望的一样。这可以用于正确排版垂直语言或出于创造性的原因。CSS 通过引入逻辑属性和值使这变得更容易，这样在垂直写入模式下工作时，大小调整可以基于元素的内联和块大小。这在创建可以在不同写入模式下工作的组件时很有用。

参见
--

* 书写模式
* 书写模式和 CSS 布局
* CSS 书写模式
In Flow and Out of Flow
=======================

在之前的 文档中我解释了常规流中块（block）和行（inline）布局，常规流中的所有元素都会以这种布局方式运作。

在下面的例子中，我新建了一个标题（h1 元素），一个段落（p 元素），一个无序列表（ul 元素）和一个包含 strong 元素的段落（p 元素），标题和段落都是块级（block level），strong 元素为行级（inline）。列表中的项通过弹性盒布局排成一行，但是列表本身仍然处于块和内联布局中 - 他的 display 属性为 block。

可以说，示例中的所有元素都属于常规流，按照源代码中的顺序渲染到页面中。

脱离常规流的元素
--------

下列元素会脱离常规流：

* floated items。浮动的元素
* items with `position: absolute` (including `position: fixed` which acts in the same way)。通过设置 position 属性为 absolute 或者 fixed 的元素
* the root element (`html`) 根元素

脱离常规流的元素会创建一个新的块级格式化上下文（Block Formatting Context: BFC）环境，其中包含的所有元素构成了一个小的布局环境，与页面中的其他内容分隔开来。而根元素，作为页面中所有内容的容器，自身脱离常规流，为整个文档创建了一个块级格式化上下文环境。

### Floated Items

在这个例子中，我有一个 div，以及两个段落。我已经为段落添加了背景颜色，然后将 div 向左浮动。div 现在已经不再处于 flow 中了。

作为一个浮动的元素，它首先根据正常 flow 布局，然后从流动中取出并尽可能地向左移动

你可以看到下面段落的背景颜色在下面运行，只是该段落的行框已被缩短以导致在浮动周围包裹内容的效果。我们段落的方框仍然按照正常流程规则显示。这就是为什么要在浮动项目周围留出空间，必须为项目添加边距，以便将线框推离它。你无法对以下内插内容应用任何内容来实现此目的。

### Absolute Positioning

设置元素属性为 `position: absolute` 或者 `position: fixed` 会使此元素脱离文档流，他本来占据的空间也会被移除。在下面的例子中，我定义了三个 p 元素，并且将第二个 p 元素设置为 `position` `absolute`, `top: 30px` , `right: 30px`. 使其脱离文档流。

设置 `position: fixed` 也能使元素脱离文档流，但是偏移量会根据视口而不是父元素来定。

当通过定位方式使元素脱离文档流，元素内容可能重叠，这需要你自己去处理。脱离文档流意味着页面中的其他元素不知道该元素的存在，故不会对该元素做出响应。

### Relative Positioning and Flow

如果你给一个元素开启相对定位，那该元素依然会位于文档流中，然而你可以通过设置偏移值的方式来移动他。正如下面的例子所展示的，该元素的原先占据的空间仍然会被保留。

当你移动一个元素或者使元素脱离文档流，为防止重叠，你可能需要对元素内容和元素周围的内容做一些管理，要么清除浮动，要么保证相对定位不会覆盖其他元素。

Summary
-------

In this guide we have covered the ways to take an element out of flow in order to achieve some very specific types of positioning. In the next guide we will look at a related issue, that of creating a Block Formatting Context, in Formatting Contexts Explained (en-US).

See Also
--------

* Learn Layout: *Positioning*
初始值
===

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
**实验性:** **这是一项实验性技术**  
在将其用于生产之前，请仔细检查浏览器兼容性表格。

**`initial-value`** CSS描述符在使用`@property` `at-rule`的时候是必需的，除非 syntax 属性接受了任何有效的 token 流。它为属性设置初始值。

被选定为`initial-value`的参数，依照`syntax`描述符定义，必须可以正确地解析。因此，如果`syntax`描述符为`<color>`，那么初始值必须是一个有效的`color`值。

语法
--


```css
@property --property-name {
  syntax: "<color>";
  inherits: false;
  initial-value: #c0ffee;
}

@property --property-name {
  syntax: "<color>";
  inherits: true;
  initial-value: #c0ffee;
}
```

取值
--

对于设定的`syntax`，具有正确值的字符串。

形式定义
----

|  |  |
| --- | --- |
| Related at-rule | `@property` |
| 初始值 | `n/a (required)` |
| 计算值 | as specified |

形式语法
----
```

initial-value =   
  <declaration-value>?    
  
```

实例
--

为 `--my-color` `自定义属性`添加颜色值类型检测、设置默认值并且设置属性值不允许被继承。

使用 CSS `@property` 规则:


```css
@property --my-color {
  syntax: "<color>";
  inherits: false;
  initial-value: #c0ffee;
}
```


使用 JavaScript 中的 `CSS.registerProperty` (en-US)函数：


```js
window.CSS.registerProperty({
  name: "--my-color",
  syntax: "<color>",
  inherits: false,
  initialValue: "#c0ffee",
});
```

规范
--

| Specification |
| --- |
| CSS Properties and Values API Level 1 # initial-value-descriptor |

浏览器兼容性
------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

参见
--

* CSS 属性与值 API
* CSS 绘图 API (en-US)
* CSS 类型对象模型 (en-US)
* CSS Houdini
继承性
===

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
**实验性:** **这是一项实验性技术**  
在将其用于生产之前，请仔细检查浏览器兼容性表格。

**`inherits`** CSS 描述符在使用`@property` `at-rule`时是必需的，它控制由 `@property`声明注册的自定义属性默认情况下是否会被继承。

Syntax（类型描述符）
-------------


```css
@property --property-name {
  syntax: "<color>";
  inherits: false;
  initial-value: #c0ffee;
}

@property --property-name {
  syntax: "<color>";
  inherits: true;
  initial-value: #c0ffee;
}
```

取值
--

`true`

属性默认继承

`false`

属性默认不继承

规范定义
----

|  |  |
| --- | --- |
| Related at-rule | `@property` |
| 初始值 | `auto` |
| 计算值 | as specified |

标准语法
----


```css
inherits =   true   |  false  
```

实例
--

为 `--my-color` `自定义属性`添加颜色值类型检测、设置默认值并且设置属性值不允许被继承。

使用 CSS `@property` @规则:


```css
@property --my-color {
  syntax: "<color>";
  inherits: false;
  initial-value: #c0ffee;
}
```


使用 JavaScript 中的 `CSS.registerProperty` (en-US)函数：


```js
window.CSS.registerProperty({
  name: "--my-color",
  syntax: "<color>",
  inherits: false,
  initialValue: "#c0ffee",
});
```

规范
--

| Specification |
| --- |
| CSS Properties and Values API Level 1 # inherits-descriptor |

浏览器兼容性
------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

另见
--

* CSS 属性与值 API
* CSS 绘图 API (en-US)
* CSS 类型对象模型 (en-US)
* CSS Houdini
syntax
======

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
**实验性:** **这是一项实验性技术**  
在将其用于生产之前，请仔细检查浏览器兼容性表格。

**`syntax`** CSS 描述符在使用`@property` `at-rule`时是必需的，它描述了该属性所允许的语法结构。

Syntax
------

如下是所有的有效 syntax 字符串：


```css
syntax: "<color>"; /\* 接收一个颜色值 \*/

syntax: "<length> | <percentage>"; /\* 接收长度或百分比参数，但是二者之间不进行计算合并 \*/

syntax: "small | medium | large"; /\* 接收这些参数值之一作为自定义标识符 \*/

syntax: "\*"; /\* 任何有效字符 \*/
```

取值
--

规范定义的、受语法支持的字符串。支持的语法是CSS types的子集。这些可以单独使用，一些类型也可以结合使用。

`"<length>"`

任何有效的 `<length>` 值。

`"<number>"`

任何有效的 `<number>` 值。

`"<percentage>"`

任何有效的 `<percentage>` 值。

`"<length-percentage>"`

任何有效的 `<length-percentage>` 值。

`"<color>"`

任何有效的 `<color>` 值。

`"<image>"`

任何有效的 `<image>` 值。

`"<url>"`

任何有效的 `url()` 值。

`"<integer>"`

任何有效的 `<integer>` 值。

`"<angle>"`

任何有效的 `<angle>` 值。

`"<time>"`

任何有效的 `<time>` 值。

`"<resolution>"`

任何有效的 `<resolution>` 值。

`"<transform-function>"`

任何有效的 `<transform-function>` 值。

`"<custom-ident>"`

任何有效的 `<custom-ident>` 值。

`"<transform-list>"`

A list of valid `<transform-function>` 值。

形式定义
----

|  |  |
| --- | --- |
| Related at-rule | `@property` |
| 初始值 | `n/a (required)` |
| 计算值 | as specified |

形式语法
----
```

syntax =   
  <string>    
  
```

实例
--

为 `--my-color` `自定义属性`添加颜色值类型检测、设置默认值并且设置属性值不允许被继承。

使用 CSS `@property` 规则:


```css
@property --my-color {
  syntax: "<color>";
  inherits: false;
  initial-value: #c0ffee;
}
```


使用 JavaScript 中的 `CSS.registerProperty` (en-US)函数：


```js
window.CSS.registerProperty({
  name: "--my-color",
  syntax: "<color>",
  inherits: false,
  initialValue: "#c0ffee",
});
```

规范
--

| Specification |
| --- |
| CSS Properties and Values API Level 1 # the-syntax-descriptor |

浏览器兼容性
------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

参见
--

* CSS 属性与值 API
* CSS 绘图 API (en-US)
* CSS 类型对象模型 (en-US)
* CSS Houdini
指南：媒体对象
=======

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
媒体对象是 web 上随处可见的一种模式。它由Nicole Sullivan命名，表示一种一侧是图片并且另一侧是描述性的文字的两列盒子，比如一篇 facebook 帖子或者 tweet。

![](/zh-CN/docs/Web/CSS/Layout_cookbook/Media_objects/media-object.png)

要求
--

媒体对象模式需要以下特性的一些或者全部：

* 在移动设备上被堆叠，在桌面设备上显示两列
* 图片可以在左边，也可以在右边
* 图片可以是小图，也可以是大图
* 媒体对象可以被嵌套
* 无论哪边更高，媒体对象应该清除内容
使用指南
----

**备注：** Download this example

做出选择
----

我选择使用Grid Layout实现媒体对象，因为它可以让我在我需要的时候控制两个维度的布局。这意味着当我们有一个页脚（footer）的时候，上面的内容很短，页脚可以被推到媒体对象的底部。

另一个使用网格布局（Grid Layout）的原因是为了可以使用`fit-content`图片的追踪（track）大小。通过使用 最大尺寸是 200 像素的`fit-content` ，当我们有一个小图片比如 icon 的时候，track 仅仅得到和 image 的尺寸一样的大小（`max-content` 大小）。如果图片更大，track 在 200 像素的时候停止增长，因为图片应用了`max-width` 为 100%。同样，它会缩小以适应列内部的尺寸。

通过使用`grid-template-areas` 来实现布局，我可以看到 CSS 中的这个模式。我定义我的网格，其并且设置最大宽度（max-width）为 500 像素，因此在较小的设备上媒体对象会被堆叠起来。

模式的一个选项是翻转它将图片切换到另一边——这通过添加`media-flip` 类来实现，它定义了一个翻转的网格模板所以布局被镜像了。

当我们在另一个媒体对象之中嵌套一个媒体对象，我么你需要将它放到常规布局的第二个 track 中，当翻转时放到第一个 track 中

回退方案
----

对于这种模式有很多种可能的回退方案，取决于你希望支持的浏览器。一个比较好的方案是将图片浮动到左边，并且为盒子添加 clearfix 来确保它包含浮动元素。

**备注：** Download this example

一旦浮动元素成为网格项，浮动将不再被应用到网格上，因此你不需要做任何特殊的事情来清除浮动。

你需要做的事情是移除应用到这些 items 的任何边界，以及我们在一个网格上下文中不需要的任何宽度（在网格中我们有`gap`属性来控制它，并且 track 控制了尺寸）。

MDN 上相关的资源
----------

* CSS Grid Layout
* Progressive Enhancement and Grid Layout
* Using Grid Template Areas
* fit-content
* Grid-template-areas
浏览器兼容性
------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.
分离式导航菜单
=======

Baseline Widely available
-------------------------

This feature is well established and works across many devices and browser versions. It’s been available across browsers since September 2020.

* Learn more
* See full compatibility
* Report feedback
一种导航样式，其中一个或多个元素与其余导航项之间是分离的。

![分离为两组的项目](/zh-CN/docs/Web/CSS/Layout_cookbook/Split_Navigation/split-navigation.png)

需求
--

一种常见的导航样式是将一个元素推离其他元素。我们可以使用弹性盒（Flexbox）实现这一点，而不需要将两组项目放入两个单独的弹性容器（flex container）中。

指南
--

下载这份示例

做出选择
----

这一样式结合了自动外边距（auto margin）与弹性盒两种方法来把项目分离开。

自动外边距会吸收其应用方向上的所有可用空间。这就是利用自动外边距实现区块居中的工作原理——区块两侧都有一个试图占用所有空间的空白，从而将区块推到了中间。

在这种情况下，左侧的自动边距会占用所有可用空间，并将项目推到右侧。你可以将类 `push` 应用到列表中的任何项目上。

浏览器兼容性
------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

参见
--

* CSS 弹性盒布局
卡片
==

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
这个模式是带有可选页脚的“卡片”组件列表。

![Three card components in a row](/zh-CN/docs/Web/CSS/Layout_cookbook/Card/cards.png)

需求
--

卡片组件可以包含各种内容，如头部、图片、内容和页脚。

每个卡片组件应有相同的高度，并且页脚应该在卡片组件的底部。

当添加到卡片组中时，卡片应在两个维度上对齐。

使用指南
----

下载这个示例

所选方案
----

尽管是单维布局，该卡片还是使用 CSS 网格布局技术进行布局，因为它可以为网格轨道使用内容大小。在设置单列网格时，我使用了以下方法：


```css
.card {
  display: grid;
  grid-template-rows: max-content 200px 1fr;
}
```


标题轨道被设置为 `max-content`，这使得它不能被拉伸。我决定让我的图片放置在 200 像素高的轨道里。然后我把下一个轨道（也就是内容所在的地方）的高度设置为 `1fr`。这意味着它将占用任何额外的空间。

如果该轨道确实有页脚，它将自动调整大小，因为在隐式网格中创建的行是默认自动调整大小的，这样可以让添加到其中的内容适合网格大小。

**备注：** 由于每张卡片都是独立的网格，所以独立卡片中的各种元素并不互相对齐。所提出的 Grid Level 2 的子网格功能将给这个问题一个解决方案。

有用的后备措施或替代方法
------------

弹性盒可以用来布置卡片，在这种情况下，应该让内容区增长，而其他项目不增长。我略微倾向于能够从容器中控制轨道，而不需要为项目添加规则，这种布局卡片的方式更加合理。

对于整体布局，你可以使用 flexbox，然而这将导致卡片在最后的 flex 行上伸展，因为那里的卡片数量少于上面的行。另外，你可以使用 CSS 多列布局——这将导致卡片顺着列铺开，可能会导致问题。

请参阅多列布局方案以了解这些布局方法的演示。

无障碍考虑
-----

根据卡片的内容，你可以或应该做一些事情来加强无障碍性。请参阅 Heydon Pickering 撰写的 Inclusive Components: Card，那篇文章对这些问题进行了非常详细的解释。

浏览器兼容性
------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

参见
--

* `grid-template-columns`、`grid-template-rows`、`grid-gap` (en-US)
* Inclusive Components: Card
居中一个元素
======

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
在这份指南中你将了解到把一个盒子居中放置在另一个之中的方法。在弹性盒子模型（flexbox）出现之前，要做到同时垂直与水平居中是很困难的，而现在利用盒子对齐属性（Box Alignment）就很直截了当了。

![居中对齐在较大盒子内的元素](/zh-CN/docs/Web/CSS/Layout_cookbook/Center_an_element/cookbook-center.png)

需求
--

把一个项目同时垂直与水平居中地放置在另一个盒子中。

指南
--

下载这份示例

做出选择
----

要将一个盒子居中放置在另一个之中，我们需要让作为容器的盒子变成伸缩容器。再将 `align-items` 设置为 center 来实现块向轴（block axis）上的居中，并把 `justify-content` 设置为 center 来实现行向轴（inline axis）上的居中。

将来我们可能不需要将父容器设置为伸缩容器就可以居中元素，因为此处使用的“盒子对齐”属性也被指定为适用于区块布局。然而，当前在区块布局上对盒子对齐属性的支持仍然是有限的，因此目前使用伸缩盒子来实现居中还是最可靠的方法。

浏览器兼容性
------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

MDN 上相关的资源
----------

* 弹性盒中的盒对齐方式（Box Alignment）
* CSS 盒对齐指南
面包屑导航
=====

Baseline Widely available
-------------------------

This feature is well established and works across many devices and browser versions. It’s been available across browsers since September 2020.

* Learn more
* See full compatibility
* Report feedback
面包屑导航通过提供返回起始页面的面包屑轨迹，帮助用户了解他们在网站中所处的位置。

![与分隔符一同显示的链接](/zh-CN/docs/Web/CSS/Layout_cookbook/Breadcrumb_Navigation/breadcrumb-navigation.png)

要求
--

这些项通常以行内方式显示，并带有分隔符，以指示各个页面之间的层次结构。

指南
--

下载这份示例

**备注：** 上述示例使用了两个选择器来向每个除了首项 `li` 元素以外插入内容。也可以仅用一个选择器达到目标：


```css
.breadcrumb li:not(:first-child)::before {
  content: "→";
}
```


这种解决方案使用了更加复杂的选择器，但所需规则较少。你可以自由选择更想要的解决方案。

做出选择
----

这种模式使用一个简单的弹性布局摆布，展示了一行 CSS 如何为我们提供导航。分隔符是由 CSS 内容生成属性添加的，你也可以将其换成其他想要的分隔符（样式）。

无障碍考虑
-----

我使用了 `aria-label` 和 `aria-current` (en-US) 属性来帮助用户理解这个导航的结构，以及当前页面在结构中的位置。详情请参见相关链接。

注意通过 `content` 添加的箭头 `→` 也会暴露在屏幕阅读器或盲文显示器中。

浏览器兼容性
------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

参见
--

* CSS 弹性盒子布局
* 提供面包屑路径
* 使用 aria-current 属性
粘性页脚
====

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
粘性页脚模式是指当页面内容不足以填满视口高度时，页脚会“粘附”在视口底部的一种模式。在本教程中，我们将介绍创建粘性页脚的几种技术。

![粘性页脚被推到盒子底部](/zh-CN/docs/Web/CSS/Layout_cookbook/Sticky_footers/cookbook-footer.png)

要求
--

粘性页脚模式需要满足以下要求：

* 当内容不足以填满视口时，页脚粘附在视口底部。
* 如果页面内容超过视口底部，页脚会正常地位于内容下方。
实践指南
----

下载此示例

**备注：** 在这个示例和接下来的示例中，我们使用一个设置为 `min-height: 100%` 的 wrapper，以便我们的实时示例工作。你也可以通过在 `<body>` 上设置 `min-height` 为 `100vh`，然后将其用作网格容器来实现全页面的效果。

做出选择
----

在上面的示例中我们使用 CSS 网格布局来实现粘性页脚。`.wrapper` 的最小高度为 `100%`，这意味着它与所在的容器一样高。然后我们创建一个单列网格布局，包含三行，每个布局部分占一行。

网格自动放置会按照源顺序放置我们的项目，因此页眉进入第一个自动调整大小的轨道，主要内容进入 `1fr` 轨道，页脚进入最后一个自动调整大小的轨道。`1fr` 轨道将占据所有可用空间，因此会增长以填补空白。

替代方法
----

如果你需要兼容不支持网格布局的浏览器，你还可以使用弹性盒子来创建粘性页脚。

弹性盒子示例与前一个示例相似，但我们在 `.wrapper` 上使用 `display:flex` 而不是 `display:grid`；我们还将 `flex-direction` 设置为 `column`。接着，我们将主要内容设置为 `flex-grow: 1`，将其他两个元素设置为 `flex-shrink: 0`——当内容填充主区域时，这可以防止它们缩小。

浏览器兼容性
------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

MDN 上的资源
--------

* 网格布局的基本概念
打印
==

有时，你的网站或应用程序可能希望改善用户在打印内容时的体验。有几种可能的情况：

* 你希望根据纸张的大小和形状调整布局。
* 你希望使用不同的样式来增强纸上内容的外观。
* 你希望使用更高分辨率的图像以获得更好的效果。
* 你想调整打印的用户体验，比如在打印开始前呈现一个特殊格式的内容版本。

你可能还希望管理打印过程的其他情况，但这些都是最常见的场景。本文提供了一些提示和技术帮助你更好地打印 web 内容。

使用打印样式表
-------

将以下内容添加到你的 `<head>` 标签。


```html
<link href="/path/to/print.css" media="print" rel="stylesheet" />
```

使用媒体查询和 @page 改善布局
------------------

你可以使用 CSS `@media` at 规则为网页设置打印在纸上和显示在屏幕上时的不同外观。`print` 选项可以设置打印内容时使用的样式。

将其添加到你的样式表末尾。请注意，特殊性和优先级规则仍然适用：


```css
@media print {
  /\* 你所有打印的样式都放在这里 \*/
  #header,
 #footer,
 #nav {
    display: none !important;
  }
}
```


你还可以使用 `@page` at 规则修改打印页面的外观，包括页面的尺寸、方向和边距。`@page` at 规则可用于定位打印输出中的所有页面或页面的特定子集。

检测打印请求
------

浏览器发送 `beforeprint` 和 `afterprint` 事件让内容确定打印何时发生。你可以用它来调整打印过程中显示的用户界面（例如在打印过程中显示或隐藏用户界面元素）。

示例
--

以下是一些常见示例。

### 完成后自动关闭窗口

以下示例将在用户打印其内容后关闭窗口：


```js
window.addEventListener("afterprint", () => self.close);
```

### 无需打开弹出窗口即可打印外部页面

如果你想在不打开弹窗的情况下打印外部页面，可以使用隐藏的 `<iframe>` 元素（请参阅：HTMLIFrameElement），在用户打印其内容后自动将其移除。下面是一个可能的示例，它将打印一个名为 `externalPage.html` 的文件：

#### HTML


```html
<button id="print\_external">打印外部页面！</button>
```


#### JavaScript


```js
function setPrint() {
  const closePrint = () => {
    document.body.removeChild(this);
  };
  this.contentWindow.onbeforeunload = closePrint;
  this.contentWindow.onafterprint = closePrint;
  this.contentWindow.print();
}

document.getElementById("print\_external").addEventListener("click", () => {
  const hideFrame = document.createElement("iframe");
  hideFrame.onload = setPrint;
  hideFrame.style.display = "none"; // 隐藏 iframe
  hideFrame.src = "external-page.html";
  document.body.appendChild(hideFrame);
});
```

参见
--

* `window.print`
* `beforeprint` 事件
* `afterprint` 事件
* 媒体查询
* `@media`
* CSS 分页媒体模块
使用编程方法测试媒体查询
============

DOM 提供了通过编程方法来获得媒体查询结果的特性。这是通过 `MediaQueryList` 接口和它的方法来实现的。创建了 `MediaQueryList` 对象之后，就可以通过它来检查查询结果，或者设置事件监听器，在查询结果发生变化时自动接收到通知。

创建媒体查询列表
--------

在获取查询结果前，首先要创建查询列表，也就是 `MediaQueryList` 对象来存放媒体查询。为了实现这个目的，可以使用 `window.matchMedia` 方法。

举个例子，设置一个用来判断设备的旋转方向（横屏还是竖屏）的查询列表：


```js
var mediaQueryList = window.matchMedia("(orientation: portrait)");
```

检查查询结果
------

一旦创建了媒体查询列表，你就可以通过检查它的 `matches` 属性来获取相应的查询结果，上述属性会直接返回查询结果：


```js
if (mediaQueryList.matches) {
  /\* 设备的旋转方向为纵向 portrait \*/
} else {
  /\* 设备的旋转方向不是纵向，也就是横向 landscape \*/
}
```

接收查询提醒
------

如果你需要持续观察查询结果值的变化情况，那么，注册一个监听器比手动检查查询结果要高效很多。要注册监听器，只要在 `MediaQueryList` 对象上使用 `addListener()` 方法，并使用一个回调函数作为其参数。这样，就通过实现 `MediaQueryListListener` (en-US) 接口指定了一个监听器。每当查询结果发生变化，比如从 `true` 变为 `false` 时，就会调用一遍传入的回调函数。


```js
// 创建查询列表
const mediaQueryList = window.matchMedia("(orientation: portrait)");

// 定义回调函数
function handleOrientationChange(mql) {
  // ...
}

// 先运行一次回调函数
handleOrientationChange(mediaQueryList);

// 为查询列表注册监听器，同时将回调函数传给监听器
mediaQueryList.addListener(handleOrientationChange);
```


上述代码创建了一个屏幕方向的测试查询列表 `mediaQueryList`，并且添加了事件监听器。需要注意的是，当我们添加监听后，我们其实直接调用了一次监听。这会让我们的监听器以目前设备的屏幕方向来初始化判定代码。换句话说，如果我们代码中设定设备处于竖屏模式，而实际上它在启动时处于横屏模式，那么我们在后面的判定就会出现矛盾。

然后，我们就能在 `handleOrientationChange()` 方法中检查查询结果，比如，可以设置屏幕方向变化后的逻辑处理代码：


```js
function handleOrientationChange(evt) {
  if (evt.matches) {
    /\* The viewport is currently in portrait orientation \*/
  } else {
    /\* The viewport is currently in landscape orientation \*/
  }
}
```

终止查询通知
------

如果不再需要再接收媒体查询值变化的相关通知，那么，只要调用 `MediaQueryList` 的 `removeListener()` 方法，就可以方便地移除监听：


```js
mediaQueryList.removeListener(handleOrientationChange);
```

浏览器兼容性
------

### MediaQueryList 接口

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

另见
--

* Media queries (en-US)
* `window.matchMedia()`
* `MediaQueryList`
* `MediaQueryListListener` (en-US)