syntax - CSS：层叠样式表

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


指南：媒体对象 - 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
媒体对象是 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.


分离式导航菜单 - 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/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 弹性盒布局


卡片 - 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


居中一个元素 - 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
在这份指南中你将了解到把一个盒子居中放置在另一个之中的方法。在弹性盒子模型（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 盒对齐指南


面包屑导航 - 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 属性


Contribute a recipe - CSS：层叠样式表

Contribute a recipe
===================

如果你愿意为 Layout Cookbook 贡献示例文件，那么本页将通过阐释步骤指导你发布示例。

好的 recipe 是怎样的？
---------------

\*\*任何有用的 web 设计模式的最简版本。\*\*你 CSS 文件中的每一行代码都应该有助于演示该模式，省去无用的部分就是为了能让示例显得完美。这种想法就是，某个人既能将这种模式应用在网站中，又可以保持自己的风格。

发布 recipe 的步骤
-------------

一份 recipe 包括以下内容：

1. 一个动态的示例，存储在 CSS Examples GitHub repo 之上。
2. 这份示例的可供下载版本，同样也存储在 CSS Examples repo 之上。
3. 该网站的某个页面在 CSS layout cookbook 上应详细说明：
    1. 要求
    2. recipe
    3. 做出的选择
    4. 任何有用的反馈或供选择的方法
    5. 任何无障碍访问问题
    6. 浏览器兼容性
    7. 其他资源
### 1. 建立自己的模式

在将示例转换为 recipe 之前，先将你的模式创建成为一个简单的 HTML 页面。想想看你要展示的是什么，并使这个想法尽可能简单。避免使用特殊的 CSS 约定（例如 BEM），因为并非每个人都熟悉这些约定，反而会使他们将事情做得看起来要比预期中的更复杂。

确保 HTML 和 CSS 有效，并将其在一种以上的浏览器上进行测试。如果你使用的 CSS 属性并非广受支持，那也没关系！你可以在创建页面时包含浏览器支持信息。在某些情况下，创建示例的第二个版本可能会有帮助，其中包括回退支持。

### 2. 创建一个动态示例

The live examples that you can see on cookbook pages and elsewhere on MDN allow visitors to play with the code and change relevant parts without being overwhelmed with all of the code needed. You recipe will be demonstrated by way of one or more examples.

Fork the CSS Examples repo and then take a look in the `css-cookbook` folder. There is a cookbook-template.html file you can copy as a starting point. Save this in the css-cookbook directory with a name that makes sense for your pattern. The template is commented to help you add the various parts to the right place.

The important parts of this are as follows.

There is a stylesheet for styles for the editor panels, and some basic body styling, and a JavaScript file included for the editor functionality. Leave these files as they are.

There are two style blocks in the head. The first are for things that a visitor to the page does not need to change to play with the example. The second is for any of the items they might want to play with in the live example. We typically add all of our CSS from like example in the first block, then choose which sets of rules we need to move down to the second block. The rules in the second block should be those that are fundamental to the pattern, perhaps those where a user could make a change to a CSS value and see the pattern update.

You need to add the HTML for your component twice. First inside the section with a class of preview, then inside the textarea `playable-html`.

Your editable CSS, from the second block in the head, also needs to be copied into the `playable-css` section.

A simple worked example is center.html, which is embedded on the page Center an element. You can use this to see how to add the various bits correctly.

If you have forked the repo and therefore have our CSS and JavaScript files alongside your example, if you open up your live example in the browser you should see everything working exactly as it will when included in a page.

#### Useful tips

1. Do not indent the CSS and HTML inside the textareas; instead bump it up against the start of the lines. This will look better when it is rendered.
2. If you have any required images, pop them into the directory with the examples. Or you are welcome to use any already there.
3. You can adjust the height of the textareas by changing the height in the inline styles.
### 3. 创建一份可供下载的版本

As the examples include all of our live example code, we want to offer visitors a simple example without all of that included. Make a copy of your live example with --download appended. For example, center.html, has a download version named `center--download.html`. This file will be similar to your initial example. It should be a basic version of your pattern as a single HTML page. It can be handy to include the body CSS rules that are in our included stylesheet, if you take a look at cookbook-template--download.html, these are included as a starting point.

### 4. 用你的示例发起 Pull 请求

Make a PR on the CSS Examples repo. This way we can help you with any changes to the example that may be needed before you create your page, plus the example will need to be live to be included some it makes sense to create it first. Include in your PR an explanation of the pattern and what you are demonstrating.

### 5. 创建你的页面

Once your example is merged you can create your page. You will need an MDN account to do so with page creation permissions, and you can then create the page as a subpage of the CSS Cookbook page. There is a template for Cookbook pages here (en-US).

The template explains what should be part of each section, and you can refer to other cookbook examples for more help. If you click to edit any of those pages then you will be able to see things such as the macros used to embed compat data, and live examples.

If you need general guidance on using the MDN wiki, see the help pages available here.

If you need to ask any questions, or want someone to take a look at your page then the MDN Discourse forum is a good place to do this, or chat with us on Matrix.

See also
--------

* Cookbook page template (en-US)
* CSS Examples repo


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

![粘性页脚被推到盒子底部](/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 上的资源
--------

* 网格布局的基本概念


Column layouts - CSS：层叠样式表

Column layouts
==============

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
你可能经常需要创建一个包含几个栏目的布局，css 提供了几个方法来实现它。使用 Grid, Flexbox 或者 Multi-column layout 都取决于你想要实现什么目标，在这篇 recipe 中我们会探讨这些内容
 ![three different styles of layouts which have two columns in the container.](/zh-CN/docs/Web/CSS/Layout_cookbook/Column_layouts/cookbook-multiple-columns.png)

Requirements
------------

你也许会为你的栏目实现多种设计样式：

* 连续的内容线，分成报纸式的专栏
* 被划分成几个高度相等的栏目的一行
* 按行和列排列的多行列
The recipes
-----------

为了达到你的需要你需要选择不同的布局方式

### A continuous thread of content — multi-column layout

If you create columns using multi-column layout your text will remain as a continuous stream filling each column in turn. The columns must all be the same size, and you are unable to target an individual column or the content of an individual column.

如果你使用多列布局来创建列，则文本会以连续流的形式依次填满每个列。这些列必须大小相同，并且你不能够针对单个列或者单个列的内容

You can control the gaps between columns with the `column-gap` property, and add a rule between columns using `column-rule`.

你可以使用`column-gap` 控制列之间的距离，并且使用`column-rule`.增加列之间的规则

**备注：** Download this example

在以下情况使用多列布局：

* 你想要你的文本看起来想报纸那种排版布局。
* 你有一组要分成列的小项目。
* 你不需要单独为指定的列写样式。
### A single row of items with equal heights — flexbox

Flexbox can be used to break content into columns by setting `flex-direction` to `row`, however flexbox targets the elements inside the flex container and will place each direct child into a new column. This is a different behavior to what you saw with multicol.

Flexbox 通过设置 row 的`flex-direction` ，可以用于将内容分成列，然而，flexbox 的目标是 flex 容器内的元素，并将把每个直接的子元素放到一个新列中，这是与 multicol 不同的地方。

There is currently no way to add a rule between flex items, and browser support for the `column-gap` and `row-gap` properties is limited. Therefore to create gaps between items use a margin.

目前没有办法可以在 flex 的 item 中添加规则，而且浏览器对`column-gap` 和 `row-gap`的支持是有限的，因此使用 margin 属性来创建 item 之间的间距

**备注：** Download this example

Flexbox can also be used to create layouts where the flex items wrap onto new rows, by setting the `flex-wrap` property on the container to `wrap`. These new flex lines will distribute space along that line only — the items in the new line will not line up with items in the line above, as you'll see in the example below. This is why flexbox is described as one-dimensional. It is designed for controlling layout as a row or a column, but not both at the same time.

Flexbox 还可以被用来创建 flex items 自动换行的布局，通过给 flex container 设置 `flex-wrap` 属性为 wrap. 这些新的 flex 行只会沿该行分配空间——新行中的项不会与上面行中的项对齐，你可以在下面的例子中看到。这就是为什么 flexbox 被描述为一维。他是为了将布局控制为行或列，但不是同时控制行和列。

**备注：** Download this example

Use flexbox:

* For single rows or columns of items. 设置一行或者一列中的 items
* When you want to do alignment on the cross axis after laying out your items. 当你想在横轴上对齐你的 items
* When you are happy for wrapped items to share out space along their line only and not line up with items in other lines.
### Lining items up in rows and columns — grid layout

If what you want is a layout where items line up in rows and columns then you should choose CSS Grid Layout. Grid Layout works on the direct children of the grid container in a similar way to the manner in which flexbox works on the direct children of the flex container, however with CSS Grid you can line your items up in rows and columns — it is described as two-dimensional.

如果你想要 items 在行和列进行布局，你应该选择 Grid Layout. Grid Layout 作用于 grid container 的 直接子元素类似于 flexbox。但是你可以在行和列两方面来控制他（flex 只能在行或者列）。

**备注：** Download this example

Use Grid:

* For multiple rows or columns of items.
* When you want to be able to align the items on the block and inline axes.
* When you want items to line up in rows and columns.
浏览器兼容性
------

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

Resources on MDN
----------------

* Guide to Multi-column Layout
* Guide to Flexbox
* Guide to CSS Grid Layout


打印 - CSS：层叠样式表

打印
==

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

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

你可能还希望管理打印过程的其他情况，但这些都是最常见的场景。本文提供了一些提示和技术帮助你更好地打印 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 分页媒体模块


使用编程方法测试媒体查询 - 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)


使用媒体查询 - CSS：层叠样式表

使用媒体查询
======

**媒体查询**（**Media queries**）非常实用，尤其是当你想要根据设备的大致类型（如打印设备与带屏幕的设备）或者特定的特征和设备参数（例如屏幕分辨率和浏览器视窗宽度）来修改网站或应用程序时。

媒体查询常被用于以下目的：

* 有条件的通过 `@media` 和 `@import` at-rules 用CSS 装饰样式。
* 用 `media=` 属性为`<style>`, `<link>`, `<source>`和其他HTML元素指定特定的媒体类型。如：
```

<link rel="stylesheet" src="styles.css" media="screen" />
<link rel="stylesheet" src="styles.css" media="print" />
```

* 使用`Window.matchMedia()` 和`MediaQueryList.addListener()` 方法来测试和监控媒体状态。

**备注：** 本页的例子使用 CSS `@media` 的方式来说明目的，但是对于所有类型的媒体查询，基本语法均相同。

语法
--

每条媒体查询语句都由一个可选的*媒体类型*和任意数量的*媒体特性*表达式构成。可以使用多种*逻辑操作符*合并多条媒体查询语句。媒体查询语句不区分大小写。

当媒体类型（如果指定）与在其上显示文档的设备匹配并且所有媒体功能表达式都计算为 true 时，媒体查询将计算为 true。涉及未知媒体类型的查询始终为 false。

**备注：** 即使媒体查询返回 false，带有媒体查询附加到其`<link>`标记的样式表仍将下载。但是，除非查询结果变为 true，否则其内容将不适用。

定位媒体类型
------

媒体类型描述了给定设备的一般类别。尽管通常在设计网站时会考虑屏幕，但你可能希望创建针对特殊设备（例如打印机或基于音频的屏幕阅读器）的样式。例如，此 CSS 针对打印机：

```css
@media print { ... }
```

你还可以定位多个设备。例如，此`@media`规则使用两个媒体查询来同时定位屏幕和打印设备

```css
@media screen, print { ... }
```

有关所有媒体类型的列表，请参见Media types。由于它们仅以非常广泛的术语描述设备，因此只有少数几种可用。要定位更具体的属性，请改用*媒体功能*。

定位媒体特性
------

媒体功能描述了给定的user agent的输出设备或环境的特定特征。例如，你可以将特定样式应用于宽屏显示器，使用鼠标的计算机，或应用于在弱光条件下使用的设备。当用户的主要输入机制（例如鼠标）可以悬停在元素上时，如下为一个示例：

```css
@media (hover: hover) { ... }
```

许多媒体功能都是*范围功能*，这意味着可以在它们前面加上“最小”或“最大”来表示“最小条件”或“最大条件”约束。例如，仅当你的浏览器的viewport宽度等于或小于 12450px 时，此 CSS 才会应用样式：

```css
@media (max-width: 12450px) { ... }
```

如果你在未指定值的情况下创建媒体功能查询，则该样式将全部被应用，只要该查询的值不为零（或在 Level 4 中为`none`）即可。例如，此 CSS 将适用于任何带有彩色屏幕的设备：

```css
@media (color) { ... }
```

如果某个功能不适用于运行浏览器的设备，则涉及该媒体功能的表达式始终为 false。例如，将不会使用嵌套在以下查询中的样式，因为没有语音专用设备具有屏幕长宽比：

```css
@media speech and (aspect-ratio: 11/5) { ... }
```

有关更多媒体功能media feature示例，请参阅每个特定功能的参考页。

创建复杂查询
------

有时你可能想创建一个取决于多个条件的媒体查询。这就是*逻辑运算符*使用的场景：`not`，`and`，和 `only`。此外，你可以将多个媒体查询合并到一个*逗号分隔的列表*中。这使你可以在不同情况下应用相同的样式。

在前面的示例中，我们已经看到 `and` 运算符用于将媒体类型与媒体功能分组。`and` 运算符还可以将多个媒体功能组合到单个媒体查询中。同时，`not` 运算符会否定媒体查询，从而基本上颠倒了它的正常含义。`only` 运算符可防止较早的浏览器应用样式。

**备注：** 在大多数情况下，默认情况下，如果未指定其他类型，则使用`all`媒体类型。但是，如果使用`not`或`only`运算符，则必须显式指定媒体类型。

### 结合多种类型和特性

`and`关键字将媒体功能与媒体类型或其他媒体功能组合在一起。此示例结合了两种媒体功能，以将样式限制为宽度至少为 30 em 的横向的设备：

```css
@media (min-width: 30em) and (orientation: landscape) { ... }
```

要将样式限制为带有屏幕的设备，可以将媒体功能链接到`screen`媒体类型：

```css
@media screen and (min-width: 30em) and (orientation: landscape) { ... }
```

### 测试多重查询

当用户的设备与各种媒体类型，功能或状态中的任何一种匹配时，可以使用逗号分隔的列表来应用样式。例如，如果用户设备的最小高度为 680px 或为纵向模式的屏幕设备，则以下规则将应用其样式：

```css
@media (min-height: 680px), screen and (orientation: portrait) { ... }
```

以上面的示例为例，如果用户使用的打印机的页面高度为 800 像素，则 media 语句将返回 true，因为将应用第一个查询。同样，如果用户使用的是纵向模式的智能手机，并且视口高度为 480px，则将应用第二个查询，并且 media 语句仍将返回 true。

### 反转查询的含义

`not`关键字会反转整个媒体查询的含义。它只会否定要应用的特定媒体查询。 （因此，它不会应用于以逗号分隔的媒体查询列表中的每个媒体查询。）`not`关键字不能用于否定单个功能查询，只能用于否定整个媒体查询。看看以下`not`关键字的例子：

```css
@media not all and (monochrome) { ... }
```

所以上述查询等价于：

```css
@media not (all and (monochrome)) { ... }
```

而不是：

```css
@media (not all) and (monochrome) { ... }
```

再看另一个例子，如下媒体查询：

```css
@media not screen and (color), print and (color) { ... }
```

等价于：

```css
@media (not (screen and (color))), print and (color) { ... }
```

### 提升老版本浏览器兼容性

`only`关键字可防止不支持带有媒体功能的媒体查询的旧版浏览器应用给定的样式。*它对现代浏览器没有影响。*

```css
@media only screen and (color) { ... }
```

版本 4 中的语法改进
-----------

媒体查询 4 级规范对语法进行了一些改进，以使用具有“范围”类型（例如宽度或高度，减少冗余）的功能进行媒体查询。级别 4 添加了用于编写此类的查询范围上下文。例如，使用最大宽度`max-` 功能，我们可以编写以下代码：

**备注：** 媒体查询 4 级规范在现代浏览器中具有合理的支持，但某些媒体功能并未得到很好的支持。有关更多详细信息，请参见 `@media` browser compatibility table。

```css
@media (max-width: 30em) { ... }
```

在媒体查询 4 级规范可以这样写：

```css
@media (width <= 30em) { ... }
```

使用`min-`和`max-`可以测试一个在两个值之间的宽度

```css
@media (min-width: 30em) and (max-width: 50em) { ... }
```

用 4 级语法书写如下

```css
@media (30em <= width <= 50em ) { ... }
```

媒体查询 4 级规范还添加了用**and**, **not**, 和 **or**实现的完整的布尔运算来合并媒体查询的方法。

### 使用 `not`否定一个特性

在媒体功能周围使用`not()`会否定查询中的该特性。例如，如果设备没有悬停功能，则`not(hover)`将被匹配：

```css
@media (not(hover)) { ... }
```

### 用 `or`测试多个特性

你可以使用`or`测试多个功能之间的匹配，如果任何功能为 true，则解析为 true。例如，以下查询测试具有单色显示或悬停功能的设备：

```css
@media (not (color)) or (hover) { ... }
```

参见
--

* 使用编程方法测试媒体查询
* CSS Animations Between Media Queries
* Extended Mozilla media features (en-US)
* Extended WebKit media features


Flex 项排序 - CSS：层叠样式表

Flex 项排序
========

Flexbox 和 Grid 等新的布局方法为内容的顺序控制提供了可能。在本文中，我们将介绍使用 Flexbox 时如何更改内容的视觉顺序。我们还将从无障碍的角度考虑重新排序项目的影响。

反转项目的显示
-------

`flex-direction` 属性有如下四个值：

* `row`
* `column`
* `row-reverse`
* `column-reverse`

前两个值使项目保持与它们在文档源顺序中出现的顺序相同，并从起始行开始顺序显示它们。

![The items are displayed in a row starting on the left.](/zh-CN/docs/Web/CSS/CSS_flexible_box_layout/Ordering_flex_items/basics1.png)

![The items are displayed as a column starting from the top ](/zh-CN/docs/Web/CSS/CSS_flexible_box_layout/Ordering_flex_items/align10.png)

后两个值通过调换开始和结束行来进行项目的反转。

![The items are displayed in reverse order starting on the right-hand line.](/zh-CN/docs/Web/CSS/CSS_flexible_box_layout/Ordering_flex_items/align9.png)

![The items are displayed in a column in reverse order starting at the bottom line.](/zh-CN/docs/Web/CSS/CSS_flexible_box_layout/Ordering_flex_items/align11.png)

请记住，起始行与写入模式有关。上面两个示例说明了 `row` 和 `row-reverse` 在从左到右的语言是怎么工作的如英语。如果你使用的是右到左的语言，如阿拉伯语，则 `row` 的起始行将在右边， `row-reverse` 起始行会在左边。

![Flex containers with Arabic letters showing how row starts from the right hand side and row-reverse from the left.](/zh-CN/docs/Web/CSS/CSS_flexible_box_layout/Ordering_flex_items/order-rtl.png)

这看起来似乎是一种以相反顺序显示事物的简洁方式，但是你应该注意，这些项目只以相反顺序显示。在这个问题上，规范说明如下：

>
> “注意：Flex 布局的重新排序功能仅会影响视觉渲染，保留语音顺序和基于源顺序的导航。这使作者能够操纵视觉呈现，同时保持非 CSS UA 和线性模型（例如语音和顺序导航）的原始顺序不变。” - Ordering and Orientation
>
>
>

如果你的项目是链接或者用户可以选择的其他元素，那么选项卡的顺序就是这些项目在文档源中出现的顺序，而不是你的视觉顺序。

如果使用反向值或以其他方式重新排序项，则应考虑是否实际需要更改源中的逻辑顺序。该规范继续警告不要使用重新排序来修复源代码中的问题：

>
> “作者不得使用 flex-flow / flex-direction 的顺序或反向值来代替正确的源顺序，因为这会破坏文档的无障碍。*”*
>
>
>

**备注：** 近几年来，Firefox 出现了一个错误，即它会尝试遵循视觉顺序而不是源顺序，从而使其行为与其他浏览器不同。现在，此问题已得到解决。你应始终将源顺序作为文档的逻辑顺序，因为所有最新的用户代理都将遵循该规范并遵循该规范。

在下面的实时示例中，我添加了一种焦点样式，以便当你从一个链接到另一个标签时，可以看到突出显示的样式。如果使用`flex-direction`更改顺序，则可以看到制表符顺序如何继续遵循源中列出的项目的顺序。

与更改`flex-direction`的值不会更改项目导航到的顺序相同，更改此值不会更改绘制顺序。它仅是项目的视觉反转。

`order` 属性
----------

除了颠倒显示弹性项目的顺序之外，你还可以使用`order` 属性指定单个项目并更改其在视觉顺序中的显示位置。.

`order`属性旨在按顺序排列项目。这意味着为项目分配了代表其组的整数。然后，按照该整数（最低的值）首先按照视觉顺序放置项目。如果多个项目具有相同的整数值，则在该组中按照源顺序对项目进行布局。

例如，我有 5 个弹性条目，并按如下所示分配`order`值：

* Source item 1: `order: 2`
* Source item 2: `order: 3`
* Source item 3: `order: 1`
* Source item 4: `order: 3`
* Source item 5: `order: 1`

这些项目将按以下顺序显示在页面上：

* Source item 3: `order: 1`
* Source item 5: `order: 1`
* Source item 1: `order: 2`
* Source item 2: `order: 3`
* Source item 4: `order: 3`

![Items have a number showing their source order which has been rearranged.](/zh-CN/docs/Web/CSS/CSS_flexible_box_layout/Ordering_flex_items/order-property.png)

你可以在下面的实时示例中使用这些值，并查看如何更改顺序。另外，尝试将`flex-direction`更改为`row-reverse`，看看会发生什么—切换了起始行，以便从相反的一侧开始排序。

弹性项目默认 `order` 值为 `0`, 因此整数值大于 0 的项目，将会显示在那些未指定 `order` 值的项目之后。

你还可以按顺序使用负值，这很有用。如果要先显示一个项目，并保持所有其他项目的顺序不变，则可以将该项目的顺序设为`-1`。由于该值小于 0，因此始终会首先显示该项目。

在下面的实时代码示例中，我使用 Flexbox 布置了项目。通过更改在 HTML 中为其分配了类`active`，你可以更改首先显示的项目，你可以更改首先显示哪个项目，因此在布局顶部变为全宽，而在其下方显示其他项目。

这些项目以规范中描述的顺序修改的文档顺序显示。在显示项目之前，将考虑 order 属性的值。

Order 还会更改项目的绘制顺序; 对于`order`较低的项目将首先绘制，对于`order`值较高的项目将随后绘制。

order 属性和无障碍
------------

使用 order 属性对于无障碍具有与使用`flex-direction`更改方向完全相同的含义。使用`order`可以更改项目的绘制顺序和外观。它不会更改项目的顺序导航顺序。因此，如果用户在项目之间切换，他们可能会发现自己以非常混乱的方式在布局中跳跃。

通过浏览此页面上的任何实时示例，你可以了解订单如何给不使用某种指点设备的任何人带来奇怪的体验。要了解有关视觉顺序和逻辑顺序的这种分离以及它为无障碍带来的一些潜在问题的更多信息，请参见以下资源。

* Flexbox and the keyboard navigation disconnect
* HTML Source Order vs CSS Display Order
* The Responsive Order Conflict for Keyboard Focus
order 使用示例
----------

有时在某些地方，弹性项目的逻辑顺序和可视顺序与视觉顺序是分开的，这很有帮助。仔细使用`order`属性可以使一些有用的通用模式易于实现。

你可能有一个设计，也许是显示新闻的卡片。新闻项的标题是突出显示的关键内容，并且如果用户在标题之间使用键盘制表符按键（tab）以查找要阅读的内容，则可能是用户可能会跳转到的元素。该卡还带有日期；我们要创建的最终设计就是这样。

![A design component with a date, then heading and then content.](/zh-CN/docs/Web/CSS/CSS_flexible_box_layout/Ordering_flex_items/order-card.png)

视觉上，日期显示在源中标题上方。但是，如果卡是由屏幕阅读器读出的，则我希望标题先公布，然后再公布日期。我们可以使用`order`属性来做到这一点。

The card is going to be our flex container, with `flex-direction` set to column. I then give the date an `order` of `-1`. This pulls it up above the heading.

该卡将成为我们的伸缩容器，`flex-direction`设置为 column。然后，我将日期定为`-1`。这将其拉到标题上方。

这些小的调整是`order`属性有意义的情况。保持逻辑顺序为文档的阅读和制表符顺序，并以最易于访问和结构化的方式进行维护。然后使用`order`进行纯粹的视觉设计调整。这样做时，请注意不要重新排序在用户四处浏览时可能由键盘访问的项目。尤其是在使用较新的布局方法时，应确保浏览器测试包括仅使用键盘而不是鼠标或触摸屏来测试站点。你将快速查看你的开发选择是否使绕过内容变得困难。


弹性盒子与其他布局方法的联系 - CSS：层叠样式表

弹性盒子与其他布局方法的联系
==============

在本文中，我们将了解弹性盒子（Flexbox）如何与所有其他 CSS 模块相适应。如果你想学习 flexbox，我们将一起找出需要注意的规范和 flexbox 与一些其他模块不同的原因。

**备注：** CSS 1 和 CSS 2 是一个单一的整体规范，其中所有 CSS 都定义在一个文档中。随着 CSS 成为一种功能更加丰富的语言，各个部分有不同的发展速度，如何维护一个庞大的规范就成了问题。因此现在的 CSS 是模块化的，不同的 CSS 模块有不同的规范，一起构成了现在的 CSS。这些模块之间相互关联，并且处于不同的开发阶段。

box alignment 模块
----------------

许多人开始关注 flexbox 的最初原因是在 flex 容器中能够很好的对齐其中的元素。flexbox 可以设置在其交叉轴以及主轴上的对齐属性。

这些属性最开始出现在 flexbox 规范中，现在已经成为Box Alignment 规范的一部分。这个规范详细说明了在所有布局中（不仅仅是 flexbox）对齐属性是如何起作用的。对齐属性用于设置元素对齐方式和沿轴的空间分配。

之所以在 flexbox 规范和 box alignment 模块规范中都有对对齐属性的详细描述，是为了确保 flexbox 规范的完成不会受 box alignment 模块规范的影响，因为后者需要详细说明所有的布局类型中的对齐方法。flexbox 规范中有一条注释指出将来一旦 Box Alignment Level 3 完成，它将会取代 flexbox 规范中的相关定义：

>
> “注意：虽然对齐属性是在 CSS Box Alignment [CSS-ALIGN-3] 中定义的，但“Flexible Box Layout”在此处重现了相关属性的定义，以免形成规范性的依赖关系，而这可能会减慢规范的发展。这些属性仅适用于 Flex 布局，直到 CSS Box Alignment Level 3 完成并定义其对其他布局模式的效果；此外，在 Box Alignment 模块中定义的任何新值都将应用于 Flexible Box Layout；换句话说，一旦 Box Alignment 模块完成，其中的相关定义将取代此处的定义。”
>
>
>

在本系列的后续文章（在 flex 容器中对齐元素）中，我们将彻底研究 Box Alignment 属性如何应用于 flex 元素。

### gap 属性

属性`row-gap` 和 `column-gap`，其简写为`gap`，近期添加到了盒子布局规范中。这些属性（名称为`grid-row-gap`, `grid-column-gap` and `grid-gap`）最初定义在 CSS 网格布局中。但是他们被重命名并移入盒子布局规范。这样的话，所有的布局方法都可以使用这些属性。不过在浏览器实现 Flex 的这些属性之前只能通过`margin` 来控制元素之间的间隙距离。

Writing Modes
-------------

In the Basic concepts of flexbox article, I explained that flexbox is **writing mode aware**. Writing modes are fully detailed in the CSS Writing Modes specification, which details how CSS supports the various different writing modes that exist internationally. We need to be aware of how this will impact our flex layouts as writing mode changes the direction that blocks are laid out in our document. Understanding **block** and **inline** directions is key to new layout methods.

It is worth noting that we might want to change the writing mode of our document for reasons other than publishing content in a language that uses a different writing mode. See this article for a full description of writing modes and ways to use them, both for content in other languages and for creative reasons.

### The writing modes

The writing modes specification defines the following values of the `writing-mode` property, which serve to change the direction that blocks are laid out on the page, to match the direction that blocks lay out when content is formatted in that particular writing mode. You can change the live example below to these modes in order to see what happens to the flex layout.

* `horizontal-tb`
* `vertical-rl`
* `vertical-lr`
* `sideways-rl`
* `sideways-lr`

Note that `sideways-rl` and `sideways-lr` have support only in Firefox currently. There are also some known issues with regard to `writing-mode` and flexbox. You can see more information on browser support in the MDN documentation for writing-mode. However if you are planning on using writing modes in your layout, carefully testing the results is advisable — not least because it would be easy to make things hard to read!

Note that you would not normally use CSS and the `writing-mode` property to change an entire document to another writing mode. This would be done via HTML, by adding a `dir` and `lang` attribute to the `html` element to indicate the document language and default text direction. This would mean that the document would display correctly even if CSS did not load.

Flexbox and other layout methods
--------------------------------

The flexbox specification contains a definition of what happens if an item uses another layout method and then becomes a flex item. For example, if an item is floated and then its parent becomes a flex container. Or, how a flex container behaves as part of layout.

An element set to `display: flex` behaves in most ways like any other block level container that establishes a containing block. Floats will not intrude, and the containers' margins will not collapse.

With regard to flex items, if an item was floated or cleared and then becomes a flex item due to the parent having `display: flex` applied, the floating and clearing will no longer happen, and the item will not be taken out of normal flow in the way that floats are. If you have used the `vertical-align` property, as used with `inline-block` or table layout for alignment, this will no longer affect the item and you can use the alignment properties of flexbox instead.

In this next live example the child elements have been floated, and then their container has had `display: flex` added. If you remove `display: flex`, you should see that the `.box` element collapses as we have no clearing applied. This demonstrates that the float is happening. Re-apply `display: flex` and the collapsing does not happen. This is because the items no longer have a float applied, as they have been transformed into flex items.

Flexbox and Grid Layout
-----------------------

CSS Grid Layout and Flexbox generally act in the same way with regards to overwriting other methods. You might however want to use flexbox as a fallback for grid layout, as there is better support for flexbox in older browsers. This approach works very well. If a flex item becomes a grid item, then the `flex` properties that may have been assigned to the child elements will be ignored.

You can use the Box Alignment properties across both layout methods, so using flexbox as a fallback for grid layout can work very well.

### Flex and grid — what's the difference?

A common question is to ask what the difference is between Flexbox and CSS Grid Layout — why do we have two specifications that sometimes appear to be doing the same thing?

The most straightforward answer to this question is defined in the specifications themselves. Flexbox is a one-dimensional layout method whereas Grid Layout is a two-dimensional layout method. The example below has a flex layout. As already described in the Basic concepts article, flex items can be allowed to wrap but, once they do so, each line becomes a flex container of its own. When space is distributed flexbox does not look at the placement of items in other rows and tries to line things up with each other.

If we create a very similar layout using Grid, we can control the layout in both rows and columns.

These examples point to another key difference between these layout methods. In Grid Layout you do the majority of sizing specification on the container, setting up tracks and then placing items into them. In flexbox, while you create a flex container and set the direction at that level, any control over item sizing needs to happen on the items themselves.

In some cases you could happily use either layout method, but as you become confident with both you will find each one suiting different layout needs, and you will end up with both methods in your CSS. There is rarely a right or wrong answer.

As a rule of thumb, if you are adding widths to flex items in order to make items in one row of a wrapped flex container line up with the items above them you really want two-dimensional layout. In this case it is likely that the component would be better laid out using CSS Grid Layout. It isn't the case that you should use flexbox for small components and grid layout for larger ones; a tiny component can be two dimensional, and a large layout can be represented better with layout in one dimension. Try things out — we have a choice in layout method for the first time, so take advantage of it.

For more comparisons of grid and flexbox see the article Relationship of Grid Layout to other layout methods. This article details many of the ways that Grid Layout differs from flex layout, and demonstrates some of the extra functionality you get when using Grid Layout such as layering of items on the grid. This may also help in your decision as to which layout method to use.

Flexbox and display: contents
-----------------------------

The `contents` value of the `display` property is a new value that is described in the spec as follows:

>
> “The element itself does not generate any boxes, but its children and pseudo-elements still generate boxes as normal. For the purposes of box generation and layout, the element must be treated as if it had been replaced with its children and pseudo-elements in the document tree.”
>
>
>

This value of `display` controls box generation, and whether the element should generate a box that we can style and see on the page, or whether instead the box it would normally create should be removed and the child elements essentially moved up to participate in whatever layout method the parent would have been part of. This is much easier to see with an example.

In the following live example I have a flex container with three child elements. One of these flex items has two elements nested inside it, which would not ordinarily participate in flex layout. Flex layout only applies to the direct children of a flex container.

By adding `display: contents` to the wrapper around the nested elements, you can see that that item has disappeared from the layout, allowing the two sub-children to be laid out as if they were direct children of the flex container. You can try removing the `display: contents` line to see it return.

Note that this only removes the box from the layout; the sub-children don't become direct children in any other way. You can see that as I have used a direct child selector to add the background and borders to the flex items, this has not been applied to our nested children. They have been laid out as flex items, but as they are not direct children they do not get the other styling.

**警告：** Use of `display: contents` will also remove the element from the accessibility tree – screen readers will not see what's inside, just the same as if you used `display: none`. Use of `contents` should only be for presentational, not content, elements.

Also, having removed the box you cannot then use it to — for example — add a background colour behind the nested sub children. If you remove `display: contents` in this live example you will see that the direct child we are removing has an orange background colour. This also disappears when the box disappears.

Browser support for `display:contents` is limited and required for this demo to work. Firefox supports `display: contents` already, and the value is being implemented in Chrome. Once there is better browser support this feature will be very useful in circumstances where you need the markup for semantic reasons but do not want to display the box that it would generate by default.


控制弹性元素在主轴上的比例 - CSS：层叠样式表

控制弹性元素在主轴上的比例
=============

在这篇指南中我们将探索应用于弹性（flex）元素的三个属性，它们能使我们在主轴方向上控制弹性元素的尺寸和伸缩性——`flex-grow`、`flex-shrink` 和 `flex-basis`。充分了解这些属性如何与伸张和缩小的元素一起工作是掌握弹性盒子（flexbox）的关键所在。

预览
--

这三个属性控制弹性元素的以下几个方面的灵活性：

* `flex-grow`：该元素获得（伸张）多少正可用空间（positive free space）？
* `flex-shrink`：该元素要消除（收缩）多少负可用空间（negative free space）？
* `flex-basis`：在该元素未伸张和收缩之前，它的大小是多少？

以上属性通常用简写属性 `flex` 表达。下面的代码设置 `flex-grow` 属性值为 `2`、`flex-shrink` 属性值为 `1`、`flex-basis` 属性值为 `auto`。

```css
.item {
  flex: 2 1 auto;
}
```

如果你阅读过文章弹性盒子的基本概念，那么你应该已经对这些属性有了初步了解。为了让你能明白当你在用它们的时候浏览器在做什么，我们将进一步探讨它们。

工作于主轴的重要概念
----------

在考虑 flex 属性如何在主轴方向上控制比率之前，有一些概念值得我们去深究。这涉及到弹性元素在任何伸缩之前的自然尺寸，以及可用空间（free space）的概念

### 弹性元素的尺寸

为了计算出有多少可用空间能用于放置弹性元素，浏览器必须知道这个元素有多大。它是如何解决没有应用绝对单位的宽度和高度的弹性元素？

在 CSS 中还有 `min-content` 和 `max-content` 这两个概念；这两个关键字可以用来代替长度单位。

例如下面的例子，我们有两段包含一个文本字符串的段落。第一段设置了 `min-content` 的宽度。在支持这个关键字的浏览器你可以看见文本已尽可能抓住机会来自动换行，使之变得尽可能小且没有溢出。这就是该字符串的 `min-content` 大小。本质上讲，字符串中最长的单词决定了大小。

第二段设置了 `max-content` 值，其与前者相反。它会变得尽可能大，没有自动换行的机会。如果容器太窄，它就会溢出其自身的盒子。

记住这种行为，以及 `min-content` 和 `max-content` 所产生的影响，我们将在后文中探索 `flex-grow` 和 `flex-shrink`。

### 正负可用空间

去谈论这些属性之前我们需要理解**正负可用空间**（positive and negative free space）的概念。当一个弹性容器有正可用空间时，它就有更多的空间用于在容器内显示弹性元素。比如说，如果我们有 500px 宽的容器，`flex-direction` 属性值为 `row`，三个 100px 宽的弹性元素，那么我们还有 200px 的正可用空间，如果我们想要填充整个容器，则可将其分配到元素中。

![该图像展示了在元素显示后剩余的空间。](/zh-CN/docs/Web/CSS/CSS_flexible_box_layout/Controlling_ratios_of_flex_items_along_the_main_axis/basics7.png)

当弹性元素的自然尺寸加起来比弹性容器内的可用空间大时，我们产生了负可用空间。比如我们有一个像上面那样的 500px 宽的容器，但是三个弹性元素每个都为 200px 宽，那我们就一共需要 600px 宽，因此就有了 100px 的负可用空间。这可以从弹性元素中删除以使其能适应容器。

![元素从容器中溢出](/zh-CN/docs/Web/CSS/CSS_flexible_box_layout/Controlling_ratios_of_flex_items_along_the_main_axis/ratios1.png)

我们需要理解正可用空间的分配和负可用空间的移除，这样才能理解 flex 属性。

下面的例子我们会将属性 `flex-direction` 设置为 row，因此元素的尺寸仅来自于它们的宽度。我们通过比较所有元素和容器的宽度来计算正负可用空间。你同样可以使用 `flex-direction: column`，这样主轴将变为列，然后你需要比较元素和它们所在容器的高度来计算正负可用空间。

flex-basis 属性
-------------

`flex-basis` 属性在任何空间分配发生之前初始化弹性元素的尺寸。此属性的初始值为 `auto`。如果 `flex-basis` 设置为 `auto`，浏览器会先检查元素的主尺寸是否设置了绝对值再计算出它们的初始值。比如说你已经给你的元素设置了 200px 的宽，则 200px 就是这个元素的 `flex-basis`。

如果你的元素为自动调整大小，则 `auto` 会解析为其内容的大小。此时你所熟知的 `min-` 和 `max-content` 大小会变得有用，弹性盒子会将元素的 `max-content` 大小作为 `flex-basis`。下面的实例可以证明这一点。

在这个示例中我们创建了一些固定的盒子，它们的 `flex-grow` 和`flex-shrink` 都设置为 `0`。这里我们看看第一个元素，显式地设置其宽度为 150px，作为主尺寸，即设置 `flex-basis` 为 150px，而另外两个元素没有设置宽度而是根据它们内容的宽度设置尺寸。

除了 `auto` 关键字以外，你还可以使用 `content` 关键字作为 `flex-basis` 的值。这会导致即使元素设置了宽度，`flex-basis` 还是会根据内容大小进行设置。你也可以通过设置 flex-basis 为 `auto` 并确保你的元素没有设置宽度来达到相同的效果，以便它能自动调整大小。

空间分配时，如果你想要弹性盒子完全忽略元素的尺寸就需要设置 `flex-basis` 为 `0`。这显式地说明弹性盒子可用抢占所有空间，并按比例进行分配。随着我们继续关注 `flex-grow`，我们将看到这方面的例子。

flex-grow 属性
------------

`flex-grow` 属性指定了**弹性增长因子**（flex grow factor），这决定了在分配正可用空间时，弹性元素相对于弹性容器中的其余弹性元素的增长程度。

如果你所有的元素都设置了相同的 `flex-grow` 属性值，那么空间将会在它们之间平均分配。如果你想要这种情形，通常你需要使用 `1` 作为值，但如果你喜欢你还可以将它们的 `flex-grow` 都设置为 `88`、`100` 或 `1.2`——这只是个比例。如果 flex-grow 的值全部相同，并且在弹性容器中还有正可用空间，那么它就会被平均地分配给所有元素。

### 结合 `flex-grow` 和 `flex-basis`

根据 `flex-grow` 和 `flex-basis` 的相互影响，有些东西会变得迷惑起来。让我们考虑三个不同内容大小的弹性元素的例子，并应用下列 `flex` 规则：

`flex: 1 1 auto;`

这个例子中设置 `flex-basis` 的值为 `auto` 且没有设置它们的宽，因此它们是自动调整大小的。这意味着弹性盒子的大小取决于元素的 `max-content` 大小。在布局完元素之后，弹性容器中还有一些正可用空间，展示在这幅图片的阴影区域中：

![图像使用阴影区域展示了正可用空间](/zh-CN/docs/Web/CSS/CSS_flexible_box_layout/Controlling_ratios_of_flex_items_along_the_main_axis/ratios2.png)

我们使用与内容大小相等的 `flex-basis`，以便从总可用空间（弹性容器的宽度）中减去可用分配空间，然后剩余空间在每个元素之间平均分配。我们比较大的元素最终会变得更大，因为它一开始就有一个比较大的尺寸，即使它与其他元素具有相同的分配空间：

![在元素之间分配的正空间](/zh-CN/docs/Web/CSS/CSS_flexible_box_layout/Controlling_ratios_of_flex_items_along_the_main_axis/ratios3.png)

如果你真正想要的是三个同样尺寸的元素，即使它们开始具有不同的尺寸，你应该使用这个：

`flex: 1 1 0;`

我们要说的是，为了我们的空间分配，元素的尺寸计算值是 0——所有空间都用来争夺，并且所有元素具有相同的 `flex-grow` 值，它们每个都获得相等的空间分配。最终结果是三个等宽的可伸缩元素。

尝试在这个实例中将 `flex-grow` 的值从 1 更改为 0 以查看不同的行为：

### 为元素设置不同的 flex-grow 因子

我们对 `flex-grow` 和 `flex-basis` 如何工作的理解使我们能够通过分配不同的 `flex-grow` 值来进一步控制我们单个元素的大小。如果我们设置 `flex-basis` 值为 `0` 则所用空间都可以被分配，我们可以给每个弹性元素分配不同的 `flex-grow` 因子。在下面的示例中，我们会使用下面的值：

* 设置第一个元素的值为 `1`。
* 设置第二个元素的值为 `1`。
* 设置第三个元素的值为 `2`。

`flex-basis` 值为 `0` 意味着可用空间会根据以下规则分配。我们需要将弹性增长因子相加，然后将弹性容器的正可用空间总量除以该值，在这个例子中为 4。而后我们就可以根据每一个的值分配空间——第一个元素得到一个单位、第二个元素得到一个单位、第三个元素得到二个单位。也就是说第三个元素是第一个和第二个元素的两倍。

记住你要在这里使用正值。这是一个元素和其他元素之间的比例。你还可以使用更大的数字或者更小的数字——这由你自己决定。把上例中分配的值更改为 `.25`、`.25` 和 `.50` 并去测试——你会得到相同的结果。

flex-shrink 属性
--------------

`flex-shrink` 属性指定了**弹性收缩因子**（flex shrink factor），它确定在分配负可用空间时，弹性元素相对于弹性容器中其余弹性元素收缩的程度。

该属性用于处理浏览器计算弹性元素的 `flex-basis` 值，并发现它们太大以至于无法适应弹性容器的情形。只要 `flex-shrink` 有正值，元素就会收缩以至于它们不会溢出容器。

因此 `flex-grow` 用于添加可用空间，而 `flex-shrink` 减少空间来使盒子适应它们的容器而不溢出。

下一个示例中我们的弹性容器有三个元素，我们已经给它们每一个设置了 200px 的宽度，并且设置容器为 500px 宽。设置 `flex-shrink` 为 `0` 的元素不允许收缩，以使它们溢出了盒子。

改变 `flex-shrink` 值为 `1` 你会发现每个元素都收缩了同样大小的量，现在所有元素都适应盒子。这样做后它们已变得比它们的初始宽度还小。

### 结合 `flex-shrink` 和 `flex-basis`

你可以看见 `flex-shrink` 和 `flex-grow` 工作的一样好。但是它们有两个原因使它们不*完全*一样。

即使它微不足道，但规范中的定义内容是 `flex-shrink` 对于负空间和 `flex-grow` 对于正空间不完全相同的原因：

>
> “注意：当分配负空间时，弹性收缩因子乘以弹性元素的基本尺寸。这会根据元素能够缩小的比例分配负空间。例如，在较大的元素明显缩小之前，较小的子元素不会缩小到 0。”
>
>
>

第二个原因是在负可用空间消除期间弹性盒子会阻止小的元素缩小到 0。这些元素会以 `min-content` 的大小进行铺设——这个大小是它们利用任何可以利用的自动换行机会后所变成的。

在下面的例子中，在 `flex-basis` 解析为内容大小的位置你会看到 `min-content` 的铺设。如果你改变弹性容器的宽度——比如增加到 700px 宽，再减少弹性元素的宽度，你会看到前两个元素将换行，但是它们绝不会小于 `min-content` 的大小。随着盒子变得越来越小，第三个元素随后从空间中溢出。

在实践中，收缩行为会倾向于给你合理的结果。你通常不希望自己的内容完全消失，或者文本框比自己的最小内容要小，因此上述规则对于需要缩小以适应容器的内容的合理行为而言是有意义的。

### 给元素设置不同的 `flex-shrink` 因子

在 `flex-grow` 值相同的情形下，你可以给弹性元素设置不同的 `flex-shrink` 因子。假如你想让一个元素比它的兄弟元素收缩的更快或更慢，或者不再收缩，这会改变它的默认行为。

在下面的示例中第一个元素设置 `flex-shrink` 的值为 1、第二个为 `0`（因此它将不会收缩）、第三个为 `4`。第三个元素比第一个收缩的更快。任意设置不同的值——你可以给 `flex-grow` 使用小数或者大一点的数。选择对于你来说任意合理的数。

掌握弹性元素的大小
---------

真正理解弹性元素如何工作的关键是理解有多少东西参与影响弹性元素。思考以下方面，哪些是我们在这些指南中已经讨论过了的：

### 什么设置了元素的基本大小？

1. `flex-basis` 设置为 `auto`，且元素设置了宽度吗？如果设置了，元素的大小将会基于设置的宽度。
2. `flex-basis` 设为了 `auto` 或 `content`（在支持的浏览器中）? 如果设置了，元素的大小为原始大小。
3. `flex-basis` 是不为 `0` 的长度单位吗？如果是这样，那这就是元素的大小。
4. `flex-basis` 设为了 `0`？如果是这样，则元素的大小不在空间分配计算的考虑之内。
### 我们有可用空间吗？

元素没有正可用空间就不会增长，没有负可用空间就不会缩小。

1. 如果我们把所有元素的宽度相加（如果在列方向工作则为高度），总和是否小于容器的总宽度（或高度）？如果是这样，那么你有正可用空间，并且 `flex-grow` 会发挥作用。
2. 如果我们把所有的元素的宽度相加（如果在列方向工作则为高度），总和是否大于容器的总宽度（或高度）？如果是这样，那么你有负可用空间，并且 `flex-shrink` 会发挥作用。
### 分配空间的其他方式

如果我们不想将空间添加到元素中，记住你可以在弹性容器中使用指南中所描述的对准属性来处理元素之间或元素周围的空闲空间。`justify-content` 属性能够在元素之间或元素周围分配空闲空间。你还可以在弹性元素上使用自动边距（auto margin）来吸收空间并在元素之间创建间距。

随着所有的弹性工具的使用，你会发现大多数任务都可以实现，尽管在开始时可能需要一些实验。


掌握弹性物件的包装 - CSS：层叠样式表

掌握弹性物件的包装
=========

Flexbox 被设计为一维的布局工具，这意味着在处理元素布局方式时只能设计为行或者设计为列——两者不能兼顾。然而 Flex 拥有一种将 flex 元素包围在新的一行内的特性，创建一个新的行如果设置了 `flex-direction` 为 `row` 以及创建新的一列如果设置了 `flex-direction` 为 `column`。在这篇教程中，我将解释这个特性的内部工作原理，以及它设计的目的是什么和在什么情况下要使用 CSS 网格布局而不是弹性盒子。

把物件包装起来
-------

`flex-wrap` 属性的初始值是`nowrap`。这就意味着如果你有一组的对其容器而言太宽的弹性物件，它们就会溢出。如果你想要一旦它们变得太宽就换行，你必须给 `flex-wrap` 属性添加`wrap`值，或者，用`row wrap` 或 `column wrap` 值作用于`flex-flow`的速写。

物件接着就会在容器内换行。在接下来的例子里，我有 10 个`160px`的`flex-basis`物件，它们都具备伸展和收缩能力。一旦第一行达到了没有足够空间放置额外 160 像素物件的点，一个新的弹性行就会被建立，一直这样直到所有的物件被放置。因为物件可以伸展，它们会扩展大于 160 像素从而完整地填充一行。如果在最后一行只有 1 个物件，它就将拉长了充满整行。

我们可以看到相同的事情也发生在列上。容器会需要有一个高度让物件可以开始换行并且制造新的列，并且物件会拉伸高度来填满每一个列。

包装和弹性方向
-------

当结合 `flex-direction` 属性，包装就如你所期待的方式工作。如果 `flex-direction` 被设置成 row-reverse 那么物件就会从容器的底边开始并且以行的反向顺序堆叠自身。

注意反向只能发生在行内、行的方向。我们从右面开始然后跳到第二行再从右边开始。我们没有在两个方向上都反向，从容器底部上来的反向！

一维布局介绍
------

正如我们上面例子中所见到的，如果我们的物件被允许伸展和收缩，当最后一行或一列有较少的物件时，那么这些物件就会伸展从而填满可用空间。

弹性盒子中并没有方法告诉一行里的物件和上一行里的物件对齐——每个弹性行表现得就像一个新的弹性容器。它在主要坐标轴上处理空间分布。如果只有一个物件，并且这个物件允许伸展，他就会填充坐标轴，就好像你有一个单物件的弹性容器。

如果你想在二维方向上布局，那么你很可能想要网格布局。我们可以比较我们上面的行换行例子和 CSS 网格版本的布局来看一下区别。一下实时的例子使用 CSS 网格布局来构建一个布局，它具有至少 160 像素的列的布局，在所有列之间分配额外的空间。

这就是一维和二维布局的区别。在一维的方式里就像弹性盒子，我们仅仅控制行或者列。在二维布局里就像网格，我们同时控制两个。如果你想按行分布空间，使用弹性盒子。如果不是，使用网格。

基于弹性盒子的网格系统如何工作？
----------------

基本上基于弹性盒子的网格系统，是通过将弹性盒子带回到我们所熟悉的基于浮层布局的世界，来工作的。如果你对弹性物件设置了百分比的宽度——`flex-basis` 或是通过对物件增加宽度同时让 `flex-basis` 的值保持为`auto`——你就能获得二维布局的印象。你可以在下面的例子中看到这样的运作。

这里我有设置 `flex-grow` 和 `flex-shrink` 为 `0` 来使固定弹性物件，并且接着使用百分比来控制弹性，正如我们在浮动布局里所使用的那样。

如果你需要弹性物件在坐标轴上对齐，用这样的方法来控制宽度就能达到这个效果。在大多数的情况下，向弹性物件增加款宽度的做法演示了你可能会比将组件切换成网格布局提供的更好体验。

在物件之间建立间隔
---------

当包装弹性物件的时候，间隔它们的需要很可能被提出。在当下我们还没有任何针对弹性盒子的块对齐模块间隔属性的实现。在未来我们将能够对弹性盒子简单的使用 `row-gap` 和 `column-gap` 就如我们在 CSS 网格里做的。当下你会需要使用边距来达成这个要求。

你可以从下面一个实时的例子里看到，为了建立间隔并且不在容器的边缘建立间隔，我们需要在弹性容器自身上使用负边距。弹性容器的任何一条边移入第二个包装从而使得负边距可以将包装的元素拉回来。

正是这个间隔属性的需求，一旦实现，将为我们解决问题。适当的间隙只发生在物件的内边缘。

折叠物件
----

弹性盒子标准详述了如果一个弹性物件在物件上被设置了 `visibility: collapse` 时应当发生什么。参见对于`visibility`属性的 MDN 文档。这份标准描述了如下的表现：

>
> “定义可见性：在一个弹性物件上的折叠导致它成为一个折叠弹性物件，在一个表行或者表列制造一个类似于 visibility:collapse 的效果：折叠弹性物件整个地从渲染中移除，但在底层保留了一个“支撑”从而保持了弹性行的跨界尺寸的稳定。因此，如果一个弹性容器仅包含一个弹性行，动态地折叠或者展开物件可能改变弹性容器的主尺寸，但是这样确保了跨界尺寸上没有影响以及不会导致页面其余的布局“晃动”。动态行包装在折叠后会被重做的，所以，包含多行的弹性容器的跨界尺寸是可能变化的。” - 折叠物件
>
>
>

如果你想要针对弹性物件使用 JavaScript 来显示和隐藏内容的例子，这样的表现是很有用的。这个标准里的例子演示了一个这样的模式。

在下面的实时例子里，我有一个非包装的弹性容器。第三个物件相比其他的有跟多的内容被设置 `visibility: collaps` 并且因此弹性盒子会保持一个高度的结构来满足显示物件的需要。如果你从 CSS 里移除`visibility: collapse` 或是将值改变为 `visible`，你会看到物件消失了并且空间在非包装的物件之间重新分配；弹性容器的高度不应该改变。

**备注：** 对下面的两个例子使用 Firefox 浏览器，因为 Chrome 和 Safari 会把折叠处理为隐藏。

当处理多行弹性容器时你会需要理解包装会在折叠*后*被重做。所以浏览器需要重做包装的行为来计算新的还留在行内方向里的被折叠物件的空间。

这意味着物件可能在和他们所开始的不同的行里结束。在一个物件在被显示和隐藏的场景下，它很可能导致物件结束在不同的行里。

我已经在下一个实时例子里构建了这样的表现。你可以看到基于折叠物件的位置，伸展改变了它们所在的行。如果你加入更多的内容到第二个物件里，一旦获得了足够多的内容它就改变了行。然后首行仅仅成为和单行文本一样的高度。

如果这对你的布局造成了麻烦，可能就需要重新考虑这个结构，比如，将每一行放置到分开的弹性容器里从而它们不会跨行。

### `visibility: hidden` 和 `display: none` 的区别

当你为了隐藏一个物件去设置 `display: none` ，物件就被格式化的页面结构移除。在实际中的意义就是技术器忽略了它，类似转换的事情不会运行。使用 `visibility: hidden` 保持了格式化结构的框，这十分有用，它仍旧表现的像是布局中的一部分即便用户看不到它。


Flexbox 典型用例 - CSS：层叠样式表

Flexbox 典型用例
============

在这个文档中，我们将看一些常见 flexbox 的用例—这些都是比其他布局更合理的方法。

**为什么选择 flexbox？**

在浏览器完美支持的环境中，你选择使用 flexbox 的原因是你希望把一堆元素不是放在这个方向就是那个方向。因为在放置元素过程中，你想控制元素在那个方向的维度，或者控制他们彼此之间的间距。flexbox 就是为此设计的。. 又可以阅读Relationship of Flexbox to other layout methods来了解更多关于 flexbox 和 CSS Grid 布局的区别，在这篇文章里面，我们会讨论 flexbox 如何运用与 CSS 整体布局。

在现实中，为了便于对齐，我们通常会选择用 Flexbox 作为替代品，来完成即使用 Grid 布局更好的情况。一旦盒子对齐（Box Alignment）被盒模型所实行，这种情况就会得到改善。在这个教程中，我们会介绍一些会在现在使用 flexbox 的用例。

导航
--

导航的一个常见特征，就是使用水平条的样式去呈现一系列元素。这一模式看起来很简单，但是在 flexbox 出现之前却是很难实现的。它成为一个最简单的 flexbox 示例，可以被被看成是 flexbox 理想的使用场景。

当我们有一组元素需要水平排列展示，很可能在末尾会多出一些空间。我们需要决定如何去处理这些额外的空间，通常有多种不同的方案。我们要么在元素外部展示这些空间即使用间距或包裹的方式来分隔开不同元素，要么将空间吸收至元素内部即需要一个方法来允许元素拉伸以占满额外空间。

### 在元素外部处理空间分布

为了让多余的空间分布在多个元素之间或周围，我们使用 flexbox 中相应的对齐属性以及 `justify-content` 属性。你可以通过 Aligning Items in a flex container 来阅读更多关于这个专门用来处理主轴（main axis）对齐的属性。

在下面的示例中，我们让各元素都展示为其自身的尺寸，通过使用 `justify-content: space-between` 使元素之间拥有相同的空间。你可以通过 `space-around` 的值来改变空间分布的方式，在浏览器支持的环境下还可以使用 `space-evenly`。你也可以使用 `flex-start` 让空间展示在所有元素末尾。使用 `flex-end` 让空间展示在所有元素之前， `center` 可以剧中所有元素。

### 让元素自己处理空间分布

导航的另一个不同模式是让元素自己去决定如何处理额外的空间，而不是将空间分布在它们之间。在这种情况下，我们使用 `flex` 属性来允许各元素彼此成比例的拉伸和收缩，正如 Controlling ratios of flex items along the main axis 所描述。

如果我想让导航中的所有元素都等宽，会使用 `flex: auto`，这是 `flex: 1 1 auto` 的简写形式。所有元素都在它们的 flex-basis 尺寸上进行自动的收缩。这意味着，较长的元素会获得更多的空间。因为 flex-basis 的值被设置为 0，所以所有空间都会被平均分配。

拆分导航
----

另一种在主轴上对齐元素的方式就是使用自动边距。这种方式将创造出一部分元素左对齐而另一部分右对齐的导航栏设计。

这儿我们使用在 Using auto margins for main axis alignment 这篇文章中介绍的自动边距技术。所有的元素在主轴上按照弹性盒布局的默认设定 `flex-start` 进行对齐，同时我们给那个需要右对齐的元素添加 `margin-left: auto;` 样式。你可以尝试将那个类名转移到其他元素上以改变（向右）分割作用的位置。

在这个例子里我们也为每个元素启用了 `margin` 属性来控制元素间的间隔，并给容器添加负边距以保证元素与容器的接洽处没有缝隙。在弹性盒布局实现盒式对齐规范中的 `gap` 属性前，如果我们想要控制元素的间隔就不得不使用使用边距属性。

元素居中
----

在弹性盒布局到来之前，开发者们曾开玩笑说网页设计中最难的部分是垂直居中。现在，使用弹性盒布局中的对齐属性，这会变得很简单，如下例所示。

你可以修改对齐方式，用 `flex-start` 使元素对齐到交叉轴的开始处或者用 `flex-end` 使元素对齐到交叉轴的结束处。

在未来，我们可能不需要为了元素的居中而创建一个弹性盒容器，因为盒对齐属性最终会在块布局中实现。但是现在，假如你想在一个元素中居中另一个，弹性盒布局是一个很好的选择。在上面的例子中，将一个元素放入弹性盒容器里之后，要么在容器中使用 `align-items`，要么在元素中使用 `align-self` 来达到所需的效果。

绝对底部
----

不管你使用的是弹性盒还是网格来进行布局，这些布局方式都只对弹性盒容器或者网格容器的（直接）子元素生效。这也意味着即使你的 `content` 长度不定，组件在高度上仍会充满整个弹性盒容器或者网格容器。但任何使用常规块布局的方法都会导致 `content` 内容较少时 `footer` 上升到 `content` 下方而不是容器的底部。
 ![Two card components showing that the internals of the component do not stretch with the wrapper.](/zh-CN/docs/Web/CSS/CSS_flexible_box_layout/Typical_use_cases_of_flexbox/flex-cards.png)

弹性盒就能解决常规块布局的问题。我们创建一个弹性盒容器，并启用 `flex-direction``: column` 。之后我们在 `content` 部分启用 `flex: 1`——`flex: 1 1 0` 的缩略形式，这个元素就可以在 `flex-basis` 为零的基础上伸缩。因为这是唯一一个可以延伸的元素，它会占据所有在弹性盒容器中可以占据的空间，同时将 `footer` 推至底部。如果你移除例子里的属性 `flex` 你就会看见 `footer` 回到 `content` 底部。

媒体对象
----

媒体对象是网页设计中的常见模式：这种模式下，一侧具有图片或其他元素，另一侧具有文本。理想情况下，媒体对象应该可以翻转：即把图片从左侧移动到右侧。

这种模式随处可见，用于评论、以及其他需要显示图片和描述的地方。使用 flexbox 可以允许包含图片的媒体对象部分从图片中获取其尺寸调整信息，并对媒体对象的主体进行弹性布局，以占用剩余空间。

在下面的实例中，你可以看到我们的媒体对象。使用对齐属性来将交叉轴上的元素对齐到`flex-start`，然后为`.content` flex 元素设置为`flex: 1`。与上面的列布局卡片模式一样，启用`flex: 1`表示此部分卡片可以延伸。

Some things that you might want to try in this live example relate to the different ways you might want to constrain the media object in your design.

为避免图片过大，可以在为图片添加`max-width`。由于媒体对象那一侧使用的是 flexbox 的初始值，它可以缩小但不会延伸，且其 `flex-basis` 值是 auto。应用于图片的任何`width` 或 max-width 将会成为 flex-basis。

```css
.image img {
  max-width: 100px;
}
```

你也可以允许双方按比例延伸和缩小。如果将两边都设置为`flex: 1`，它们从`flex-basis`为 0 增长和缩小，因此最终会得到两个大小相等的列。你可以将内容作为指南，并将其都设置为 `flex: auto`，这种情况下，它们将从内容的大小或直接应用于弹性元素的任何大小（例如图片的宽度）延伸和缩小。

```css
.media .content {
  flex: 1;
  padding: 10px;
}

.image {
  flex: 1;
}
```

You could also give each side different `flex-grow` factors, for example setting the side with the image to `flex: 1` and the content side to `flex: 3`. This will mean they use a `flex-basis` of `auto` but distribute that space at different rates according to the `flex-grow` factor you have assigned. The flex properties we use to do this are described in detail in the guide Controlling ratios of flex items along the main axis.

```css
.media .content {
  flex: 3;
  padding: 10px;
}

.image {
  flex: 1;
}
```

### Flipping the media object

To switch the display of the media object so that the image is on the right and the content is on the left we can use the `flex-direction` property set to `row-reverse`. The media object now displays the other way around. I have achieved this in the live example by adding a class of `flipped` alongside the existing `.media` class. This means you can see how the display changes by removing that class from the html.

Form controls
-------------

Flexbox is particularly useful when it comes to styling form controls. Forms have lots of markup and lots of small elements that we typically want to align with each other. A common pattern is to have an `<input>` element paired with a `<button>`, perhaps for a search form or where you simply want your visitor to enter an email address.

Flexbox makes this type of layout easy to achieve. I have contained my `<button>` and `<input>` field in a wrapper which I have given a border and set to `display: flex`. I then use the flex properties to allow the `<input>` field to grow, while the button does not grow. This means we have a pair of fields, with the text field growing and shrinking as the available space changes.

You could add a label or icon to the left as easily as we popped the button onto the right. I have added a label, and other than some styling for background colour I didn't need to change the layout. The stretchy input field now has a little less space to play with but it uses the space left after the two items are accounted for.

Patterns like this can make it much easier to create a library of form elements for your design, which easily accommodate additional elements being added. You are taking advantage of the flexibility of flexbox by mixing items that do not grow with those that do.

结论
--

当了解上面的这些示例时，你已经满怀希望的想象怎么找到最好的方式使用弹性盒子布局实现你想要的结果。大部分情况下，你拥有不止一种选择。将可以变化的内容和不能变化的混合在一起，通过内容来决定他们的大小或者允许弹性布局设置按比例分配空间。要因地制宜，对症下药。

先考虑一下用什么方法展示你的内容比较好，然后在了解怎么用弹性布局或其他布局方法实现你的想法。


flex 布局的基本概念 - CSS：层叠样式表

flex 布局的基本概念
============

Flexible Box 模型，通常被称为 flexbox，是一种一维的布局模型。它给 flexbox 的子元素之间提供了强大的空间分布和对齐能力。本文给出了 flexbox 的主要特性，更多的细节将在别的文档中探索。

我们说 flexbox 是一种一维的布局，是因为一个 flexbox 一次只能处理一个维度上的元素布局，一行或者一列。作为对比的是另外一个二维布局 CSS Grid Layout，可以同时处理行和列上的布局。

flexbox 的两根轴线
-------------

当使用 flex 布局时，首先想到的是两根轴线 — 主轴和交叉轴。主轴由 `flex-direction` 定义，另一根轴垂直于它。我们使用 flexbox 的所有属性都跟这两根轴线有关，所以有必要在一开始首先理解它。

### 主轴

主轴由 `flex-direction` 定义，可以取 4 个值：

* `row`
* `row-reverse`
* `column`
* `column-reverse`

如果你选择了 `row` 或者 `row-reverse`，你的主轴将沿着 **inline** 方向延伸。

![If flex-direction is set to row the main axis runs along the row in the inline direction.](/zh-CN/docs/Web/CSS/CSS_flexible_box_layout/Basic_concepts_of_flexbox/basics1.png)

选择 `column` 或者 `column-reverse` 时，你的主轴会沿着上下方向延伸 — 也就是 **block 排列的方向。**

![If flex-direction is set to column the main axis runs in the block direction.](/zh-CN/docs/Web/CSS/CSS_flexible_box_layout/Basic_concepts_of_flexbox/basics2.png)

### 交叉轴

交叉轴垂直于主轴，所以如果你的`flex-direction` (主轴) 设成了 `row` 或者 `row-reverse` 的话，交叉轴的方向就是沿着列向下的。

![If flex-direction is set to row then the cross axis runs in the block direction.](/zh-CN/docs/Web/CSS/CSS_flexible_box_layout/Basic_concepts_of_flexbox/basics3.png)

如果主轴方向设成了 `column` 或者 `column-reverse`，交叉轴就是水平方向。

![If flex-direction is set to column then the cross axis runs in the inline direction.](/zh-CN/docs/Web/CSS/CSS_flexible_box_layout/Basic_concepts_of_flexbox/basics4.png)

理解主轴和交叉轴的概念对于对齐 flexbox 里面的元素是很重要的；flexbox 的特性是沿着主轴或者交叉轴对齐之中的元素。

起始线和终止线
-------

另外一个需要理解的重点是 flexbox 不会对文档的书写模式提供假设。过去，CSS 的书写模式主要被认为是水平的，从左到右的。现代的布局方式涵盖了书写模式的范围，所以我们不再假设一行文字是从文档的左上角开始向右书写，新的行也不是必须出现在另一行的下面。

你可以在接下来的文章中学到更多 flexbox 和书写模式关系的详细说明。下面的描述是来帮助我们理解为什么不用上下左右来描述 flexbox 元素的方向。

如果 `flex-direction` 是 `row` ，并且我是在书写英文，那么主轴的起始线是左边，终止线是右边。

![Working in English the start edge is on the left.](/zh-CN/docs/Web/CSS/CSS_flexible_box_layout/Basic_concepts_of_flexbox/basics5.png)

如果我在书写阿拉伯文，那么主轴的起始线是右边，终止线是左边。

![The start edge in a RTL language is on the right.](/zh-CN/docs/Web/CSS/CSS_flexible_box_layout/Basic_concepts_of_flexbox/basics6.png)

在这两种情况下，交叉轴的起始线是 flex 容器的顶部，终止线是底部，因为两种语言都是水平书写模式。

之后，你会觉得用起始和终止来描述比左右更合适，这会对你理解其他相同模式的布局方法（例如：CSS Grid Layout）起到帮助的作用。

Flex 容器
-------

文档中采用了 flexbox 的区域就叫做 flex 容器。为了创建 flex 容器，我们把一个容器的 `display` 属性值改为 `flex` 或者 `inline-flex`。完成这一步之后，容器中的直系子元素就会变为 **flex 元素**。由于所有 CSS 属性都会有一个初始值，所以 flex 容器中的所有 flex 元素都会有下列行为：

* 元素排列为一行 (`flex-direction` 属性的初始值是 `row`)。
* 元素从主轴的起始线开始。
* 元素不会在主维度方向拉伸，但是可以缩小。
* 元素被拉伸来填充交叉轴大小。
* `flex-basis` 属性为 `auto`。
* `flex-wrap` 属性为 `nowrap`。

这会让你的元素呈线形排列，并且把自己的大小作为主轴上的大小。如果有太多元素超出容器，它们会溢出而不会换行。如果一些元素比其他元素高，那么元素会沿交叉轴被拉伸来填满它的大小。

### 更改 flex 方向 flex-direction

在 flex 容器中添加 `flex-direction` 属性可以让我们更改 flex 元素的排列方向。设置 `flex-direction: row-reverse` 可以让元素沿着行的方向显示，但是起始线和终止线位置会交换。

把 flex 容器的属性 `flex-direction` 改为 `column` ，主轴和交叉轴交换，元素沿着列的方向排列显示。改为 `column-reverse` ，起始线和终止线交换。

下面的例子中，`flex-direction` 值为 `row-reverse`。尝试使用其他的值 `row` ，`column`，`column-reverse`，看看内容会发生什么改变。

用 flex-wrap 实现多行 Flex 容器
------------------------

虽然`flexbox`是一维模型，但可以使我们的`flex`项目应用到多行中。在这样做的时候，你应该把每一行看作一个新的`flex`容器。任何空间分布都将在该行上发生，而不影响该空间分布的其他行。

为了实现多行效果，请为属性`flex-wrap`添加一个属性值`wrap`。现在，如果你的项目太大而无法全部显示在一行中，则会换行显示。下面的实时例子包含已给出宽度的项目，对于`flex`容器，项目的子元素总宽度大于容器最大宽度。由于`flex-wrap`的值设置为`wrap`，所以项目的子元素换行显示。若将其设置为`nowrap`，这也是初始值，它们将会缩小以适应容器，因为它们使用的是允许缩小的初始`Flexbox`值。如果项目的子元素无法缩小，使用`nowrap`会导致溢出，或者缩小程度还不够小。

参见掌握弹性物件的包装指南，以了解更多有关弹性物件包装的信息。

简写属性 flex-flow
--------------

你可以将两个属性 `flex-direction` 和 `flex-wrap` 组合为简写属性 `flex-flow`。第一个指定的值为 `flex-direction` ，第二个指定的值为 `flex-wrap`.

在下面的例子中，尝试将第一个值修改为 `flex-direction` 的允许取值之一，即 `row`, `row-reverse`, `column` 或 `column-reverse`, 并尝试将第二个指定值修改为 `wrap` 或 `nowrap`。

flex 元素上的属性
-----------

为了更好地控制 flex 元素，有三个属性可以作用于它们：

* `flex-grow`
* `flex-shrink`
* `flex-basis`

在这里，我们只会大概介绍一下它们的用法，更详细的细节请参阅其他的文章。

在考虑这几个属性的作用之前，需要先了解一下 **可用空间** available space 这个概念。这几个 flex 属性的作用其实就是改变了 flex 容器中的可用空间的行为。同时，可用空间对于 flex 元素的对齐行为也是很重要的。

假设在 1 个 500px 的容器中，我们有 3 个 100px 宽的元素，那么这 3 个元素需要占 300px 的宽，剩下 200px 的可用空间。在默认情况下，flexbox 的行为会把这 200px 的空间留在最后一个元素的后面。

![This flex container has available space after laying out the items.](/zh-CN/docs/Web/CSS/CSS_flexible_box_layout/Basic_concepts_of_flexbox/basics7.png)

如果期望这些元素能自动地扩展去填充满剩下的空间，那么我们需要去控制可用空间在这几个元素间如何分配，这就是元素上的那些 `flex` 属性要做的事。

### Flex 元素属性：`flex-basis`

`flex-basis` 定义了该元素的**空间大小**（**the size of that item in terms of the space**），flex 容器里除了元素所占的空间以外的富余空间就是**可用空间** available space。该属性的默认值是 `auto` 。此时，浏览器会检测这个元素是否具有确定的尺寸。在上面的例子中，所有元素都设定了宽度（width）为 100px，所以 `flex-basis` 的值为 100px。

如果没有给元素设定尺寸，`flex-basis` 的值采用元素内容的尺寸。这就解释了：我们给只要给 Flex 元素的父元素声明 `display: flex` ，所有子元素就会排成一行，且自动分配小大以充分展示元素的内容。

### Flex 元素属性：`flex-grow`

`flex-grow` 若被赋值为一个正整数，flex 元素会以 `flex-basis` 为基础，沿主轴方向增长尺寸。这会使该元素延展，并占据此方向轴上的可用空间（available space）。如果有其他元素也被允许延展，那么他们会各自占据可用空间的一部分。

如果我们给上例中的所有元素设定 `flex-grow` 值为 1，容器中的可用空间会被这些元素平分。它们会延展以填满容器主轴方向上的空间。

flex-grow 属性可以按比例分配空间。如果第一个元素 `flex-grow` 值为 2，其他元素值为 1，则第一个元素将占有 2/4（上例中，即为 200px 中的 100px）, 另外两个元素各占有 1/4（各 50px）。

### Flex 元素属性： `flex-shrink`

`flex-grow`属性是处理 flex 元素在主轴上增加空间的问题，相反`flex-shrink`属性是处理 flex 元素收缩的问题。如果我们的容器中没有足够排列 flex 元素的空间，那么可以把 flex 元素`flex-shrink`属性设置为正整数来缩小它所占空间到`flex-basis`以下。与`flex-grow`属性一样，可以赋予不同的值来控制 flex 元素收缩的程度——给`flex-shrink`属性赋予更大的数值可以比赋予小数值的同级元素收缩程度更大。

在计算 flex 元素收缩的大小时，它的最小尺寸也会被考虑进去，就是说实际上 flex-shrink 属性可能会和 flex-grow 属性表现的不一致。因此，我们可以在文章《控制 Flex 子元素在主轴上的比例》中更详细地看一下这个算法的原理。

**备注：** 在给 `flex-grow` 和 `flex-shrink` 赋值时要注意比例。如果我们给所有 flex 元素的 flex 属性赋值为 `1 1 200px` ，并且希望其中一个元素可以增加到 2 倍，我们可以给该元素的 flex 属性赋值为`2 1 200px`。当然，你也可以选择赋值为 flex: `10 1 200px` 和 flex: `20 1 200px` 。

### Flex 属性的简写

你可能很少看到 `flex-grow`，`flex-shrink`，和 `flex-basis` 属性单独使用，而是混合着写在 `flex` 简写形式中。 `Flex` 简写形式允许你把三个数值按这个顺序书写 — `flex-grow`，`flex-shrink`，`flex-basis`。

你可以在下面的实例中尝试把 flex 简写形式中的数值更改为不同数值，但要记得第一个数值是 `flex-grow`。赋值为正数的话是让元素增加所占空间。第二个数值是`flex-shrink` — 正数可以让它缩小所占空间，但是只有在 flex 元素总和超出主轴才会生效。最后一个数值是 `flex-basis`；flex 元素是在这个基准值的基础上缩放的。

大多数情况下可以用预定义的简写形式。在这个教程中你可能经常会看到这种写法，许多情况下你都可以这么使用。下面是几种预定义的值：

* `flex: initial`
* `flex: auto`
* `flex: none`
* `flex: <positive-number>`

`flex: initial` 是把 flex 元素重置为 Flexbox 的初始值，它相当于 `flex: 0 1 auto`。在这里 `flex-grow` 的值为 0，所以 flex 元素不会超过它们 `flex-basis` 的尺寸。`flex-shrink` 的值为 1, 所以可以缩小 flex 元素来防止它们溢出。`flex-basis` 的值为 `auto`. Flex 元素尺寸可以是在主维度上设置的，也可以是根据内容自动得到的。

`flex: auto` 等同于 `flex: 1 1 auto`；和上面的 `flex:initial` 基本相同，但是这种情况下，flex 元素在需要的时候既可以拉伸也可以收缩。

`flex: none` 可以把 flex 元素设置为不可伸缩。它和设置为 `flex: 0 0 auto` 是一样的。元素既不能拉伸或者收缩，但是元素会按具有 `flex-basis: auto` 属性的 flexbox 进行布局。

你在教程中常看到的 `flex: 1` 或者 `flex: 2` 等等。它相当于`flex: 1 1 0` 或者 `flex: 2 1 0`。元素可以在 `flex-basis` 为 0 的基础上伸缩。

尝试在下面的实例中应用这些简写值。

元素间的对齐和空间分配
-----------

Flexbox 的一个关键特性是能够设置 flex 元素沿主轴方向和交叉轴方向的对齐方式，以及它们之间的空间分配。

### `align-items`

`align-items` 属性可以使元素在交叉轴方向对齐。

这个属性的初始值为`stretch`，这就是为什么 flex 元素会默认被拉伸到最高元素的高度。实际上，它们被拉伸来填满 flex 容器——最高的元素定义了容器的高度。

你也可以设置`align-items`的值为`flex-start`，使 flex 元素按 flex 容器的顶部对齐，`flex-end` 使它们按 flex 容器的下部对齐，或者`center`使它们居中对齐。在实例中尝试——我给出了 flex 容器的高度，以便你可以看到元素在容器中移动。看看如果更改 align-items 的值为下列值会发生什么：

* `stretch`
* `flex-start`
* `flex-end`
* `center`

### `justify-content`

`justify-content`属性用来使元素在主轴方向上对齐，主轴方向是通过 `flex-direction` 设置的方向。初始值是`flex-start`，元素从容器的起始线排列。但是你也可以把值设置为`flex-end`，从终止线开始排列，或者`center`，在中间排列。

你也可以把值设置为`space-between`，把元素排列好之后的剩余空间拿出来，平均分配到元素之间，所以元素之间间隔相等。或者使用`space-around`，使每个元素的左右空间相等。

在实例中尝试下列`justify-content`属性的值：

* `stretch`
* `flex-start`
* `flex-end`
* `center`
* `space-around`
* `space-between`

在以后的文章中，为了更好的理解它们怎么使用，我们会更深入的探索这些属性。然而，这些简单的例子对大多数应用都很有帮助。

下一步
---

在读完这篇文章之后，你应该掌握了 flexbox 的基本特性。在下一篇文章中，我们将会学习如何与其他 CSS 一起使用。


对齐弹性容器中的弹性项目 - CSS：层叠样式表

对齐弹性容器中的弹性项目
============

flexbox 之所以能迅速吸引开发者的注意，其中一个原因就是它首次为网页样式居中提供了合适的方案。得益于它提供的合适的垂直居中能力，我们可以很轻松地把一个盒子居中。在这份指南里，我们将详细地介绍 flexbox 的垂直和水平居中的工作原理。

为了使我们的盒子居中，通过`align-items`属性，可以将交叉轴上的 item 对齐，此时使用的是垂直方向的块轴。而使用`justify-content`则可以对齐主轴上的项目，主轴是水平方向的。

![一个包含另一个盒子的元素在其中心。](/zh-CN/docs/Web/CSS/CSS_flexible_box_layout/Aligning_items_in_a_flex_container/align1.png)

如下代码所示，即使改变容器或内嵌元素的 size，内嵌元素也会保持居中状态

控制对齐的属性
-------

本指南中的属性如下。

* `justify-content` - 控制主轴（横轴）上所有 flex 项目的对齐。
* `align-items` - 控制交叉轴（纵轴）上所有 flex 项目的对齐。
* `align-self` - 控制交叉轴（纵轴）上的单个 flex 项目的对齐。
* `align-content` - 控制“多条主轴”的 flex 项目在交叉轴的对齐。

我们也会了解到 flexbox 如何使用 margin: auto 来实现居中。

**备注：** 这些 Flexbox 的对齐属性已经纳入 CSS Box Alignment Level 3标准里了。预计这特性将最终会取代之前在Flexbox Level One定义的属性。

交叉轴
---

`align-items` 和`align-self` 是控制我们的 flex 项目在交叉轴的对齐，如果 `flex-direction` 是 `row` 则是控制竖向对齐，反之 `flex-direction` 是 `column` 则是控制横向对齐。

我们正在用一个最简单的例子做交叉轴对齐。如果我们在父级的容器元素上添加`display: flex` 属性，那么容器里的所有子元素将会变成横向排列的 flex items。所有的 flex 项目会撑满交叉轴方向的高度，因为`display: flex` 属性会将 flex 项目的高定义成容器的高度。如果你的父级容器有设置高度，则 flex 项目会撑满整个父级容器的高度，不会管 flex 项目里的内容的多少。

![三个项目，其中一个附加文本使其比其他文件更高。](/zh-CN/docs/Web/CSS/CSS_flexible_box_layout/Aligning_items_in_a_flex_container/align2.png)

![三项拉伸到 200 像素高](/zh-CN/docs/Web/CSS/CSS_flexible_box_layout/Aligning_items_in_a_flex_container/align3.png)

flex items 的高度全都变成一样的原因是 `align-items` 属性的初始值设成 `stretch` 控制交叉轴对齐。

我们可以使用其他的值来控制 flex items 的对齐方式：

* `align-items: flex-start` flex 项目的开始端的对齐
* `align-items: flex-end` flex 项目的结束端对齐
* `align-items: center` flex 项目居中对齐
* `align-items: stretch` flex 项目撑满 flex 容器
* `align-items: baseline` flex 项目的基线对齐

下面的例子中，`align-items` 的值为 `stretch` 。尝试给 `align-items` 赋上其他的值然后看下在 flex 容器里是什么样的对齐效果。

### `align-self` 用于对齐单个 flex 子项

`align-items` 属性是给所有 flex 项目统一设置 `align-self` 的对齐属性。这意味着你能给单个 flex 项目明确地声明 `align-self` 属性。`align-self` 拥有 `align-items` 的所有属性值，另外还有一个 `auto` 能重置自身的值为 `align-items` 定义的值。

在下面的一个例子中，flex 容器为 `align-items: flex-start`，这意思是所有的 flex 项目都在交叉轴方向的开始端对齐。我用 `first-child` 选择器给第一个 flex 项目设置了 `align-self: stretch` ；另外一个 flex 项目用 selected 的类设置成 `align-self: center` 。你能试着改变 `align-items` 或者在单个 `align-self` 的值，可以发现这些值是怎么影响对齐的。

### 改变主轴方向

到目前为止我们已经看到了我们的 `flex-direction` 是 `row` 和使用的语言的书写方式为从上至下的表现行为。这意味着主轴是水平方向，交叉轴对齐则是有上至下垂直方向。

![三个项目，第一个对齐到 flex-start，第二个到中心，第三个到 flex-end。在垂直轴上对齐。](/zh-CN/docs/Web/CSS/CSS_flexible_box_layout/Aligning_items_in_a_flex_container/align4.png)

如果我们改变我们的 `flex-direction` 为 `column` ，`align-items` 和 `align-self` 对齐的 flex 项目则是水平方向从左往右。

![三个项目，第一个对齐到 flex-start，第二个到中心，第三个到 flex-end。在水平轴上对齐。](/zh-CN/docs/Web/CSS/CSS_flexible_box_layout/Aligning_items_in_a_flex_container/align5.png)

你能在下面这个例子体验一下，它除了 `flex-direction` 为 `column` 这个属性，其他的属性值和前一个例子是一样的。

轴对齐内容——align-content 属性
-----------------------

到现在为止，我们已经对定义在 flex 容器里的 flex 项目或者单个 flex 项目进行对齐操作了。如果你有一个折行的多条 flex 项目的 flex 容器，然后你可能想使用 `align-content` 来控制每行之间空间的分配，在这种特定的场景叫做packing flex lines。

要使得 `align-content` 生效，你需要你的 flex 容器的 height 要大于 flex 项目的可视内容。然后它会将所有的 flex 项目打包成一块之后再对齐剩下的空间。

`align-content` 属性的值如下：

* `align-content: flex-start`
* `align-content: flex-end`
* `align-content: center`
* `align-content: space-between`
* `align-content: space-around`
* `align-content: stretch`
* `align-content: space-evenly` （没有在 Flexbox 特性中定义）

在下面的例子，有一个 400px 高的 flex 容器，能足够地显示 flex 项目。`align-content` 的值为 `space-between` 等同于分配 flex 行之间的空间。

尝试用其他的属性值查看 `align-content` 是如何影响布局的。

在强调一次我们可以切换我们的 `flex-direction` 为 `column` 去观察这个属性的行为是怎样的。和之前一样，我们需要足够的交叉轴空间去显示所有的 flex 项目之外还有有一定的自由空间。

**备注：** `space-evenly` 没有在 flexbox 特性中定义，而是后来添加到 Box Alignment 的特性的属性。浏览器的支持没有 flexbox 特性好。

查看 `justify-content` 在 MDN 的文档 获取属性值的浏览器支持的更多详细说明。

对齐主轴内容
------

到目前我们已经看到 flex 项目是如何在交叉轴上对齐的，现在我们可以看一下主轴上的对齐。这里只有一个属性是用于主轴上对齐——`justify-content`。这是因为我们把所有的 flex 项目当成一个组去处理。用 `justify-content` 这个属性的时候，我们只控制主轴出显示出来 flex 项目的多余空间。

在我们的最开始的例子中，我们在 flex 容器定义了 `display: flex`，flex 项目则水平排队从容器的初始端显示。这是因为 `justify-content` 的初始值是 `flex-start` ，其他多余的空间都会显示在 flex 项目的最后。

![Three items, each 100 pixels wide in a 500 pixel container. The available space is at the end of the items.](/zh-CN/docs/Web/CSS/CSS_flexible_box_layout/Aligning_items_in_a_flex_container/align6.png)

`justify-content` 属性有和 `align-content` 一样的属性值：

* `align-content: flex-start`
* `align-content: flex-end`
* `align-content: center`
* `align-content: space-between`
* `align-content: space-around`
* `align-content: stretch`
* `align-content: space-evenly` （没有在 flexbox 特性中定义）

在下面的例子中， `justify-content` 的值为 `space-between` 。在显示完 flex 项目后的可用空间的分配是在 flex 项目水平方向之间。

如果主轴方向 `flex-direction` 设置成 `column`，那么 `justify-content` 分配的空间则是纵向的分配。

### 对齐和书写模式

记得这些所有的对齐方法，属性值 `flex-start` 和 `flex-end` 是受书写模式的影响的。如果 `justify-content` 的值是 `flex-start` 而已你的书写模式是从左到右的话，那么 flex items 就会从 flex container 的左边开始排列。

![Three items lined up on the left](/zh-CN/docs/Web/CSS/CSS_flexible_box_layout/Aligning_items_in_a_flex_container/basics5.png)

反之，则会 flex 项目就会从 flex 容器的右边开始排列。

![Three items lined up from the right](/zh-CN/docs/Web/CSS/CSS_flexible_box_layout/Aligning_items_in_a_flex_container/basics6.png)

下面的例子将 `direction` 属性值设成 `rtl` 强行让 flex 项目从右到左排列，你可以移除这个属性值或者改变 `justify-content` 的值，看他是如何影响 flex 项目的排列方向的。

对齐和 flex-direction
------------------

如果你改变 `flex-direction` 属性，主轴起始线也会改变——例如，使用 `row-reverse` 代替 `row`。

在下面的例子里，弹性项目布局为 `flex-direction: row-reverse` 和 `justify-content: flex-end` 。在一个书写模式为从左到右的语言中，弹性项目会对齐到左边。尝试将 `flex-direction: row-reverse` 改为 `flex-direction: row`，你会看到弹性项目会对齐到右边。

这似乎有一点令人困惑，需要记住的规则就是，当没有设置 `flex-direction` 时，弹性项目的排列方向与文档语言的文本沿行内轴的排列方向一致。`flex-start` 就是一个句子中文本的起始处。

![Diagram showing start on the left and end on the right.](/zh-CN/docs/Web/CSS/CSS_flexible_box_layout/Aligning_items_in_a_flex_container/align8.png)

你可以通过设置 `flex-direction: column`，使弹性项目沿着文档语言的块级轴方向显示。那样话，`flex-start` 就是文本第一个段落的顶端起始处。

![Diagram showing start and the top and end at the bottom.](/zh-CN/docs/Web/CSS/CSS_flexible_box_layout/Aligning_items_in_a_flex_container/align10.png)

如果你将 `flex-direction` 的值改成 `row-reverse` 或者 `column-revers` ，那么弹性项目会沿着文档语言的文本书写方向的相反方向，从轴的尾端开始排列。`flex-start` 就会变为轴的尾端。也就是说，沿着行内轴时，这个位置就是每行文本的换行处；沿着块级轴时，就是文本最后一个段落的底部。

![Diagram showing start on the right and end on the left.](/zh-CN/docs/Web/CSS/CSS_flexible_box_layout/Aligning_items_in_a_flex_container/align9.png)

![Diagram showing end at the top and start at the bottom](/zh-CN/docs/Web/CSS/CSS_flexible_box_layout/Aligning_items_in_a_flex_container/align11.png)

使用自动的外边距在主轴上对齐
--------------

我们想要处理个别弹性项目在主轴上的对齐，但是没有 `justify-items` 属性或者 `justify-self` 属性可用，因为弹性项目会被当成一个组来对齐。然而，我们可以使用自动的外边距来处理一些个别弹性项目或者一组弹性项目想和其他弹性项目分离开的对齐情况。

一个常见的案例是导航栏，一些重要项目右对齐，而一组其他主要项目左对齐。你可能会想，这个时候就需要一个 `justify-self` 属性。但是下面的情况，如图所示，有 3 个项目在左边，2 个在右边。假设可以在项目 d 上设置 `justify-self` 的话，那么跟在后面的项目 e 的对齐方式也会发生改变。可能这正是我们想要的效果，但某些时候并不是。

![Five items, in two groups. Three on the left and two on the right.](/zh-CN/docs/Web/CSS/CSS_flexible_box_layout/Aligning_items_in_a_flex_container/align7.png)

另一个办法是，单独把项目 d 的 `margin-left` 属性设置成 `auto`。自动的外边距会占据全部的多余的空间——在一个块上设置自动的左右外边距可以使它居中。两边尽可能占据多的空间，块就被置于中间位置了。

在下面这个在线例子中，弹性项目按默认方式简单地沿行排列，而样式类 `push` 有设置有 `margin-left: auto`。你可以尝试删除它，或者把这个类名加到别的弹性项目上，你会看到它是怎样影响弹性项目排列的。

未来的 Flexbox 对齐特性
----------------

在本文的开头，我解释了 Level1 flexbox 规范中当前包含的对齐相关属性也被包含在了 Box Alignment Level3 规范中，这意味着将来会很好地扩展这些属性和值。我们已经看到了这种情况的发生，比如：为 `align-content` 和`justify-content` 属性引入`space-evenly`值。

Box Alignment 模块还包含其他创建子项之间间隙的方法，比如在 CSS Grid Layout 中包含的 `column-gap` 和`row-gap` 特性。这些属性包含在 Box Alignment 规范中意味着在将来我们也应该能够在 flex 布局中使用`column-gap`和`row-gap`，在 Firefox 63 中，你将在 flex 布局中找到第一个浏览器对 gap 属性的实现。

在深入研究 flexbox 对齐时，我的建议是同时查看 Grid Layout 中的对齐方式。两种规范都使用 Box Alignment 规范中详细说明的对齐属性。你可以在 MDN 文章《Box Alignment in Grid Layout》中查看使用网格时这些属性的行为，并且我还在《 Box Alignment Cheatsheet》中比较了这些规范中对齐的工作方式。

更多
--

* Box Alignment
* Box Alignment in Flexbox
* Box Alignment in Grid Layout (en-US)


lab() - CSS：层叠样式表

lab()
=====

函数记号 **`lab()`** 在 CIE L\*a\*b\* 颜色空间中表示指定颜色。Lab 表示人可见的全部颜色的范围。

语法
--

```css
lab(29.2345% 39.3825 20.0664);
lab(52.2345% 40.1645 59.9971);
lab(52.2345% 40.1645 59.9971 / .5);
```

### 取值

* 函数记号：`lab(L a b [/ A])`
    + `L` 为介于 `0` 和 `100` 之间的 `<number>` 或介于 `0%` 和 `100%` 之间的 `<percentage>`，指定了 CIE 明度，此处数值 `0` 对应 `0%`（黑），数值 `100` 对应 `100%`（白）。
    + `a` 为介于 `-125` 和 `125` 之间的 `<number>` 或介于 `-100%` 和 `100%` 之间的 `<percentage>`，指定了在 Lab 颜色空间中沿 `a` 轴的距离，即颜色绿或红的程度。
    + `b` 为介于 `-125` 和 `125` 之间的 `<number>` 或介于 `-100%` 和 `100%` 之间的 `<percentage>`，指定了在 Lab 颜色空间中沿 `b` 轴的距离，即颜色蓝或黄的程度。
    + `A`（alpha）可为介于 `0` 和 `1` 之间的 `<number>` 或 `<percentage>`，此处数值 `1` 对应 `100%`（完全不透明）。

**备注：** 在 CSS 中，通常当百分比值有等价数值时，`100%` 等于数值 `1`。此处注意 `100%` 对于 `L` 值等于数值 `100`，对于 `a` 值和 `b` 值等于 `125`。

### 形式语法
```

<lab()> =
  lab( [ <percentage> | <number> | none ] [ <percentage> | <number> | none ] [ <percentage> | <number> | none ] [ / [ <alpha-value> | none ] ]? )

<alpha-value> =
  <number>      |
  <percentage>

```

示例
--

### 用 lab() 调整明度和颜色轴

下列示例展示了改变 `lab()` 函数的明度、a 轴和 b 轴值的效果。

#### HTML

```html
<div data-color="red"></div>
<div data-color="red-a"></div>

<div data-color="green"></div>
<div data-color="green-b"></div>

<div data-color="blue"></div>
<div data-color="blue-light"></div>
```

#### CSS
```

div {
  width: 50px;
  height: 50px;
  padding: 5px;
  margin: 5px;
  display: inline-block;
  border: 1px solid black;
}
```

```css
[data-color="red"] {
  background-color: lab(100 125 125);
}
[data-color="red-a"] {
  background-color: lab(100 110 125);
}

[data-color="green"] {
  background-color: lab(75% -120 125);
}
[data-color="green-b"] {
  background-color: lab(75% -120 10);
}

[data-color="blue"] {
  background-color: lab(0 -120 -120);
}
[data-color="blue-light"] {
  background-color: lab(70 -120 -120);
}
```

#### 结果

### 用 lab() 调整不透明度

下列示例展示了改变函数记号 `lab()` 的 `A`（alpha）值的效果。为演示不透明度的效果，`red` 和 `red-alpha` 元素与 `#background-div` 元素重叠。`0.4` 的 `A` 值使颜色有 40% 的不透明度。

#### HTML

```html
<div id="background-div">
  <div data-color="red"></div>
  <div data-color="red-alpha"></div>
</div>
```

#### CSS
```

div {
  width: 50px;
  height: 50px;
  padding: 5px;
  margin: 5px;
  display: inline-block;
  border: 1px solid black;
}
#background-div {
  background-color: lightblue;
  width: 150px;
  height: 40px;
}
```

```css
[data-color="red"] {
  background-color: lab(100 125 125);
}
[data-color="red-alpha"] {
  background-color: lab(100 125 125 / 0.4);
}
```

#### 结果

规范
--

| Specification |
| --- |
| CSS Color Module Level 4 # lab-colors |

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

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

参见
--

* `<color>` 数据类型所列的所有颜色记号
* CSS 中的 LCH 颜色——是什么，为什么，怎么用？
* Safari 技术预览 122 发布记录：含 `lab()` 和 `lch()` 颜色


oklab() - CSS：层叠样式表

oklab()
=======

函数记号 **`oklab()`** 在 Oklab 颜色空间中表示指定颜色，此颜色空间尽力模仿人眼感知颜色的方式。`oklab()` 在 Oklab 颜色空间中使用直角坐标系，有 a 轴和 b 轴。若想要极坐标颜色系统——色度和色相，请使用 `oklch()`。

Oklab 为感知颜色空间，可用于：

* 在不改变图像明度的前提下，将图像转换为灰度图。
* 在保持用户所感知的色相和明度的前提下，修改颜色的饱和度。
* 创建平滑均匀的颜色渐变（例如在 `<canvas>` 元素中手动插值）。

`oklab()` 函数可表示 Oklab 颜色空间中的任意颜色。此颜色空间比 RGB 更宽广，包含宽色域颜色和 P3 颜色。

语法
--

```css
/\* oklab(明度 a 轴 b 轴) \*/
oklab(40.1% 0.1143 0.045);
oklab(59.69% 0.1007 0.1191);

/\* oklab(明度 a 轴 b 轴 / alpha) \*/
oklab(59.69% 0.1007 0.1191 / 0.5);
```

**备注：** oklab() 函数**不**像其他某些颜色函数一样支持以逗号分隔其值，且可选的 alpha 值在指定时需置于正斜杠（`/`）之后。

### 取值

* 函数记号：`oklab(L a b [/ A])`
    + `L` 为介于 `0` 和 `1` 之间的 `<number>` 或介于 `0%` 和 `100%` 之间的 `<percentage>`，此处数值 `0` 对应 `0%`（黑），数值 `1` 对应 `100%`（白）。`L` 指定了感知明度。
    + `a` 为介于 `-0.4` 和 `0.4` 之间的 `<number>` 或介于 `-100%` 和 `100%` 之间的 `<percentage>`。此值指定了在 Oklab 空间中沿 `a` 轴的距离，即颜色绿或红的程度。
    + `b` 为介于 `-0.4` 和 `0.4` 之间的 `<number>` 或介于 `-100%` 和 `100%` 之间的 `<percentage>`。此值指定了在 Oklab 空间中沿 `b` 轴的距离，即颜色蓝或黄的程度。
    + `A`（alpha）为介于 `0` 和 `1` 之间的 `<number>` 或 `<percentage>`，此处数值 `1` 对应 `100%`（完全不透明）。`A` 表示颜色的透明度（即 alpha 通道）。
### 形式语法
```

<oklab()> =
  oklab( [ <percentage> | <number> | none ] [ <percentage> | <number> | none ] [ <percentage> | <number> | none ] [ / [ <alpha-value> | none ] ]? )

<alpha-value> =
  <number>      |
  <percentage>

```

示例
--

### 用 oklab() 调整明度和轴

下列示例展示了改变 `oklab()` 函数的明度、a 轴和 b 轴值的效果。

#### HTML

```html
<div data-color="blue"></div>
<div data-color="blue-light"></div>

<div data-color="red"></div>
<div data-color="red-a"></div>

<div data-color="green"></div>
<div data-color="green-b"></div>
```

#### CSS
```

div {
  width: 50px;
  height: 50px;
  padding: 5px;
  margin: 5px;
  display: inline-block;
  border: 1px solid black;
}
```

```css
[data-color="blue"] {
  background-color: oklab(0.5 -0.3 -0.4);
}
[data-color="blue-light"] {
  background-color: oklab(0.7 -0.3 -0.4);
}

[data-color="red"] {
  background-color: oklab(100% 0.4 0.4);
}
[data-color="red-a"] {
  background-color: oklab(100% 0.2 0.4);
}

[data-color="green"] {
  background-color: oklab(100% -100% 0.4);
}
[data-color="green-b"] {
  background-color: oklab(100% -100% 0.6);
}
```

#### 结果

### 用 oklab() 调整不透明度

下列示例展示了改变 `oklab()` 函数的 `A`（alpha）值的效果。为演示不透明度的效果，`red` 和 `red-alpha` 元素与 `#background-div` 元素重叠。给予 `red-alpha` 元素 `0.4` 的不透明度使其显得比 `red` 元素更透明。

#### HTML

```html
<div id="background-div">
  <div data-color="red"></div>
  <div data-color="red-alpha"></div>
</div>
```

#### CSS
```

div {
  width: 50px;
  height: 50px;
  padding: 5px;
  margin: 5px;
  display: inline-block;
  border: 1px solid black;
}
#background-div {
  background-color: lightblue;
  width: 150px;
  height: 40px;
}
```

```css
[data-color="red"] {
  background-color: oklab(50% 130 20);
}
[data-color="red-alpha"] {
  background-color: oklab(50% 130 20 / 0.4);
}
```

#### 结果

规范
--

| Specification |
| --- |
| CSS Color Module Level 4 # ok-lab |

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

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

参见
--

* `<color>` 数据类型所列的所有颜色记号
* `oklch()`：另一使用与 `oklab()` 相同的颜色空间但在极坐标系中的函数记号
* 一个用于图像处理的感知颜色空间


color-contrast() - CSS：层叠样式表

color-contrast()
================

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

**`color-contrast()`** 函数标记接收一个 `color` 值，并将其与其他的 `color` 值比较，从列表中选择最高对比度的颜色。

语法
--

```css
color-contrast(wheat vs tan, sienna, #d2691e)
color-contrast(#008080 vs olive, var(--myColor), #d2691e)
```

### 值

函数标记：`color-contrast(color vs color-list)`

`color`

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

`vs`

字面保留字，作为语法的一部分。

`color-list`

由逗号分隔的列表，至少两个值，以与第一个值进行比较。

规范
--

| Specification |
| --- |
| CSS Color Module Level 6 # colorcontrast |

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

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


hsl() - CSS：层叠样式表

hsl()
=====

**`hsl()`** 函数标记根据其*色相*、*饱和度*和*明度*来表达 sRGB (en-US) 颜色。可选的 *alpha* 成分代表了颜色的透明度。

**备注：** 旧版的 `hsla()` 语法是 `hsl()` 的别称，接收相同的参数，行为也是相同的。

尝试一下
----

使用 `hsl()` 来定义*互补色*可以用一个公式来完成，因为它们位于色环 (en-US)中同一直径上。如果一个颜色的色相度是 `θ`，那么其互补色的色相角就是 `180deg - θ`。

语法
--

```css
hsl(120deg 75% 25%)
hsl(120deg 75% 25% / 0.6)
```

此函数也接受旧版的语法，即所有的值都是用逗号分隔的。

### 值

函数标记：`hsl(H S L[ / A])`

`H`

`<number>`、`<angle>` 或者关键字 `none`，代表色相角。关于此类型的更多细节可以参见 `<hue>` (en-US) 文档。

`S`

`<percentage>` 或者关键字 `none`，代表饱和度。在这里，`100%` 是完全饱和，而 `0%` 是完全不饱和（灰色）。

`L`

`<percentage>` 或者关键字 `none`，代表明度。在这里，`100%` 是白色，`0%` 是黑色，`50%` 是“正常”。

`A` 可选

`<alpha-value>` 或者关键字 `none`，其中数字 `1` 代表 `100%`（完全不透明）。

**备注：** 参见缺失颜色成分 以了解 `none` 的效果。

### 形式语法
```

<hsl()> =
  <legacy-hsl-syntax>  |
  <modern-hsl-syntax>

<legacy-hsl-syntax> =
  hsl( <hue> , <percentage> , <percentage> , <alpha-value>? )

<modern-hsl-syntax> =
  hsl( [ <hue> | none ] [ <percentage> | <number> | none ] [ <percentage> | <number> | none ] [ / [ <alpha-value> | none ] ]? )

<hue> =
  <number>  |
  <angle>

<alpha-value> =
  <number>      |
  <percentage>

```

示例
--

### 使用 hsl() 和 conic-gradient()

`hsl()` 函数和 `conic-gradient()` 可以很好地配合使用，因为这两个都处理角度。
```

<div></div>
```

#### CSS

```css
div {
  width: 100px;
  height: 100px;
  background: conic-gradient(
    hsl(360 100% 50%),
    hsl(315 100% 50%),
    hsl(270 100% 50%),
    hsl(225 100% 50%),
    hsl(180 100% 50%),
    hsl(135 100% 50%),
    hsl(90 100% 50%),
    hsl(45 100% 50%),
    hsl(0 100% 50%)
  );
  clip-path: circle(closest-side);
}
```

#### 结果

### 旧版语法：逗号分隔值

由于历史原因，`hsl()` 函数接受所有值用逗号分隔的形式。

#### HTML

```html
<div class="space-separated"></div>
<div class="comma-separated"></div>
```

#### CSS

```css
div {
  width: 100px;
  height: 50px;
  margin: 1rem;
}

div.space-separated {
  background-color: hsl(0 100% 50% / 50%);
}

div.comma-separated {
  background-color: hsl(0, 100%, 50%, 50%);
}
```

#### 结果

### 旧版语法：hsla()

旧版的 `hsla()` 语法是 `hsl()` 的别称。

#### HTML

```html
<div class="hsl"></div>
<div class="hsla"></div>
```

#### CSS

```css
div {
  width: 100px;
  height: 50px;
  margin: 1rem;
}

div.hsl {
  background-color: hsl(0 100% 50% / 50%);
}

div.hsla {
  background-color: hsla(0, 100%, 50%, 50%);
}
```

#### 结果

规范
--

| Specification |
| --- |
| CSS Color Module Level 4 # the-hsl-notation |

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

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

参见
--

* `<color>`：代表颜色的数据类型
* HSL 颜色拾取器


rgb() - CSS：层叠样式表

rgb()
=====

**`rgb()`** 函数标记根据颜色的红色、绿色和蓝色成分来表达颜色。可选的 alpha 成分代表了颜色的透明度。

**备注：** 旧版的 `rgba()` 语法是 `rgb()` 的别称，接收相同的参数，行为也是相同的。

尝试一下
----

语法
--

```css
rgb(255 255 255)
rgb(255 255 255 / .5)
```

此函数也接受旧版的语法，即所有的值都是用逗号分隔的。

### 值

函数标记：`rgb(R G B[ / A])`

`R`、`G`、`B`

每个都是从 `0` 到 `255` 之间的 `<number>` 值，或从 `0%` 到 `100%` 之间的 `<percentage>` 值，或者为关键字 `none`，分别代表红色、绿色和蓝色的通道。

`A` 可选

`<alpha-value>` 值或者关键字 `none`，数字 `1` 对应 `100%`（完全不透明）。

**备注：** 参见缺失颜色成分以了解 `none` 的效果。

### 形式语法
```

<rgb()> =
  <legacy-rgb-syntax>  |
  <modern-rgb-syntax>

<legacy-rgb-syntax> =
  rgb( <percentage>#{3} , <alpha-value>? )  |
  rgb( <number>#{3} , <alpha-value>? )

<modern-rgb-syntax> =
  rgb( [ <number> | <percentage> | none ]{3} [ / [ <alpha-value> | none ] ]? )

<alpha-value> =
  <number>      |
  <percentage>

```

示例
--

### 旧版语法：逗号分隔值

由于历史原因，`rgb()` 函数接受所有值用逗号分隔的形式。

#### HTML

```html
<div class="space-separated"></div>
<div class="comma-separated"></div>
```

#### CSS

```css
div {
  width: 100px;
  height: 50px;
  margin: 1rem;
}

div.space-separated {
  background-color: rgb(255 0 0 / 0.5);
}

div.comma-separated {
  background-color: rgb(255, 0, 0, 0.5);
}
```

#### 结果

### 旧版语法：rgba()

旧版的 `rgba()` 语法是 `rgb()` 的别称。

#### HTML

```html
<div class="rgb"></div>
<div class="rgba"></div>
```

#### CSS

```css
div {
  width: 100px;
  height: 50px;
  margin: 1rem;
}

div.rgb {
  background-color: rgb(255 0 0 / 0.5);
}

div.rgba {
  background-color: rgba(255 0 0 / 0.5);
}
```

#### 结果

规范
--

| Specification |
| --- |
| CSS Color Module Level 4 # rgb-functions |

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

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

参见
--

* `<color>` 数据类型，以了解所有颜色标记的列表


oklch() - CSS：层叠样式表

oklch()
=======

函数记号 **`oklch()`** 在 Oklch 颜色空间中表示指定颜色。此函数记号与 `oklab()` 有相同的 L 轴，但使用极坐标 C（色度）和 H（色相）。

语法
--

```css
oklch(40.1% 0.123 21.57)
oklch(59.69% 0.156 49.77)
oklch(59.69% 0.156 49.77 / .5)
```

### 取值

* 函数记号：`oklch(L C H [/ A])`
    + `L` 为介于 `0` 和 `1` 之间的 `<number>` 或介于 `0%` 和 `100%` 之间的 `<percentage>`，此处数值 `0` 对应 `0%`（黑），数值 `1` 对应 `100%`（白）。`L` 指定了感知明度。
    + `C` 为 `<number>` 或 `<percentage>`，此处 `0%` 对应 `0`，`100%` 对应数值 `0.4`。此值衡量了色度（大概表示“颜色的量”），其有用的最小值为 `0`，最大值无理论上限（但实际不超过 `0.5`）。
    + `H` 为 `<number>` 或 `<angle>`，指定了沿正半 a 轴（紫红方向）的色相角。`90deg` 指向正半 b 轴（芥末黄方向），`180deg` 指向负半 a 轴（蓝绿方向），`270deg` 指向负半 b 轴（天蓝方向）。
    + `A`（alpha）可为介于 `0` 和 `1` 之间的 `<number>` 或介于 `0%` 和 `100%` 之间的 `<percentage>`，此处数值 `1` 对应 `100%`（完全不透明）。
### 形式语法
```

<oklch()> =
  oklch( [ <percentage> | <number> | none ] [ <percentage> | <number> | none ] [ <hue> | none ] [ / [ <alpha-value> | none ] ]? )

<hue> =
  <number>  |
  <angle>

<alpha-value> =
  <number>      |
  <percentage>

```

示例
--

### 调整颜色的明度、色度和色相

下列示例展示了改变颜色函数 `oklch()` 的 `L`（明度）、`C`（色度）和 `H`（色相）值的效果。

#### HTML

```html
<div data-color="blue"></div>
<div data-color="blue-light"></div>

<div data-color="red"></div>
<div data-color="red-chroma"></div>

<div data-color="green"></div>
<div data-color="green-hue"></div>
```

#### CSS
```

div {
  width: 50px;
  height: 50px;
  padding: 5px;
  margin: 5px;
  display: inline-block;
  border: 1px solid black;
}
```

```css
[data-color="blue"] {
  background-color: oklch(60% 0.4 240);
}
[data-color="blue-light"] {
  background-color: oklch(90% 0.4 240);
}

[data-color="red"] {
  background-color: oklch(100% 0.4 30);
}
[data-color="red-chroma"] {
  background-color: oklch(100% 0.3 40);
}

[data-color="green"] {
  background-color: oklch(60% 0.57 161);
}
[data-color="green-hue"] {
  background-color: oklch(60% 0.57 181);
}
```

#### 结果

### 调整颜色的 alpha 值

下列示例展示了改变颜色函数 `oklch()` 的 `A`（alpha）值的效果。为演示不透明度的效果，`red` 和 `red-alpha` 元素与 `#background-div` 元素重叠。`0.4` 的 `A` 值使颜色有 40% 的不透明度。

#### HTML

```html
<div id="background-div">
  <div data-color="red"></div>
  <div data-color="red-alpha"></div>
</div>
```

#### CSS
```

div {
  width: 50px;
  height: 50px;
  padding: 5px;
  margin: 5px;
  display: inline-block;
  border: 1px solid black;
}
#background-div {
  background-color: oklch(100% 0.57 217);
  width: 150px;
  height: 40px;
}
```

```css
[data-color="red"] {
  background-color: oklch(50% 130 20);
}
[data-color="red-alpha"] {
  background-color: oklch(50% 130 20 / 0.4);
}
```

#### 结果

规范
--

| Specification |
| --- |
| CSS Color Module Level 4 # ok-lab |

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

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

参见
--

* `<color>` 数据类型所列的所有颜色记号
* 一个用于图像处理的感知颜色空间
* CSS 中的 OKLCH
* Safari 技术预览 137 发布记录：含 `oklch()` and `oklab()` 颜色


lch() - CSS：层叠样式表

lch()
=====

函数记号 **`lch()`** 在 LCH 颜色空间中表示指定颜色。此函数记号与 `lab()` 有相同的 L 轴，但使用极坐标 C（色度）和 H（色相）。

语法
--

```css
lch(29.2345% 44.2 27);
lch(52.2345% 72.2 56.2);
lch(52.2345% 72.2 56.2 / .5);
```

### 取值

* 函数记号：`lch(L C H [/ A])`
    + `L` 为介于 `0` 和 `100` 之间的 `<number>` 或介于 `0%` 和 `100%` 之间的 `<percentage>`，指定了 CIE 明度，此处数值 `0` 对应 `0%`（黑），数值 `100` 对应 `100%`（白）。
    + `C` 为 `<number>` 或 `<percentage>`，此处 `0%` 对应 `0`，`100%` 对应数值 `150`。此值衡量了色度（大概表示“颜色的量”），其有用的最小值为 `0`，最大值无理论上限（但实际不超过 `230`）。
    + `H` 为 `<number>` 或 `<angle>`，指定了沿正半 a 轴（紫红方向）的色相角。`90deg` 指向正半 b 轴（芥末黄方向），`180deg` 指向负半 a 轴（蓝绿方向），`270deg` 指向负半 b 轴（天蓝方向）。
    + `A`（alpha）可为介于 `0` 和 `1` 之间的 `<number>` 或 `<percentage>`，此处数值 `1` 对应 `100%`（完全不透明）。

**备注：** 在 CSS 中，通常当百分比值有等价数值时，`100%` 等于数值 `1`。此处注意 `100%` 对于 `L` 值等于数值 `100`，对于 `C` 值等于 `150`。

### 形式语法
```

<lch()> =
  lch( [ <percentage> | <number> | none ] [ <percentage> | <number> | none ] [ <hue> | none ] [ / [ <alpha-value> | none ] ]? )

<hue> =
  <number>  |
  <angle>

<alpha-value> =
  <number>      |
  <percentage>

```

示例
--

### 用 lch() 调整明度、色度和色相

下列示例展示了改变函数记号 `lch()` 的 `L`（明度）、`C`（色度）和 `H`（色相）值的效果。

#### HTML

```html
<div data-color="blue"></div>
<div data-color="blue-light"></div>

<div data-color="red"></div>
<div data-color="red-chroma"></div>

<div data-color="green"></div>
<div data-color="green-hue"></div>
```

#### CSS
```

div {
  width: 50px;
  height: 50px;
  padding: 5px;
  margin: 5px;
  display: inline-block;
  border: 1px solid black;
}
```

```css
[data-color="blue"] {
  background-color: lch(0% 100 240);
}
[data-color="blue-light"] {
  background-color: lch(100% 100 240);
}

[data-color="red"] {
  background-color: lch(50% 130 20);
}
[data-color="red-chroma"] {
  background-color: lch(100% 30 20);
}

[data-color="green"] {
  background-color: lch(50% 132 130);
}
[data-color="green-hue"] {
  background-color: lch(50% 132 180);
}
```

#### 结果

### 用 lch() 调整不透明度

下列示例展示了改变函数记号 `lch()` 的 `A`（alpha）值的效果。为演示不透明度的效果，`red` 和 `red-alpha` 元素与 `#background-div` 元素重叠。`0.4` 的 `A` 值使颜色有 40% 的不透明度。

#### HTML

```html
<div id="background-div">
  <div data-color="red"></div>
  <div data-color="red-alpha"></div>
</div>
```

#### CSS
```

div {
  width: 50px;
  height: 50px;
  padding: 5px;
  margin: 5px;
  display: inline-block;
  border: 1px solid black;
}
#background-div {
  background-color: lch(100% 100 240);
  width: 150px;
  height: 40px;
}
```

```css
[data-color="red"] {
  background-color: lch(50% 130 20);
}
[data-color="red-alpha"] {
  background-color: lch(50% 130 20 / 0.4);
}
```

#### 结果

规范
--

| Specification |
| --- |
| CSS Color Module Level 4 # lab-colors |

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

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

参见
--

* `<color>` 数据类型所列的所有颜色记号
* CSS 中的 LCH 颜色——是什么，为什么，怎么用？
* Safari 技术预览 122 发布记录：含 `lch()` 和 `lab()` 颜色


color-mix() - CSS：层叠样式表

color-mix()
===========

**`color-mix()`** 函数标记接收两个 `<color>` 值，并返回在指定颜色空间、指定数量混合后的颜色。

语法
--

```css
color-mix(in lch, plum, pink);
color-mix(in lch, plum 40%, pink);
color-mix(in srgb, #34c9eb 20%, white);
color-mix(in hsl longer hue, hsl(120 100% 50%) 20%, white);
```

### 值

函数标记：`color-mix(method, color1[ p1], color2[ p2])`

`method`

指定插值颜色空间的 `<color-interpolation-method>` 值。

`color1`、`color2`

需要混合的 `<color>` 值。

`p1`、`p2` 可选

`0%` 到 `100%` 之间的 `<percentage>` 值，指定每个颜色混合的数量。这两个值会按照以下的方式规范化：

* 如果 `p1` 和 `p2` 都省略了，那么 `p1 = p2 = 50%`。
* 如果 `p1` 省略，那么 `p1 = 100% - p2`。
* 如果 `p2` 省略，那么 `p2 = 100% - p1`。
* 如果 `p1 = p2 = 0%`，那么函数无效。
* 如果 `p1 + p2 ≠ 100%`，那么 `p1' = p1 / (p1 + p2)`，`p2' = p2 / (p1 + p2)`，其中 `p1'` 和 `p2'` 是规范化后的结果。

### 形式语法
```

<color-mix()> =
  color-mix( <color-interpolation-method> , [ <color> && <percentage [0,100]>? ]#{2} )

<color-interpolation-method> =
  in [ <rectangular-color-space> | <polar-color-space> <hue-interpolation-method>? ]

<rectangular-color-space> =
  srgb          |
  srgb-linear   |
  display-p3    |
  a98-rgb       |
  prophoto-rgb  |
  rec2020       |
  lab           |
  oklab         |
  xyz           |
  xyz-d50       |
  xyz-d65

<polar-color-space> =
  hsl    |
  hwb    |
  lch    |
  oklch

<hue-interpolation-method> =
  [ shorter | longer | increasing | decreasing ] hue

```

示例
--

### 混合两个颜色

在支持的浏览器中，这些项目会有更多蓝色、更少白色，因为混色了更高百分比的 `#34c9eb`。没有给出值时，百分比默认为 50%。

#### HTML

```html
<ul>
  <li>0%</li>
  <li>25%</li>
  <li>50%</li>
  <li>75%</li>
  <li>100%</li>
  <li></li>
</ul>
```

#### CSS
```

ul {
  display: flex;
  list-style-type: none;
  font-size: 150%;
  gap: 10px;
  border: 2px solid;
  padding: 10px;
}

li {
  padding: 10px;
  flex: 1;
  box-sizing: border-box;
  font-family: monospace;
  outline: 1px solid #34c9eb;
  text-align: center;
}
```

```css
li:nth-child(1) {
  background-color: color-mix(in srgb, #34c9eb 0%, white);
}

li:nth-child(2) {
  background-color: color-mix(in srgb, #34c9eb 25%, white);
}

li:nth-child(3) {
  background-color: color-mix(in srgb, #34c9eb 50%, white);
}

li:nth-child(4) {
  background-color: color-mix(in srgb, #34c9eb 75%, white);
}

li:nth-child(5) {
  background-color: color-mix(in srgb, #34c9eb 100%, white);
}

li:nth-child(6) {
  background-color: color-mix(in srgb, #34c9eb, white);
}
```

#### 结果

### 在 color-mix() 中使用色相插值

使用 shorter 色相插值时，产生的色相角度是在色轮上在输入色相之间采用最短路线时的中间值。

使用 longer 色相插值时，产生的色相角度是在色轮上走较长的路线时的中间值。

更多信息请参考 `<hue-interpolation-method>`。

```html
<div class="color-one">颜色一</div>
<div class="color-two">颜色二</div>
<div class="shorter">shorter 混合</div>
<div class="longer">longer 混合</div>
```

#### CSS
```

body {
  display: flex;
  flex-wrap: wrap;
}
div {
  border: 1px solid;
  font: bold 150% monospace;
  height: 100px;
  margin: 10px 5%;
  width: 30%;
}
```

```css
.color-one {
  background-color: hsl(10 100% 50%);
}
.color-two {
  background-color: hsl(60 100% 50%);
}
.shorter {
  background-color: color-mix(
    in hsl shorter hue,
    hsl(10 100% 50%),
    hsl(60 100% 50%)
  );
}
.longer {
  background-color: color-mix(
    in hsl longer hue,
    hsl(10 100% 50%),
    hsl(60 100% 50%)
  );
}
```

#### 结果

规范
--

| Specification |
| --- |
| CSS Color Module Level 5 # color-mix |

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

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

参见
--

* `<color>`
* `<color-interpolation-method>`
* `<hue>` (en-US)


device-cmyk() - CSS：层叠样式表

device-cmyk()
=============

**`device-cmyk()`** 函数标记用于以设备依赖的方式表达 CMYK 颜色，指定其青色、品红色、黄色和黑色成分。

创建要输出到特定打印机的材料时，若特定墨水组合的输出的已知的，这种颜色方法非常有用。CSS 处理器可能会尝试近似颜色，但最终结果可能与打印结果不同。

语法
--

```css
device-cmyk(0 81% 81% 30%);
device-cmyk(0 81% 81% 30% / .5);
device-cmyk(0 81% 81% 30% / .5, rgb(178 34 34));
```

### 值

函数标记：`device-cmyk(C M Y K[ / A][, color])`

`C`、`M`、`Y`、`K`

`<number>` 或 `<percentage>` 值，提供 CMYK 颜色的青色、品红色、黄色和黑色成分。

`A` 可选

`<alpha-value>` 值，其中 `1` 对应 `100%`（完全不透明）。

`color` 可选

可选的后备 `<color>` 值，当用户代理不知道如何将 CMYK 颜色转换为 RGB 颜色时使用。

### 形式语法
```

<device-cmyk()> =
  <legacy-device-cmyk-syntax>  |
  <modern-device-cmyk-syntax>

<legacy-device-cmyk-syntax> =
  device-cmyk( <number>#{4} )

<modern-device-cmyk-syntax> =
  device-cmyk( <cmyk-component>{4} [ / [ <alpha-value> | none ] ]? )

<cmyk-component> =
  <number>      |
  <percentage>  |
  none

<alpha-value> =
  <number>      |
  <percentage>

```

规范
--

| Specification |
| --- |
| CSS Color Module Level 5 # device-cmyk |

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

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


圆角边框生成器 - CSS：层叠样式表

圆角边框生成器
=======

此工具可用于生成 CSS `border-radius` 样式。


Box-shadow 生成器 - CSS：层叠样式表

Box-shadow 生成器
==============

这个可视化工具可以帮助你生成一个元素的 CSS `box-shadow` 相关代码，添加 box shadow 效果到你的 CSS 对象上。

Box-shadow 生成器可以向一个元素上添加一至多个 box shadow。

启动工具以后，你可以在顶侧右部找到一个长方形，那是要应用阴影效果的元素。当该元素被选择（首次加载页面时即如此）时你可以应用一些基本的样式：

* 使用颜色选择器设置元素的颜色（`color`）。
* 使用“border”复选框给予元素一个边框（`border`）。
* 使用滑轨设置元素的 `top`、`left`、`width` 和 `height` 属性。

要添加一个阴影，点击左上侧的“+”按钮，这就增加了一个阴影，并将其列在左边的栏里。现在你可以设置新阴影的值：

* 使用颜色选择器设置阴影的颜色（`color`）。
* 使用“inset”复选框设置阴影是否嵌入元素。
* 使用滑轨设置阴影元素的位置、模糊和扩展大小。

要添加另一个阴影，再次点击“+”。现在你设置的任何数值都将应用于这个新的阴影。用左上方的 ↑ 和 ↓ 按钮改变这两个阴影的应用顺序。再次选择第一个阴影，在左边的栏目中点击它。要更新元素本身的样式，请点击顶部标有“element”的按钮来选择它。

你可以为该元素添加 `::before` 和 `::after` 伪元素，并给它们加上盒状阴影。要在元素和它的伪元素之间进行切换，可以使用顶部标有“element”、“:before”和“:after”的按钮。

右下角的方框包含该元素的 CSS 和任何 `before::` 或 `::after` 伪元素。

参见
--

Border-image 生成器

该交互性工具可以让你可视化地创建边框图片（`border-image` 属性）。

Border-radius 生成器

该交互性工具可以让你可视化地创建圆角（`border-radius` 属性）。


多个背景的应用 - CSS：层叠样式表

多个背景的应用
=======

你可以应用**多个背景**到元素。这些图层彼此叠加，第一个提供的背景位于最上层，最后一个提供的背景位于最下层。只有最后一个背景可以包含背景颜色。

指定多个背景很简单：

```css
.myclass {
  background:
    background1,
    background 2,
    ...,
    backgroundN;
}
```

除了`background-color`之外，你可以用简写`background` 属性和它的各个属性来做到这一点。也就是说，以下背景属性可以被指定为一个列表，每个背景一个： `background`, `background-attachment`, `background-clip`, `background-image`, `background-origin`, `background-position`, `background-repeat`, `background-size`.

示例
--

在这个例子中，三个背景叠加在一起：Firefox 标志，气泡图像和线性渐变：

### HTML

```html
<div class="multi-bg-example"></div>
```

### CSS

```css
.multi-bg-example {
  width: 100%;
  height: 400px;
  background-image: url(firefox.png), url(bubbles.png), linear-gradient(to right, rgba(30, 75, 115, 1), rgba(255, 255, 255, 0));
  background-repeat: no-repeat, no-repeat, no-repeat;
  background-position:
    bottom right,
    left,
    right;
}
```

### 结果

（如果在 CodePen 中图像没有出现，点击 CSS 模块的 TIdy 按钮）

正如你在这里看到的，Firefox 徽标（在`background-image`中首先列出）位于气泡图形正上方，接着是位于所有先前“images”下方的渐变（最后列出）。每个后续的子属性（`background-repeat`和`background-position`）适用于相应的背景。因此，background-repeat 的第一个列出的值适用于第一个（最前面的）背景，依此类推。

参见
--

* Using CSS gradients (en-US)


调整背景图片的大小 - CSS：层叠样式表

调整背景图片的大小
=========

CSS 属性 **`background-size`** 可以用于调整元素的背景图片大小，通过指定图像的宽度和/或高度，覆盖默认的以全尺寸平铺图像的行为。通过这样做，你可以根据需要放大或缩小图像。

铺开大图像
-----

让我们考虑一张大图片，一张 2982x2808 的 Firefox 标志图片。我们想（由于某种原因，可能涉及到可怕的糟糕的网站设计）将这个图片的四个副本平铺到一个 300x300 像素的元素中。要做到这一点，我们可以使用一个固定的 150 像素的 `background-size` 值。

### HTML

```html
<div class="tiledBackground"></div>
```

### CSS

```css
.tiledBackground {
  background-image: url(https://www.mozilla.org/media/img/logos/firefox/logo-quantum.9c5e96634f92.png);
  background-size: 150px;
  width: 300px;
  height: 300px;
  border: 2px solid;
  color: pink;
}
```

### 结果

伸缩图像
----

你也可以像这样同时指定图像的水平和垂直尺寸：

```css
background-size: 300px 150px;
```

结果看起来像这样：

![现在 Firefox 图标被伸展开了](/zh-CN/docs/Web/CSS/CSS_backgrounds_and_borders/Resizing_background_images/stretched_firefox_logo.png)

放大图像
----

你可以在背景中放大图像。在这里，我们将 32x32 像素大小的 favicon 放大到了 300x300 像素：

![放大的 MDN 徽标](/zh-CN/docs/Web/CSS/CSS_backgrounds_and_borders/Resizing_background_images/scaled_mdn_logo.png)

```css
.square2 {
  background-image: url(favicon.png);
  background-size: 300px;
  width: 300px;
  height: 300px;
  border: 2px solid;
  text-shadow: white 0px 0px 2px;
  font-size: 16px;
}
```

正如你所看到的，CSS 实际上基本上是相同的，除了图像文件的名称。

特殊值：“contain”和“cover”
---------------------

除了 `<length>` 值，CSS 属性 `background-size` 提供了两个特殊的尺寸值：`contain` 和 `cover`。让我们来看看这些。

### contain

`contain` 值指定，无论包含的盒子大小如何，背景图像都应该被缩放，使每一面都尽可能大，同时不超过容器相应一面的长度。试着调整下面这个例子的大小，观察 contain 值的效果。

#### HTML

```html
<div class="bgSizeContain">
  <p>试着缩放这个元素！</p>
</div>
```

#### CSS

```css
.bgSizeContain {
  background-image: url(https://www.mozilla.org/media/img/logos/firefox/logo-quantum.9c5e96634f92.png);
  background-size: contain;
  width: 160px;
  height: 160px;
  border: 2px solid;
  color: pink;
  resize: both;
  overflow: scroll;
}
```

#### 结果

### cover

`cover` 值指定背景图片的大小，使其尽可能的小，同时确保两个尺寸都大于或等于容器的相应尺寸。试着调整下面这个例子的大小，观察 cover 值的效果。

#### HTML

```html
<div class="bgSizeCover">
  <p>试着缩放这个元素！</p>
</div>
```

#### CSS

```css
.bgSizeCover {
  background-image: url(https://www.mozilla.org/media/img/logos/firefox/logo-quantum.9c5e96634f92.png);
  background-size: cover;
  width: 160px;
  height: 160px;
  border: 2px solid;
  color: pink;
  resize: both;
  overflow: scroll;
}
```

#### 结果

参见
--

* `background-size`
* `background`
* 缩放 SVG 背景


Border-image 生成器 - CSS：层叠样式表

Border-image 生成器
================

这个工具用于生成 CSS `border-image` 的值。