使用 CSS 为 HTML 元素应用颜色 - CSS：层叠样式表

使用 CSS 为 HTML 元素应用颜色
====================

本文主要介绍 HTML 中使用 CSS 颜色的各种方法。

色彩的运用是人类表达的一种基本形式。小孩子在学会绘画前就开始尝试色彩的运用。也许这就是为什么颜色是人们在学习开发网站时最想尝试的东西之一。借助 CSS，有很多方法可以为 HTML 元素添加颜色，以创建所需的外观。

我们将会谈及添加颜色所需要的大部分内容，包括一系列可以着色的元素与相关的 CSS 属性，如何描述颜色，以及在样式表与脚本中使用颜色的方法。同时我们还会了解如何让用户选择颜色。

然后我们会通过简短的讨论总结如何机智地运用颜色：如何选择合适的颜色，同时考虑不同视力水平的人的需求。

可设置颜色的内容
--------

从 HTML 元素层面来看，所有的元素都可设置颜色。但除了元素本身之外，元素中所绘制的事物也可设置颜色，如文本、边框等等。我们将会看到一系列用于设置颜色的 CSS 属性。

在这些设置颜色的 CSS 属性中，最基础的就是 `color` 属性和 `background-color` 属性了。分别用于设置 HTML 元素内容的前景色和背景色。这两个属性几乎可用于所有的 HTML 元素。

### 文本

无论何时渲染元素，这些属性都将用于确定文本的颜色、背景以及文本上的任何装饰。

`color`

绘制文本和任何文本装饰（如添加下划线或上划线、删除线等）时使用的颜色。

`background-color`

文本的背景色。

`text-shadow`

配置应用于文字的阴影效果。阴影选项包括阴影的基色（然后根据其他参数将基色模糊并与背景混合）。请参阅文字阴影以了解更多信息。

`text-decoration-color`

默认情况下，文本装饰（如下划线、删除线等）使用 `color` 属性作为其颜色。不过，你可以使用 `text-decoration-color` 属性覆盖该行为，并为它们使用不同的颜色。

`text-emphasis-color` (en-US)

绘制文本中每个字符旁边的强调符号时使用的颜色。主要用于绘制东亚语言的文本。

`caret-color`

在元素中绘制光标 (en-US)时使用的颜色（有时也称为文本输入光标）。这仅对可编辑的元素有用，如 `<input>` 和 `<textarea>` 或设置了 HTML `contenteditable` 属性的元素。

### 盒

每个元素都是一个包含某种内容的盒子，除了盒子中的内容外，还有背景和边框。

边框

请参阅边框一节，了解可用于设置方框边框颜色的 CSS 属性列表。

`background-color`

在元素中没有前景内容的区域使用的背景色。

`column-rule-color`

绘制文本分隔线时使用的颜色。

`outline-color`

在元素外部绘制轮廓时使用的颜色。该轮廓与边框不同，它不会在文档中预留空间（因此可能会与其他内容重叠）。它通常用作焦点指示器，显示哪个元素将接收输入事件。

### 边框

任何元素都可以在其周围绘制边框。基本的元素边框是围绕元素内容边缘绘制的一条线。请参阅盒模型了解元素与其边框之间的关系，并参阅文章使用 CSS 为边框添加样式了解为边框应用样式的更多信息。

你可以使用 `border` 简写属性，这样就可以一次性配置边框的所有内容（包括边框的非颜色特性，如宽度、样式（实线、虚线等）等等）。

`border-color`

为元素边框的每一侧指定一种颜色。

`border-left-color`、`border-right-color`、`border-top-color` 和 `border-bottom-color`

设置元素边框相应边的颜色。

`border-block-start-color` 和 `border-block-end-color`

通过这些属性，你可以设置用于绘制边框的颜色，这些颜色最靠近边框所包围的区块的起始和结束位置。在从左到右的书写模式下（如英文的书写方式），块向的起始边框是上边缘，结束边框是下边缘。这与行向开始和结束不同，行向开始和结束是左右边缘（对应于方框中每行文本的开始和结束位置）。

`border-inline-start-color` 和 `border-inline-end-color`

通过这些选项，你可以为最靠近方框内文本行开头和结尾的边框边缘着色。至于是哪一边，取决于 `writing-mode`、`direction` 和 `text-orientation` 属性，它们通常（但不总是）用于根据显示语言调整文本方向。例如，如果盒子的文本是从右到左显示的，那么 `border-inline-start-color` 就会应用到边框的右侧。

### 其他使用颜色的方式

CSS 并不是唯一支持颜色的 web 技术。同时还有其他支持颜色的图形技术。

HTML Canvas API

可让你在 `<canvas>` 元素中绘制二维位图图形。请参阅我们的 Canvas 教程了解更多信息。

SVG（可缩放矢量图形）

SVG 可让你使用绘制特定形状、图案和线条的命令来绘制图像。SVG 命令的格式为 XML，可以直接嵌入网页，也可以像其他类型的图像一样，使用 `<img>` 元素放置在网页中。

WebGL

网络图形库是一种基于 OpenGL ES 的 API，用于在 Web 上绘制高性能的 2D 和 3D 图形。请参阅我们的 WebGL 教程了解更多信息。

如何描述颜色
------

要在 CSS 中表示一种颜色，就必须找到一种方法，将“颜色”这一模拟概念转化为计算机可以使用的数字形式。通常的做法是将颜色分解成不同的分量，例如混合一组三原色中每种颜色的多少，或者使颜色的亮度达到多少。因此，在 CSS 中可以有多种方法来描述颜色。

有关每种颜色值类型的详细讨论，请参阅 CSS `<color>` 一节的参考资料。

### 关键字

我们定义了一套标准颜色名称，如果你选择这种方式来描述颜色，可以使用关键字来代替数字表示，但必须有一个关键字来代表你想使用的确切颜色。颜色关键字包括标准的主色和次色（如 `red`、`blue` 或 `orange`）、灰度（从 `black` 到 `white`，包括 `darkgray` 和 `lightgray`）以及各种其他混合色，包括 `lightseagreen`、`cornflowerblue` 和 `rebeccapurple`。

有关颜色关键字的更多信息，请参见具名颜色一节。

### RGB 值

CSS 中有三种表示 RGB 颜色的方式。

#### 十六进制字符串表示法

十六进制字符串表示法用十六进制数字来表示颜色的各个分量（红、绿、蓝）。它还可能包括第四个分量：alpha 通道（或不透明度）。每个颜色分量可以用 0 到 255（0x00 到 0xFF）之间的数字表示，也可以选择用 0 到 15（0x0 到 0xF）之间的数字表示。必须使用相同位数指定所有组件。如果使用个位数符号，最终颜色的计算将使用每个分量的个位数两次；也就是说，`"#D"` 在绘制时会变成 `"#DD"`。

十六进制字符串符号中的颜色总是以字符 `"#"` 开头。之后是颜色代码的十六进制数字。字符串不区分大小写。

`"#rrggbb"`

指定完全不透明的颜色，其红色分量为十六进制数 `0xrr`，绿色分量为 `0xgg`，蓝色分量为 `0xbb`。

`"#rrggbbaa"`

指定一种颜色，其红色分量为十六进制数 `0xrr`，绿色分量为 `0xgg`，蓝色分量为 `0xbb`。Alpha 通道由 `0xaa` 指定；该值越小，颜色就越半透明。

`"#rgb"`

指定一种颜色，其红色分量为十六进制数 `0xrr`，绿色分量为 `0xgg`，蓝色分量为 `0xbb`。

`"#rgba"`

指定一种颜色，其红色分量为十六进制数 `0xrr`，绿色分量为 `0xgg`，蓝色分量为 `0xbb`。Alpha 通道由 `0xaa` 指定；该值越小，颜色就越半透明。

例如，可以用 `"#0000ff"` 或 `"#00f"` 表示不透明的亮蓝色。要使不透明色达到 25%，可以使用 `"#0000ff44"` 或 `"#f00f4"`。

#### RGB 函数表示法

RGB（红/绿/蓝）函数表示法与十六进制字符串表示法一样，都是用红、绿、蓝三种分量（以及可选的表示不透明度的 alpha 通道分量）来表示颜色。不过，定义颜色时使用的不是字符串，而是 CSS 函数 `rgb()` 。该函数的输入参数包括红色、绿色和蓝色分量的值，以及可选的第四个参数，即 alpha 通道的值。

这些参数的合法值分别是：

`red`、`green`、`blue`

每个值都必须是 0 到 255（含）之间的 `<integer>` 值，或 0% 到 100% 之间的 `<percentage>` 值。

`alpha`

alpha 通道是一个介于 0.0（完全透明）和 1.0（完全不透明）之间的数字。你也可以指定一个百分比，0% 等于 0.0，100% 等于 1.0。

例如，50% 不透明的鲜红色可以用 `rgb(255, 0, 0, 0.5)` 或 `rgb(100%, 0, 0, 50%)` 表示。

### 含有色相分量的颜色函数

除了 `rgb()` 以外，你还可以使用 `hsl()` 和 `hwb()`，它们都需要包含 `<hue>` 分量。`<hue>` (en-US) 是一种属性，可以让我们分辨出红、橙、黄、绿、蓝等颜色之间的差异或相似性。关键的是，可以在 `<angle>` 中指定色相，因为大多数颜色模型都是使用色轮 (en-US)来描述色相的。有关这些函数分类的更多信息，请参阅色彩空间和色彩模型部分。

#### HSL 函数表示法

设计师和艺术家通常喜欢使用 HSL（色相/饱和度/亮度）色彩方法。另外，CSS 的 `hsl()` 函数与 `rgb()` 函数的用法类似。

下图显示了一个 HSL 颜色柱。色相将颜色定义为圆形色轮 (en-US)上的 `<angle>`。饱和度是一个百分比，表示在灰色阴影和给定色调的最大可能量之间的百分比。随着亮度（或明度）值的增加，颜色会从最暗过渡到最亮（从黑到白）。

![HSL 颜色柱](/zh-CN/docs/Web/CSS/CSS_colors/Applying_color/640px-hsl_color_solid_cylinder.png)

图片由用户 SharkD 在 Wikipedia 上提供，采用 CC BY-SA 3.0 许可发布。

HSL 颜色的色相（H）分量值是从红色开始，依次经过黄色、绿色、青色、蓝色和洋红色（360° 时又回到红色）的一个角度，用于确定基色。该值可以用 CSS 支持的任何 `<angle>` 单位指定，包括度（`deg`）、弧度（`rad`）、梯度（`grad`）或转数（`turn`）。但这并不能控制颜色的鲜艳或暗淡、明亮或昏暗程度。

颜色的饱和度（S）分量指定最终颜色中指定色相所占的百分比。其余部分则由亮度（L）分量提供的灰度来定义。

把它想象成创造完美的油漆颜色的过程：

1. 首先，你要使用特定颜色的最大强度的基础颜料，例如用户屏幕所能显示的最强烈的蓝色。这就是**色相**（H）分量：该值代表了我们希望用作基色的鲜艳色相在色轮 (en-US)周围的角度。
2. 然后选择与你想要的颜色亮度相对应的灰度颜料；这就是亮度。你希望它非常明亮接近白色，还是非常暗接近黑色，或者介于两者之间？这可以用百分比来表示，0% 表示完全黑，100% 表示完全白（无论饱和度或色调如何）。介于两者之间的数值就是灰色区域。
3. 现在，你有了灰色颜料和鲜艳的颜色，需要将它们混合在一起。颜色的饱和度（S）表示最终颜色中鲜艳颜色所占的比例。最终颜色的其余部分由代表饱和度的灰色颜料组成。

你还可以选择加入一个 alpha 通道，使颜色的不透明度低于 100%。

下面是一些用 HSL 符号表示的颜色示例：
```

table {
  border: 1px solid black;
  font:
    16px "Open Sans",
    Helvetica,
    Arial,
    sans-serif;
  border-spacing: 0;
  border-collapse: collapse;
}

th,
td {
  border: 1px solid black;
  padding: 4px 6px;
  text-align: left;
}

th {
  background-color: hsl(0, 0%, 75%);
}
```

```html
<table>
  <thead>
    <tr>
      <th scope="col">HSL 表示法下的颜色</th>
      <th scope="col">示例</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td><code>hsl(90deg, 100%, 50%)</code></td>
      <td style="background-color: hsl(90deg, 100%, 50%);"> </td>
    </tr>
    <tr>
      <td><code>hsl(90, 100%, 50%)</code></td>
      <td style="background-color: hsl(90, 100%, 50%);"> </td>
    </tr>
    <tr>
      <td><code>hsl(0.15turn, 50%, 75%)</code></td>
      <td style="background-color: hsl(0.15turn, 50%, 75%);"> </td>
    </tr>
    <tr>
      <td><code>hsl(0.15turn, 90%, 75%)</code></td>
      <td style="background-color: hsl(0.15turn, 90%, 75%);"> </td>
    </tr>
    <tr>
      <td><code>hsl(0.15turn, 90%, 50%)</code></td>
      <td style="background-color: hsl(0.15turn, 90%, 50%);"> </td>
    </tr>
    <tr>
      <td><code>hsl(270deg, 90%, 50%)</code></td>
      <td style="background-color: hsl(270deg, 90%, 50%);"> </td>
    </tr>
  </tbody>
</table>
```

**备注：** 如果省略了色相的单位，则假定其单位为度（`deg`）。

#### HWB 函数表示法

与上面的 HSL 函数表示法类似，hwb() (en-US) 函数使用相同的色相值。不过，指定的白度和黑度值不是亮度和饱和度，而是百分比。数值之间**不用**逗号分隔，还可以包含一个可选的 alpha 值（必须在前面加上斜线 `/`）。

下面是一些用 HWB 符号表示的颜色示例：

```css
/\* 这些示例都指定了深浅不一的青绿色。 \*/
hwb(90 10% 10%)
hwb(90 10% 10%)
hwb(90 50% 10%)
hwb(90deg 10% 10%)
hwb(1.5708rad 60% 0%)
hwb(.25turn 0% 40%)

/\* 同样的青绿色，这次包含了透明度值 \*/
hwb(90 10% 10% / 0.5)
hwb(90 10% 10% / 50%)
```

### 色彩空间和颜色模型

十六进制、具名颜色和 `rgb()` 函数都使用 RGB (en-US) 模型，并与 sRGB（`srgb`）色彩空间相关联。你可能会看到“色彩模型”和“色彩空间”交替使用，但这两者之间还是有区别的，值得注意：

* 色彩模型是用数值表示色彩的数学模型。色彩模型描述了如何在色彩空间内创建可用的色彩。
* 色彩空间是对色彩进行分组的系统，因此对任何给定色彩的描述都是一致的。如果在不同的色彩空间之间转换一种颜色，它看起来会完全相同。

我们上面使用的 `hsl()` 和 `hwb()` 函数使用的是 sRGB 色彩空间，并且都使用*柱形*模型；这就是为什么 `<hue>` 角度可以让你像在色轮 (en-US)上一样控制颜色的属性。让我们来看看其他可用的色彩空间以及使用它们的原因。

#### CIELAB 和 Oklab 色彩空间

CIELAB 和 Oklab 色彩空间基于人类视觉实验，代表了人类所能看到的全部色彩范围。这些模型的主要目的在于它们是统一的，因此色彩空间中任意两点之间的给定距离在观察者看来应该是同样不同的。

对于 CIELAB 色彩空间，可以使用 `lab()` 和 `lch()` 函数。`lch()` 函数使用亮度（L）、色度（C）和色调（H），而 Lab 模型则沿色彩空间中的“a”轴和“b”轴（矩形坐标）使用亮度（L）、红/绿度和黄/蓝度。

下面的示例显示了在 `lab()` 和 `lch()` 函数中更改分量值的效果，其中每一行都修改了一个分量。第一行显示的是对 `lch()` 亮度值的更改，第二行更改的是 `lch()` 色调分量。第三行更改了 `lab()` 的“b”轴，因此我们获得了与 `lch()` 不同的效果，因为我们是在逐渐增加颜色中的黄色，而不是在整个色轮中循环：
```

/\* 不同深浅度的紫色 \*/
.container {
  display: grid;
  font-family: sans-serif;
  font-size: 14px;
  color: white;
  grid-template-columns: repeat(6, 1fr);
  gap: 4px;
}

.container div {
  border-radius: 8px;
  padding: 0.75rem;
}

#lch-20 {
  background-color: lch(20 40 0);
}
#lch-30 {
  background-color: lch(30 40 0);
}
#lch-40 {
  background-color: lch(40 40 0);
}

#lch-50 {
  background-color: lch(50 40 0);
}
#lch-60 {
  background-color: lch(60 40 0);
}
#lch-70 {
  background-color: lch(70 40 0);
}

#lch-hue-10 {
  background-color: lch(70 40 10);
}
#lch-hue-20 {
  background-color: lch(70 40 20);
}
#lch-hue-30 {
  background-color: lch(70 40 30);
}
#lch-hue-40 {
  background-color: lch(70 40 40);
}
#lch-hue-50 {
  background-color: lch(70 40 50);
}
#lch-hue-60 {
  background-color: lch(70 40 60);
}
#lab-10 {
  background-color: lab(70 40 10);
}
#lab-20 {
  background-color: lab(70 40 20);
}
#lab-30 {
  background-color: lab(70 40 30);
}
#lab-40 {
  background-color: lab(70 40 40);
}
#lab-50 {
  background-color: lab(70 40 50);
}
#lab-60 {
  background-color: lab(70 40 60);
}
```

```
<div class="container">
  <div id="lch-20">lch(20 40 0)</div>
  <div id="lch-30">lch(30 40 0)</div>
  <div id="lch-40">lch(40 40 0)</div>
  <div id="lch-50">lch(50 40 0)</div>
  <div id="lch-60">lch(60 40 0)</div>
  <div id="lch-70">lch(70 40 0)</div>
  <div id="lch-hue-10">lch(70 40 10)</div>
  <div id="lch-hue-20">lch(70 40 20)</div>
  <div id="lch-hue-30">lch(70 40 30)</div>
  <div id="lch-hue-40">lch(70 40 40)</div>
  <div id="lch-hue-50">lch(70 40 50)</div>
  <div id="lch-hue-50">lch(70 40 60)</div>
  <div id="lab-10">lab(70 40 10)</div>
  <div id="lab-20">lab(70 40 20)</div>
  <div id="lab-30">lab(70 40 30)</div>
  <div id="lab-40">lab(70 40 40)</div>
  <div id="lab-50">lab(70 40 50)</div>
  <div id="lab-60">lab(70 40 60)</div>
</div>
```

Oklab 是一种色彩空间，它使用与 CIELAB 相同的模型类型，但在构建时使用了额外的数值优化步骤，因此其数值被认为比 CIELAB 更精确。由于进行了优化，色调在感知上更加统一，因此 Oklab 是渐变的绝佳选择。如果你已经了解 `lab()` 和 `lch()`，就可以以类似的方式使用这些函数：

```css
.oklch-red {
  color: oklch(0.93 0.39 28);
}
.oklab-green {
  color: oklab(0.87 -0.2 0.18);
}
```

#### `color()` 函数

如果想在定义颜色时明确控制色彩空间，可以使用 `color()` (en-US) 函数。这对使用更宽色域 (en-US)的高清设备描述颜色非常有用。例如，如果我们想显示超出 sRGB 色域的 `display-p3 0 0 1` 颜色，可以使用 `@media` (en-US) at 规则来检测客户端硬件是否支持此范围内的颜色：

```css
.vibrant {
  background-color: color(display-p3 0 0 1);
  /\* 等同于色域之外的 rgb(-27, 55, 153) \*/
}

@media (color-gamut: p3) {
  .vibrant {
    background-color: color(display-p3 0 0 1);
  }
}
```

使用颜色
----

现在，你已经知道有哪些 CSS 属性可以让你为元素着色，也知道了可以用来描述颜色的格式，你可以将它们组合在一起，开始使用颜色了。正如你在可设置颜色的内容下的列表中所看到的，有很多事物都可以用 CSS 着色。让我们从两个方面来看看：在样式表 (en-US)中使用颜色，以及使用 JavaScript 代码添加和更改颜色，以改变元素的样式。

### 在样式表中指定颜色

为元素应用颜色的最简单方法，也是你通常会采用的方法，就是在呈现元素时使用的 CSS 中指定颜色。虽然我们不会使用前面提到的每一个属性，但我们会看几个示例。这个概念在任何使用颜色的地方都是一样的。

让我们来看一个示例，首先看看我们要达到的效果：

#### HTML

创建上述示例的 HTML 代码如下所示：

```html
<div class="wrapper">
  <div class="box boxLeft">
    <p>这是第一个盒子。</p>
  </div>
  <div class="box boxRight">
    <p>这是第二个盒子。</p>
  </div>
</div>
```

这非常简单，只需使用一个 `<div>` 作为内容的包装，内容由另外两个 `<div>` 组成，每个框中都有一个段落（`<p>`），每个段落的样式各不相同。

像往常一样，神奇的事情发生在 CSS 中，我们将在 CSS 中应用颜色并定义上述 HTML 的布局。

#### CSS

我们将逐一查看创建上述结果的 CSS，以便逐一回顾有趣的部分。

```css
.wrapper {
  width: 620px;
  height: 110px;
  margin: 0;
  padding: 10px;
  border: 6px solid mediumturquoise;
}
```

`.wrapper` 类用于为 `<div>` 指定样式，而 `<div>` 则封装了我们所有的其他内容。将使用 `width` 和 `height` 来确定容器的大小，以及其 `margin` 和 `padding`。

在这里，我们更感兴趣的是使用 `border` 属性在元素外边缘建立一个边框。该边框是一条宽 6 像素的实线，颜色为 `mediumturquoise`。

我们的两个彩色盒子有许多共同属性，因此接下来我们要建立一个定义这些共同属性的类 `.box`：

```css
.box {
  width: 290px;
  height: 100px;
  margin: 0;
  padding: 4px 6px;
  font:
    28px "Marker Felt",
    "Zapfino",
    cursive;
  display: flex;
  justify-content: center;
  align-items: center;
}
```

简而言之，`.box` 确定了每个盒子的大小以及内部使用的字体配置。我们还利用 CSS 弹性盒布局，轻松将每个盒子的内容居中。我们使用 `display: flex` 启用 `flex` 模式，并将 `justify-content` 和 `align-items` 都设置为 `center`。然后，我们就可以为两个盒子分别创建一个类，定义两者不同的属性。

```css
.boxLeft {
  float: left;
  background-color: rgb(245, 130, 130);
  outline: 2px solid darkred;
}
```

`.boxLeft` 类巧妙地将方框浮动到左侧，然后设置颜色：

* 将 CSS `background-color` 属性的值改为 `rgb(245,130,130)`，即可设置方框的背景颜色。
* 为方框定义轮廓。与更常用的 `border` 不同，`outline` 完全不影响布局；它画在元素框外的任何东西的顶部，而不是像 `border` 那样腾出空间。这个轮廓是一条两像素粗的暗红色实线。注意在指定颜色时使用了 `darkred` 关键字。
* 请注意，我们没有明确设置文本颜色。这意味着，`color` 的值将从定义它的最近的包含元素继承。默认情况下，就是黑色。

```css
.boxRight {
  float: right;
  background-color: hsl(270deg, 50%, 75%);
  outline: 4px dashed rgb(110, 20, 120);
  color: hsl(0deg, 100%, 100%);
  text-decoration: underline wavy #88ff88;
  text-shadow: 2px 2px 3px black;
}
```

**备注：** 当尝试在 Safari 中显示它时，它将无法正常显示。因为 Safari 不支持 `text-decoration: underline wavy #88ff88`。

最后，`.boxRight` 类描述了绘制在右侧的方框的独特属性。它的配置是将方框浮动到右侧，使其出现在前一个方框的旁边。然后确定以下颜色：

* `background-color` 是使用 `hsl(270deg, 50%, 75%)` 指定的 HSL 值设置的。这是一种中紫色。
* 方框的 `outline` 用于指定将方框括在一条四像素粗的虚线中，该虚线的颜色是略深一些的紫色（`rgb(110, 20, 120)`）。
* 前景（文本）颜色通过将 `color` 属性设置为 `hsl(0deg,100%,100%)` 来指定。这是指定白色的多种方法之一。
* 我们使用 `text-decoration` 在文字下方添加一条绿色波浪线。
* 最后，使用 `text-shadow` 为文字添加一点阴影。其 `color` 参数设置为 `black`。
让用户选择颜色
-------

在许多情况下，网站可能需要让用户选择一种颜色。也许你有一个可定制的用户界面，或者你正在实现一个绘图应用程序。也许你有可编辑的文本，需要让用户选择文本颜色。或者，你的应用程序可以让用户为文件夹或项目指定颜色。虽然从历史上看，有必要实现自己的颜色选择器，但 HTML 现在支持浏览器通过 `<input>` 元素，使用 `"color"` 作为其 `type` 属性的值，提供一个开箱即用的颜色选择器。

`<input>` 元素仅使用上述十六进制字符串表示法表示一种颜色。

### 示例：选择一个颜色

我们来看一个简单的示例，用户可以选择一种颜色。当用户调整颜色时，示例周围的边框会发生变化，以反映新的颜色。完成并选择最终颜色后，颜色选择器的值就会显示出来。

**备注：** 在 macOS 上，关闭颜色选择器窗口即表示已完成颜色选择。

#### HTML

这里的 HTML 创建了一个包含颜色选择器控件（标签使用 `<label>` 元素创建）和一个空段落元素（`<p>`）的盒子，我们将在其中输出 JavaScript 代码中的一些文本。

```html
<div id="box">
  <label for="colorPicker">边框颜色：</label>
  <input type="color" value="#8888ff" id="colorPicker" />
  <p id="output"></p>
</div>
```

#### CSS

CSS 为盒子设定了大小，并为外观设定了一些基本样式。此外，还为边框设定了 2 像素的宽度和边框颜色。

```css
#box {
  width: 500px;
  height: 200px;
  border: 2px solid rgb(245, 220, 225);
  padding: 4px 6px;
  font:
    16px "Lucida Grande",
    "Helvetica",
    "Arial",
    "sans-serif";
}
```

#### JavaScript

此处的脚本负责更新边框的起始颜色，使其与颜色选择器的值相匹配。然后添加两个事件处理程序，以处理来自 `<input type="color">` 元素的输入。

```js
const colorPicker = document.getElementById("colorPicker");
const box = document.getElementById("box");
const output = document.getElementById("output");

box.style.borderColor = colorPicker.value;

colorPicker.addEventListener(
  "input",
  (event) => {
    box.style.borderColor = event.target.value;
  },
  false,
);

colorPicker.addEventListener(
  "change",
  (event) => {
    output.innerText = `颜色已设置为 ${colorPicker.value}。`;
  },
  false,
);
```

每次元素的值发生变化，即每次用户调整颜色选择器中的颜色时，`input` 事件就会被发送。每次该事件发生时，我们都会设置方框的边框颜色，使其与颜色选择器的当前值相匹配。

当颜色选择器的值最终确定时，我们会收到 `change` 事件。我们的回应是将 ID 为 `"output"` 的 `<p>` 元素的内容设置为描述最终选定颜色的字符串。

机智地运用颜色
-------

在设计网站时，正确选择颜色是一个棘手的过程，尤其是如果你不具备美术、设计或至少是基本色彩理论的基础。错误的色彩选择可能会使你的网站失去吸引力，甚至更糟糕的是，由于对比度或色彩冲突问题而导致内容无法阅读。更糟糕的是，如果使用了错误的颜色，会导致有某些视力问题（尤其是色觉障碍）的人根本无法使用你的内容。

### 找到正确的颜色

想出恰到好处的颜色可能很棘手，尤其是没有受过美术或设计训练的人。幸运的是，有一些工具可以帮助你。虽然这些工具无法取代优秀的设计师帮你做这些决定，但它们绝对可以帮你入门。

#### 基本色

第一步是选择**基础色**。这是以某种方式定义网站或网站主题的颜色。正如我们将绿色与饮料激浪联系在一起，将蓝色与天空或海洋联系在一起一样，选择一种合适的基色来代表你的网站是一个很好的开始。选择基色的方法很多，其中包括以下几种：

* 与内容主题自然相关的颜色，例如与产品或理念相关的现有颜色，或代表你希望传达的情感的颜色。
* 来自与内容相关的图像的颜色。如果要创建一个关于特定物品或产品的网站，请选择该物品上实际存在的颜色。
* 浏览网站，查看大量现有的调色板和图片，寻找灵感。

在尝试确定基本颜色时，你可能会发现能让你从网页内容中选择颜色的浏览器扩展程序会特别方便。其中有些甚至是专门为帮助完成此类工作而设计的。例如，ColorZilla 网站提供了一个扩展工具（Chrome 和 Firefox），提供了一个从网页中挑选颜色的滴管工具。它还可以取不同大小区域甚至页面选定区域内像素颜色的平均值。

**备注：** 平均分配颜色的好处在于，通常看起来像纯色的颜色实际上是由多种相关颜色组成的，它们相互配合，创造出理想的效果。如果只选择其中的一个像素，那么得到的颜色本身看起来就很不协调。

#### 丰富调色板

一旦确定了基色，有很多在线工具可以帮助你建立一个合适的颜色调色板，通过对基色应用色彩理论来确定合适的添加颜色，从而与基色一起使用。其中许多工具还支持查看过滤后的颜色，这样你就可以看到这些颜色在各种色盲症患者眼中的效果。请参阅颜色与无障碍，简要了解这一点的原因。

几个示例（截至本列表最后一次修订时，所有示例均可免费使用）：

* MDN 的取色工具
* Paletton
* Adobe Color CC 在线调色盘

在设计调色板时，请务必记住，除了这些工具通常生成的颜色外，可能还需要添加一些核心中性色，如白色（或近似白色）、黑色（或近似黑色）以及一定数量的灰色。

**备注：** 通常情况下，使用尽可能少的颜色会好得多。通过使用色彩来突出重点，而不是为页面上的所有内容都添加色彩，这样就能使内容易于阅读，而且所使用的色彩也更有冲击力。

### 色彩理论的资源

对色彩理论的全面回顾超出了本文的范围，但有很多关于色彩理论的文章，你也可以在附近的学校和大学找到相关课程。以下是一些关于色彩理论的有用资源：

色彩科学（由可汗学院与皮克斯合作）

在线课程：介绍色彩是什么、如何感知色彩以及如何使用色彩表达想法等概念。由皮克斯的艺术家和设计师主讲。

维基百科上的色彩理论

维基百科上的色彩理论：维基百科上的色彩理论条目，从技术角度提供了大量精彩信息。它并不能真正帮助你进行色彩选择，但仍有很多有用的信息。

### 颜色与无障碍

有几种方法可以使颜色成为无障碍问题。色彩使用不当或粗心大意可能导致一部分目标受众无法充分使用网站或应用程序，从而造成流量损失、业务损失，甚至可能引发公共关系问题。因此，慎重考虑色彩的使用非常重要。

你至少应该对色盲进行基本研究。色盲有好几种，最常见的是红绿色盲，它会导致人们无法区分红色和绿色。还有其他一些色盲，从无法区分某些颜色到完全看不到颜色。

**备注：** 最重要的一条规则是：永远不要把颜色作为了解事物的唯一途径。例如，如果你通过将形状的颜色从白色变为绿色（成功）和红色（失败）来表示操作的成功或失败，那么患有红绿色盲的用户将无法正常使用你的网站。相反，也许可以同时使用文字和颜色，这样每个人都能明白发生了什么。

有关色盲的更多信息，请参阅以下文章：

* Medline Plus：色盲 （载于美国国家卫生研究院）
* 美国眼科学会：什么是色盲
* 色盲与网页设计（载于 Usability.gov：美国卫生与公众服务部）
### 调色板设计示例

让我们举一个简单的例子来说明如何为网站选择合适的色调。想象一下，你正在为一款发生在火星上的新游戏建立一个网站。那么，让我们在 Google 搜索火星照片。那里有很多火星色彩的好例子。我们小心地避开了模拟图和电影中的照片。我们决定使用人类在过去几十年中停放在火星表面的火星登陆器拍摄的照片，因为游戏是在火星表面进行的。我们使用颜色拾取工具来选择颜色样本。

使用滴管工具，我们找到了自己喜欢的颜色，并确定该颜色为 `#D79C7A`，这是一种非常适合火星表面的锈橙红色。

选定基色后，我们需要构建调色板。我们决定使用 Paletton 来调出我们需要的其他颜色。打开 Paletton 后，我们可以看到

![Paletton 加载完毕](/zh-CN/docs/Web/CSS/CSS_colors/Applying_color/paletton1.png)

接下来，我们在工具左下角的“Base RGB”框中输入颜色的十六进制代码（`D79C7A`）：

![输入基本颜色后](/zh-CN/docs/Web/CSS/CSS_colors/Applying_color/paletton2.png)

现在我们看到的单色调色板是基于我们从火星照片中选取的颜色。如果你出于某种原因需要很多相关的颜色，那么这些颜色很可能是不错的选择。但我们真正需要的是一种强调色。一种能与基色相得益彰的颜色。要找到这种颜色，我们可以点击菜单下方的“add complementary”（添加补色）切换按钮，选择调色板类型（目前为“Monochromatic”）。Paletton 会计算出一个合适的强调色；点击右下角的强调色，就会告诉我们这个颜色是 `#508D7C`。

![现在包含了强调色](/zh-CN/docs/Web/CSS/CSS_colors/Applying_color/paletton3.png)

如果你对建议的颜色不满意，可以更改配色方案，看看是否能找到你更喜欢的颜色。例如，如果我们不喜欢建议的蓝绿色，我们可以点击“Triad”配色方案图标，就会出现下面的图标：

![选择了 Triad 配色方案](/zh-CN/docs/Web/CSS/CSS_colors/Applying_color/paletton4.png)

右上方的灰蓝色看起来不错。点击它，我们会发现它是 `#556E8D`。这将被用作强调色，在网站的标题、标签或其他指示器的高亮部分等处少量使用，以突出重点：

![选择了 Traid 配色方案](/zh-CN/docs/Web/CSS/CSS_colors/Applying_color/paletton-color-detail.png)

现在，我们有了基础色和强调色。此外，我们还为每种颜色准备了一些互补色调，以备渐变等用途。这些颜色可以以多种格式导出，以便使用。

有了这些颜色之后，你可能还需要选择适当的中性色。通常的设计做法是尽量找到一个最佳点，既要有足够的对比度，使文字清晰可读，又要有足够的对比度，以免刺眼。在某种程度上很容易走得太远，因此在选定颜色并有使用实例后，一定要征求对颜色的反馈意见。如果对比度太低，文字会被背景冲淡，导致无法阅读；但如果对比度太高，用户可能会觉得网站花哨、不好看。

### 颜色、背景、对比度和印刷

在屏幕上看起来不错的内容，在纸上可能会大相径庭。此外，墨水可能很贵，如果用户要打印你的页面，他们不一定需要所有的背景之类的东西来耗费他们宝贵的墨水，因为最重要的是文本本身。大多数浏览器默认情况下都会在打印文档时移除背景图片。

如果你的背景颜色和图像是经过精心挑选的，并且/或者对内容的实用性至关重要，可以使用 CSS `print-color-adjust` (en-US) 属性来告诉浏览器不要对内容的外观进行调整。

`print-color-adjust` 的默认值为 `economy`，表示允许浏览器根据文档绘制到的输出设备类型，在其认为必要时更改外观，以尽量优化内容的可读性和/或打印经济性。

可以将 `print-color-adjust` 设置为 `exact`，以便告诉浏览器，你使用该功能的一个或多个元素是专门设计的，可以在颜色和图像保持原样的情况下达到最佳效果。有了这个设置，浏览器就不会篡改元素的外观，而是按照 CSS 的指示来绘制。

**备注：** 不过，并不能保证 `print-color-adjust: exact` 就能完全按照给定的方式使用 CSS。如果浏览器提供了更改输出的用户首选项（如打印对话框中的“不打印背景”复选框），则该首选项会覆盖 `print-color-adjust` 的值。

参见
--

* 绘制图形
* Web 上的图形
* CSS 颜色模块


色彩选择工具 - CSS：层叠样式表

色彩选择工具
======

这个工具让创建、修改和测试自定义网页颜色变得简单。它还可以轻松实现多种 CSS 支持的颜色格式之间的转换，包括：HEXA、RGB（红、绿、蓝）和 HSL（色相、饱和度、明度）。其中 RGB（rgba）和 HSL（hsla）格式也支持控制透明度通道（alpha channel）。

随着调整，每种颜色都呈现为三种标准 CSS 格式；此外，基于当前选择的颜色，会创建一个 HSL 和 HSV 调色板和阿尔法通道。“滴管”风格的色彩选择框能在 HSL 或 HSV 格式间切换。你也可以拖拽多种颜色至色彩选择框的底部使它们重叠，来测试它们的混合效果。调整它们的相对 Z 值，可以使它们前后移动。

这个工具将帮助你找到最理想的 CSS 颜色应用到你的 HTML。

除非另有说明，否则你所创建生成的颜色可以应用到 CSS 和 HTML 的任何一个地方。

参见
--

更多关于颜色的使用，参见：

* 通过 CSS 将颜色应用到 HTML 元素上
* 基础文本和字体样式
* 通过 CSS 编辑边框样式
* 通过 CSS 改变背景样式
* 颜色及颜色对比


使列表缩进一致 - CSS：层叠样式表

使列表缩进一致
=======

最常见的列表样式更改之一是缩进距离的改变，即列表项向右推移的距离。这往往会导致挫败感，因为在一种浏览器中有效的样式在另一种浏览器中往往没有相同的效果。例如，如果你声明列表没有左侧边距，那么它们在基于 Gecko 的浏览器中就会顽固地保持原位。本文将帮助你了解可能出现的问题以及如何避免这些问题。

要了解为什么会出现这种情况，更重要的是如何完全避免问题，我们有必要研究一下列表构造的细节。

创建一个列表
------

首先，来看一个简单，单独的列表项目。该列表项目没有标记符号（或称之为“着重号”），本身也不是列表的一部分。如下图图 1 所示，简单而朴素。

![图 1](/zh-CN/docs/Web/CSS/CSS_lists/Consistent_list_indentation/consistent-list-indentation-figure1.gif)

红色虚线边框代表列表项内容区域的外部边界。请记住，此时列表项没有任何填充或边框。如果我们再添加两个列表项，结果如图 2 所示。

![图 2](/zh-CN/docs/Web/CSS/CSS_lists/Consistent_list_indentation/consistent-list-indentation-figure2.gif)

现在，我们用一个父元素来封装它们；在本例中，我们将用一个无序列表（即 `<ul>`）来封装它们。根据 CSS 盒模型，列表项的框必须显示在父元素的内容区域内。由于父元素还没有内边距（padding）或外边距（margin），因此我们会看到图 3 所示的情况。

![图 3](/zh-CN/docs/Web/CSS/CSS_lists/Consistent_list_indentation/consistent-list-indentation-figure3.gif)

在这里，蓝色虚线边框向我们显示了 `<ul>` 元素内容区域的边缘。因为我们没有给 `<ul>` 元素添加内边距，所以它的内容的包裹层紧贴在三个列表项外。

现在我们来添加列表项目标记，由于这是一个无序列表，我们添加传统的实心圆“着重标记”，如下图图 4 所示。

![图 4](/zh-CN/docs/Web/CSS/CSS_lists/Consistent_list_indentation/consistent-list-indentation-figure4.gif)

从外观上看，标记位于 `<ul>` 内容区域之外，但这并不是最重要的部分。关键是标记要放在 `<li>` 元素而不是 `<ul>` 元素的“首要盒子”外。它们有点像列表项的附属物，悬挂在 `<li>` 内容区域之外，但仍与 `<li>` 相连。

这就是为什么在每一个现代浏览器中，标记都会被置于为 `<li>` 元素设置的任何边框之外，前提是 `list-style-position` 的值为 `outside`。如果改为 `inside`，那么标记就会出现在 `<li>` 的内容中，就像放在 `<li>` 开头的行内框一样。

二次缩进
----

那么，所有组成部分将如何出现在文档中呢？目前，我们的情况与这些样式类似：

```css
ul,
li {
  margin-left: 0;
  padding-left: 0;
}
```

如果我们把这个列表原封不动地放到文档中，就不会有明显的缩进，标记也会有从浏览器窗口左边缘垮散的危险。

要避免这种情况并获得一定的缩进，浏览器实现者只有三种选择。

1. 给予每个 `<li>` 元素左外边距。
2. 给予 `<ul>` 元素左外边距。
3. 给予 `<ul>` 元素左内边距。

事实证明，似乎没有人使用过第一个选项。第二个选项被 Opera 采用。Firefox 浏览器采用了第三种方案。

让我们先来看看这两种方法。在 Opera 中，通过在 `<ul>` 元素上设置 40 像素的左边距来缩进列表。如果我们对 `<ul>` 元素应用背景色，并保留列表项和 `<ul>` 的边框，就会得到图 5 所示的结果。

![图 5](/zh-CN/docs/Web/CSS/CSS_lists/Consistent_list_indentation/consistent-list-indentation-figure5.gif)

另一方面，Gecko 为 `<ul>` 元素设置了 40 像素的左*内边距*，因此，如果使用与制作图 5 完全相同的样式，将示例加载到基于 Gecko 的浏览器中，就会得到图 6。

![图 6](/zh-CN/docs/Web/CSS/CSS_lists/Consistent_list_indentation/consistent-list-indentation-figure6.gif)

正如我们所看到的，无论标记位于何处，它们都会与 `<li>` 元素相连。两者的区别完全在于 `<ul>` 的样式。只有当我们尝试在 `<ul>` 元素上设置背景或边框时，才能看到其中的区别。

寻求一致
----

综上所述，我们可以得出这样的结论：如果希望在 Gecko 和 Opera 之间一致地呈现列表，需要**同时**设置 `<ul>` 元素的左外边距和左内边距。为此，我们可以完全忽略 `<li>`。如果你想重现 Netscape 6.x 中的默认显示方式，可以这样写：

```css
ul {
  margin-left: 0;
  padding-left: 40px;
}
```

如果对 Opera 采用的模式更感兴趣，那么这样写：

```css
ul {
  margin-left: 40px;
  padding-left: 0;
}
```

当然，也可以填写自己喜欢的值。如果你喜欢，可以将两者都设置为 `1.25em`——没有理由一定要使用基于像素的缩进。如果你想将列表重置为无缩进，那么仍需将外边距和内边距都清零：

```css
ul {
  margin-left: 0;
  padding-left: 0;
}
```

但请记住，这样做会使着重符号挂在列表及其父元素之外。如果父元素是 `body`，那么着重号就很有可能完全位于浏览器窗口之外，从而不可见。

结论
--

最后，我们可以发现，本文中提到的浏览器在列表布局方面都没有对错之分。它们使用不同的默认样式，这就是问题所在。如果能确保同时为列表的左内边距和左外边距设置样式，那么列表缩进的跨浏览器一致性就会大大提高。

建议
--

* 在你调整列表的缩进的时候，务必确认同时设置了内外边距。
原始文档信息
------

* 作者：Eric A. Meyer, Netscape Communications
* 上次更新于：2002 年 8 月 30 日
* 版权信息：2001-2003 Netscape © 版权所有。保留所有权利。
* 备注：这篇转载文章最初是 DevEdge 网站的一部分。


any-pointer - CSS：层叠样式表

any-pointer
===========

**`any-pointer`** CSS 媒体特性 测试用户是否拥有*任意*定点装置（如鼠标）。以及如果存在定点装置，它的精确度是什么样的。

**备注：** 如果你想测试*主*定点设备的精确度，使用 `pointer` (en-US) 。

语法
--

`any-pointer` 特性使用下面的关键字。

`none`

没有可用的定点设备。

`coarse`

至少有一个输入途径包含一个精度有限的定点装置。

`fine`

至少有一个输入途径包含一个精确的定点装置。

**备注：** 当输入设备拥有不同特性时，可能有多于一个的值被匹配。`none` 仅当它们都不是定点设备时被匹配。

示例
--

这个例子为拥有至少一个精确定点装置的用户创建了一个小 checkbox，为拥有至少一个粗略定点装置的用户创建了一个大 checkbox。大 checkbox 的优先级更高，因为它的声明在小 checkbox 的声明后。

### HTML

```html
<input id="test" type="checkbox" /> <label for="test">Look at me!</label>
```

### CSS

```css
input[type="checkbox"]:checked {
  background: gray;
}

@media (any-pointer: fine) {
  input[type="checkbox"] {
    -moz-appearance: none;
    -webkit-appearance: none;
    appearance: none;
    width: 15px;
    height: 15px;
    border: 1px solid blue;
  }
}

@media (any-pointer: coarse) {
  input[type="checkbox"] {
    -moz-appearance: none;
    -webkit-appearance: none;
    appearance: none;
    width: 30px;
    height: 30px;
    border: 2px solid red;
  }
}
```

### 结果

规范
--

| Specification |
| --- |
| Media Queries Level 4 # any-input |

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

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

参见
--

* `pointer` media feature (en-US)


device-height - CSS：层叠样式表

device-height
=============

**已弃用:** 不再推荐使用该特性。虽然一些浏览器仍然支持它，但也许已从相关的 web 标准中移除，也许正准备移除或出于兼容性而保留。请尽量不要使用该特性，并更新现有的代码；参见本页面底部的兼容性表格以指导你作出决定。请注意，该特性随时可能无法正常工作。

**`device-height`** CSS media feature 可以用来测试设备的渲染高度。注意，该条媒体查询将会在 媒体查询 level4（目前处于候选草案）中废弃

语法
--

`device-height` feature is specified as a `<length>` value. It is a range feature, meaning that you can also use the prefixed **`min-device-height`** and **`max-device-height`** variants to query minimum and maximum values, respectively.

例子
--

在高度低于 800px 时加载指定样式

```html
<link
 rel="stylesheet"
 media="screen and (max-device-height: 799px)"
 href="http://foo.bar.com/short-styles.css" />
```

Specifications
--------------

| Specification |
| --- |
| Media Queries Level 4 # device-height |

Browser compatibility
---------------------

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


any-hover - CSS：层叠样式表

any-hover
=========

**`any-hover`** CSS 媒体特性 可以用来测试是否有*任意*可用的输入机制可以在元素上 hover。

语法
--

`any-hover` 使用下面列表的值作为关键字。

`none`

可用的输入机制里没有机制可以方便地 hover，或者不存在定点输入机制。

`hover`

一个或多个可用的输入机制可以方便地在元素上 hover。

示例
--

### 测试是否有输入机制可以 hover

#### HTML

```html
<a href="#">Try hovering over me!</a>
```

#### CSS

```css
@media (any-hover: hover) {
  a:hover {
    background: yellow;
  }
}
```

#### 结果

规范
--

| Specification |
| --- |
| Media Queries Level 4 # any-input |

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

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

更多资料
----

* the `hover` media feature


prefers-color-scheme - CSS：层叠样式表

prefers-color-scheme
====================

**`prefers-color-scheme`** CSS 媒体特性用于检测用户是否有将系统的主题色设置为亮色或者暗色。

语法
--

`no-preference`

表示系统未得知用户在这方面的选项。在布尔值上下文中，其执行结果为 `false`。

`light`

表示用户已告知系统他们选择使用浅色主题的界面。

`dark`

表示用户已告知系统他们选择使用暗色主题的界面。

**备注：** “未得知”、“已告知”等用语，英文原文如此。
 “未得知”可理解为：浏览器的宿主系统不支持设置主题色，或者支持主题色并默认为/被设为了未设置/无偏好。
 “已告知”为：浏览器的宿主系统支持设置主题色，且被设置为了亮色或者暗色。

目前，若结果为 `no-preference`，无法通过此媒体特性获知宿主系统是否支持设置主题色，或者用户是否主动将其设置为无偏好。出于隐私保护等方面的考虑，用户或用户代理也可能在一些情况下在浏览器内部将其设置为 `no-preference`。

示例
--

这个例子使用了一个有黑色背景和白色文字的元素，当用户使用浅色主题时，会翻转黑白颜色。

### HTML

```html
<div class="day">Day (initial)</div>
<div class="day light-scheme">Day (changes in light scheme)</div>
<div class="day dark-scheme">Day (changes in dark scheme)</div>
<br />

<div class="night">Night (initial)</div>
<div class="night light-scheme">Night (changes in light scheme)</div>
<div class="night dark-scheme">Night (changes in dark scheme)</div>
```

### CSS

```css
.day {
  background: #eee;
  color: black;
}
.night {
  background: #333;
  color: white;
}

@media (prefers-color-scheme: dark) {
  .day.dark-scheme {
    background: #333;
    color: white;
  }
  .night.dark-scheme {
    background: black;
    color: #ddd;
  }
}

@media (prefers-color-scheme: light) {
  .day.light-scheme {
    background: white;
    color: #555;
  }
  .night.light-scheme {
    background: #eee;
    color: black;
  }
}

.day,
.night {
  display: inline-block;
  padding: 1em;
  width: 7em;
  height: 2em;
  vertical-align: middle;
}
```

### 结果

规范
--

| Specification |
| --- |
| Media Queries Level 5 # prefers-color-scheme |

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

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

参见
--

* Video tutorial: Coding a Dark Mode for your Website
* Redesigning your product and website for dark mode
* Changing color schemes in Windows, macOS and Android.


aspect-ratio - CSS：层叠样式表

aspect-ratio
============

**`aspect-ratio`** CSS 媒体属性 可以用来测试 viewport 的宽高比。

语法
--

宽高比属性被指定为`<ratio>`值来代表 viewport 的宽高比。其为一个范围，这意味着你可以使用 **`min-aspect-ratio`** 和 **`max-aspect-ratio`** 分别查询最小和最大的值。

示例
--

下面的例子包含一个 `<iframe>`，拥有它自身的 viewport。调整的 `<iframe>` 宽高来观察 `aspect-ratio` 的变化。

### HTML

```html
<div id="inner">
  Watch this element as you resize your viewport's width and height.
</div>
```

### CSS

```css
/\* 最小宽高比 \*/
@media (min-aspect-ratio: 8/5) {
  div {
    background: #9af; /\* blue \*/
  }
}

/\* 最大宽高比 \*/
@media (max-aspect-ratio: 3/2) {
  div {
    background: #9ff; /\* cyan \*/
  }
}

/\* 明确的宽高比，放在最下部防止同时满足条件时的覆盖\*/
@media (aspect-ratio: 1/1) {
  div {
    background: #f9a; /\* red \*/
  }
}
```

### 结果

规范
--

| Specification |
| --- |
| Media Queries Level 4 # aspect-ratio |

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

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


overflow-block - CSS：层叠样式表

overflow-block
==============

CSS 媒体特性 **`overflow-block`** 可用于测试输出设备如何处理沿块向轴溢出初始包含区块的内容。

语法
--

`overflow-block` 特性可指定为下列关键词值之一。

`none`

不显示沿块向轴溢出的内容。

`scroll`

可通过滚动看见沿块向轴溢出的内容。

`optional-paged`

可通过滚动看见沿块向轴溢出的内容，但可手动触发分页（例如通过 `break-inside` 等）使后续内容显示于下一页。

`paged`

内容按页分开；沿块向轴溢出某页的内容显示于下一页。

示例
--

### HTML

```html
<p>
  Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam ac turpis
  eleifend, fringilla velit ac, aliquam tellus. Vestibulum ante ipsum primis in
  faucibus orci luctus et ultrices posuere cubilia Curae; Nunc velit erat,
  tempus id rutrum sed, dapibus ut urna. Integer vehicula nibh a justo imperdiet
  rutrum. Nam faucibus pretium orci imperdiet sollicitudin. Nunc id facilisis
  dui. Proin elementum et massa et feugiat. Integer rutrum ullamcorper eleifend.
  Proin sit amet tincidunt risus. Sed nec augue congue eros accumsan tincidunt
  sed eget ex.
</p>
```

### CSS

```css
@media (overflow-block: scroll) {
  p {
    color: red;
  }
}
```

### 结果

规范
--

| Specification |
| --- |
| Media Queries Level 4 # mf-overflow-block |

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

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

参见
--

* 使用媒体查询
* @media


-webkit-device-pixel-ratio - CSS：层叠样式表

-webkit-device-pixel-ratio
==========================

**非标准:** 该特性是非标准的，请尽量不要在生产环境中使用它！

**`-webkit-device-pixel-ratio`** 是一个非标准的布尔类型 CSS 媒体类型，是标准 `resolution` (en-US) 媒体类型的一个替代方案。

Its value is the number of device pixels used to represent each CSS `px`. Although the value is a `<number>` and thus doesn't syntactically allow units, its implicit unit is `dppx`.

### Syntax

**`-webkit-device-pixel-ratio`** is a range value meaning the prefixed **`-webkit-min-device-pixel-ratio`** and **`-webkit-max-device-pixel-ratio`** are also available.

```css
@media (-webkit-min-device-pixel-ratio: 2) { ... }
/\* is equivalent to \*/
@media (min-resolution: 2dppx) { ... }

/\* And likewise \*/
@media (-webkit-max-device-pixel-ratio: 2) { ... }
/\* is equivalent to \*/
@media (max-resolution: 2dppx) { ... }
```

### Specifications

| Specification |
| --- |
| Compatibility Standard # css-media-queries-webkit-device-pixel-ratio |

### See also

* `-webkit-transform-2d` (en-US)
* `-webkit-transform-3d` (en-US)
* `-webkit-transition` (en-US)
* `-webkit-animation` (en-US)


scripting - CSS：层叠样式表

scripting
=========

**`scripting`** CSS 媒体特性可以用来测试脚本（例如 JavaScript）是否可用。

语法
--

`scripting` 功能指定为从下面列表中选择的关键字值。

`none`

脚本在当前文档上完全不可用。

`initial-only`

脚本在最初的页面加载过程中被启用，但在之后则不被启用。

`enabled`

脚本是受支持的并在当前文档上激活。

示例
--

### HTML

```html
<p class="script-none">You do not have scripting available. :-(</p>
<p class="script-initial-only">
  Your scripting is only enabled during the initial page load. Weird.
</p>
<p class="script-enabled">You have scripting enabled! :-)</p>
```

### CSS

```css
p {
  color: lightgray;
}

@media (scripting: none) {
  .script-none {
    color: red;
  }
}

@media (scripting: initial-only) {
  .script-initial-only {
    color: red;
  }
}

@media (scripting: enabled) {
  .script-enabled {
    color: red;
  }
}
```

### 结果

规范
--

| Specification |
| --- |
| Media Queries Level 5 # scripting |

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

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

参见
--

* 使用媒体查询
* @media


width - CSS：层叠样式表

width
=====

可以使用 `width` CSS `@media` 基于视口宽度（或页面框，用于分页媒体）应用样式。

语法
--

该`width`特性被指定为`<length>`，表示 viewport 宽度的值。这是一个范围特性，也就是说，你也可以使用前缀 **`min-width`** 和 **`max-width`** 分别查询最小值和最大值。

示例
--

### HTML

```html
<div>改变 viewport 的宽度的同时，观察这个元素的变化。</div>
```

### CSS

```css
/\* 精确宽度 \*/
@media (width: 360px) {
  div {
    color: red;
  }
}

/\* 最小宽度 \*/
@media (min-width: 35rem) {
  div {
    background: yellow;
  }
}

/\* 最大宽度 \*/
@media (max-width: 50rem) {
  div {
    border: 2px solid blue;
  }
}
```

### 结果

规范
--

| Specification |
| --- |
| Media Queries Level 4 # width |

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

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


orientation - CSS：层叠样式表

orientation
===========

CSS 媒体属性**屏幕方向**（**`orientation`**）可用于测试视口 viewport（或者对于分页媒体而言的页面框盒）的横纵方向。

**备注：** 此属性不等价于*设备*的屏幕旋转方向。在许多设备上，当屏幕方向为纵向时，打开软键盘将导致视口 viewport 的宽度大于高度，从而导致浏览器突然改用横向样式，而不是保持纵向。

语法
--

`orientation` 属性被指定为下列关键字值中的任意一个。

### 关键字值

`portrait`

viewport 处于纵向，即高度大于等于宽度。

`landscape`

viewport 处于横向，即宽度大于高度。

示例
--

### HTML

```html
<div>Box 1</div>
<div>Box 2</div>
<div>Box 3</div>
```

### CSS

```css
body {
  display: flex;
}

div {
  background: yellow;
}

@media (orientation: landscape) {
  body {
    flex-direction: row;
  }
}

@media (orientation: portrait) {
  body {
    flex-direction: column;
  }
}
```

### 结果

规范
--

| Specification |
| --- |
| Media Queries Level 4 # orientation |

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

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


prefers-reduced-motion - CSS：层叠样式表

prefers-reduced-motion
======================

CSS 媒体查询特性 **`prefers-reduced-motion`** 用于检测用户的系统是否被开启了动画减弱功能。

语法
--

`no-preference`

用户未修改系统动画相关特性。

`reduce`

这个值意味着用户修改了系统设置，将动画效果最小化，最好所有的不必要的移动都能被移除。

用户偏好
----

在火狐中，满足以下条件则 `reduce` 会生效：

* 在 GTK/Gnome 中，可以通过 *GNOME Tweaks*（在“通用”或“外观”菜单中，取决于具体版本）的配置，设置 `gtk-enable-animations` 的值为 `false`。
    + 可以在 GTK 3 的配置文件中的 `[Settings]` 模块下设置 `gtk-enable-animations = false`。
* 在 Windows 10 中：设置 > 轻松获取 > 显示 > 在 Windows 中显示动画。
* 在 Windows 7 中：控制面板 > 轻松获取 > ?是计算机更易于查看 > 关闭不必要动画。
* 在 MacOS 中：系统偏好 > 辅助使用 > 显示 > 减少运动。
* 在 iOS 上：设置 > 通用 > 辅助性 > 减少运动。
* 在 Android 9+ 上：设置 > 辅助性 > 移除动画。
例子
--

下面的例子将会展示一组令人心烦的动画，不过当你开启了系统的“减少运动”后就能看到动画减弱的效果了。

### HTML

```html
<div class="animation">animated box</div>
```

### CSS

```css
.animation {
  animation: vibrate 0.3s linear infinite both;
}

@media (prefers-reduced-motion: reduce) {
  .animation {
    animation: none;
  }
}
```

```
.animation {
  background-color: rebeccapurple;
  color: #fff;
  font:
    1.2em Helvetica,
    arial,
    sans-serif;
  width: 200px;
  padding: 1em;
  border-radius: 1em;
  text-align: center;
}

/\* ----------------------------------------------
 \* Generated by Animista on 2018-9-2 13:47:0
 \* w: http://animista.net, t: @cssanimista
 \* ---------------------------------------------- \*/

/\*\*
 \* ----------------------------------------
 \* animation vibrate-1
 \* ----------------------------------------
 \*/

@keyframes vibrate {
  0% {
    transform: translate(0);
  }
  20% {
    transform: translate(-2px, 2px);
  }
  40% {
    transform: translate(-2px, -2px);
  }
  60% {
    transform: translate(2px, 2px);
  }
  80% {
    transform: translate(2px, -2px);
  }
  100% {
    transform: translate(0);
  }
}
```

### Result

规范
--

| Specification |
| --- |
| Media Queries Level 5 # prefers-reduced-motion |

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

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

参考
--

* An introduction to the reduced motion media query


hover - CSS：层叠样式表

hover
=====

该 **`hover`** CSS `@media` 可以根据用户的主要输入机制是否可以悬停在元素之上来应用样式。

语法
--

悬停功能指定为从下面列表中选择的关键字值。

`none`

主要输入机制无法悬停或不方便悬停（例如，当用户执行不方便的长按操作时，许多移动设备模拟悬停），或者没有主指示输入机制。

`hover`

主要输入机制可以方便地悬停在元素上。

示例
--

### HTML

```html
<a href="#">Try hovering over me!</a>
```

### CSS

```css
@media (hover: hover) {
  a:hover {
    background: yellow;
  }
}
```

### 结果

规范
--

| Specification |
| --- |
| Media Queries Level 4 # hover |

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

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

参见
--

* the `any-hover` media feature


overflow-inline - CSS：层叠样式表

overflow-inline
===============

CSS 媒体特性 **`overflow-inline`** 可用于测试输出设备如何处理沿行向轴溢出初始包含区块的内容。

语法
--

`overflow-inline` 特性可指定为下列关键词值之一。

`none`

不显示沿行向轴溢出的内容。

`scroll`

可通过滚动看见沿行向轴溢出的内容。

示例
--

### HTML

```html
<p>
  Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam ac turpis
  eleifend, fringilla velit ac, aliquam tellus. Vestibulum ante ipsum primis in
  faucibus orci luctus et ultrices posuere cubilia Curae; Nunc velit erat,
  tempus id rutrum sed, dapibus ut urna. Integer vehicula nibh a justo imperdiet
  rutrum. Nam faucibus pretium orci imperdiet sollicitudin. Nunc id facilisis
  dui. Proin elementum et massa et feugiat. Integer rutrum ullamcorper eleifend.
  Proin sit amet tincidunt risus. Sed nec augue congue eros accumsan tincidunt
  sed eget ex.
</p>
```

### CSS

```css
p {
  white-space: nowrap;
}

@media (overflow-inline: scroll) {
  p {
    color: red;
  }
}
```

### 结果

规范
--

| Specification |
| --- |
| Media Queries Level 4 # mf-overflow-inline |

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

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


使用 CSS 的多列布局 - CSS：层叠样式表

使用 CSS 的多列布局
============

**CSS 多列布局**扩展*块布局模式*，以便更容易地定义多列文本。如果一行太长，人们阅读文本很麻烦; 如果眼睛从一行的终点移动到下一个行的开始需要太长时间，它们就会丢失它们所在的行。因此，为了最大限度地利用大屏幕，作者应该将宽度不等的文本列并排放置，就像报纸一样。

糟糕的是如果不使用 CSS 和 HTML 在特定的位置强制换行，或者严格限制文本中允许的标记，或者夸张地使用脚本的话，这是不可能实现的。该限制通过从传统的块级布局模块中延伸出来的新的 CSS 属性得以解决。

使用多列布局
------

### 列计数器和宽度

有两个 CSS 属性控制是否实现多列布局和显示多少列：`column-count` 和 `column-width` (en-US)。

属性 `column-count` 设置特定数量的列数。例如：

示例 1
----

### HTML

```html
<div id="col">
  <p>
    Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod
    tempor incididunt ut labore et dolore magna aliqua.
  </p>
  <p>
    Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut
    aliquip ex ea commodo consequat.
  </p>
  <p>
    Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore
    eu fugiat nulla pariatur.
  </p>
  <p>
    Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia
    deserunt mollit anim id est laborum.
  </p>
</div>
```

### CSS

```css
#col {
  column-count: 2;
}
```

### 结果

内容将显示在两列中（如果你使用的是兼容多列布局的浏览器）：

属性 `column-width` 设置期望的最小列宽。如果 `column-count` 没有设置，那么浏览器就会以合适的宽度尽量显示更多的列。

示例 2
----

### HTML

```html
<div id="wid">
  Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod
  tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam,
  quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
  consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse
  cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non
  proident, sunt in culpa qui officia deserunt mollit anim id est laborum
</div>
```

### CSS

```css
#wid {
  column-width: 100px;
}
```

### 结果

详细细节在 CSS Multi-column Layout Module Level 1 中。

在多列块中，内容会自动从一列换到另一列中。所有 HTML，CSS 和 DOM 功能在列之间都得到支持，比如编辑和打印。

### columns 属性简写

多数时候，网页设计者都会使用 `column-count` 和 `column-width` (en-US) 的一个。由于它们的值没有重叠，一般使用简写属性 `columns`。例如，

CSS 声明 `column-width: 12em` 可替换成 `columns: 12em`。

示例 3
----

### HTML

```html
<div id="col\_short">
  Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod
  tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam,
  quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
  consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse
  cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non
  proident, sunt in culpa qui officia deserunt mollit anim id est laborum
</div>
```

### CSS

```css
#col\_short {
  columns: 12em;
}
```

CSS 声明 `column-count: 4` 可替换成 `columns: 4`。

示例 4
----

### HTML

```html
<div id="columns\_4">
  Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod
  tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam,
  quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
  consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse
  cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non
  proident, sunt in culpa qui officia deserunt mollit anim id est laborum
</div>
```

### CSS

```css
#columns\_4 {
  columns: 4;
}
```

### 结果

CSS 声明 `column-width: 8em` 和 `column-count: 12` 可替换成 `columns: 12 8em`。

示例 5
----

### HTML

```html
<div id="columns\_12">
  Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod
  tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam,
  quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
  consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse
  cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non
  proident, sunt in culpa qui officia deserunt mollit anim id est laborum
</div>
```

### CSS

```css
#columns\_12 {
  columns: 12 8em;
}
```

### 结果

### 高度平衡

CSS3 多列规范需要列高平衡：即，浏览器自动设置最大列高，因此每列中的内容高度大致相同。Firefox 浏览器是这样的。

然而，一些情况下，明确设置最大列高也是有用的，这样内容从第一列开始，尽可能多的生成列，甚至会溢出右边沿。因此，如果通过设置`height` 或 `max-height` 属性来限制列高，在生成新的一列之前每一列都会仅允许增加到这个高度。该模型对布局来说也更高效。

### 列间隙

列之间有缝隙。建议值为 `1em`。该值可通过设置多列模块的 `column-gap` 属性来修改：

示例 6
----

### HTML

```html
<div id="column\_gap">
  Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod
  tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam,
  quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
  consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse
  cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non
  proident, sunt in culpa qui officia deserunt mollit anim id est laborum
</div>
```

### CSS

```css
#column\_gap {
  column-count: 5;
  column-gap: 2em;
}
```

### 结果

优雅降级
----

多列属性会被不支持多列模型的浏览器忽略。因此，为这些浏览器创建单列结构而为支持多列的浏览器创建多列结构相对来说比较简单。

讨论
--

CSS3 多列特性能帮助网页设计者最优化使用屏幕资源。如果你是一位具有丰富想象力的开发者，你会发现多列特性更多的好处，特别是在高度平衡特性方面。


处理 Multicol 中的溢出 - CSS：层叠样式表

处理 Multicol 中的溢出
================

在本指南中，我们将了解 multicol 如何处理溢出，包括在列框内以及内容超出容器容量的情况。

column boxes 内部溢出
-----------------

当子项的大小大于列框时，就会发生溢出。例如，当列中的图像宽度大于 `column-width` 值或基于 `column-count` 声明的列数生成的列宽度时，就可能会发生这种情况。

在这种情况下，内容溢出（并且是可见的）到下一列，而不是被列框裁切。你可以在下面的示例中看到，在编写本文时，浏览器以不同的方式处理预期的呈现图像。

![](/zh-CN/docs/Web/CSS/CSS_multicol_layout/Handling_overflow_in_multicol_layout/image-overflow-multicol.png)

如果你想要一个图像尺寸缩小到适合列框，标准的响应式的解决方案是设置最大宽度:100%。

更多的列
----

如何处理溢出的列取决于是在一个片段化的媒体上下文（比如打印）中，还是在一个连续的媒体上下文（比如 web 页面）中。

在一个片段化的媒体中，一旦碎片（例如页面）中充满了列，多出的列将移至新页面。在连续介质中，列将沿横向溢出。在 web 上，这意味着水平滚动条的出现。

下面的示例显示了这种溢出行为。multicol 容器有一个高度，列的文本多于空间，因此多出的列会在容器外面出现。

本规范的未来版本中，会允许横向溢出的列向下排列，用户能向下滚动鼠标查看溢出的列。

使用纵向的媒体查询
---------

multicol 在 web 上的一个问题：如果你的列比 viewport 高，读者需要上下滚动来阅读，这样的用户体验不好。避免这种情况的一种方法是，只有在有足够的高度时才应用列属性。

在下面的示例中，我们使用了 `min-height`。

在本系列的最后一篇指南中，我们将看到片段化下的 Muticol 如何使用的规范，去控制列内容的溢出。


多列布局的样式 - CSS：层叠样式表

多列布局的样式
=======

由于在多列（*multicol*）容器中创建的列盒子是匿名盒子，我们可以对其进行的样式设置非常有限。然而，我们还是有一些可以做的事情。本指南解释了如何更改列之间的间距和样式规则。

为列盒子设置样式
--------

非常遗憾，目前无法为列盒子设置样式。构成你的列盒子的匿名盒子无法以任何方式定位，这意味着无法更改盒子的背景颜色或使一个列大于其他列。也许在未来的规范版本中可以实现。然而，目前我们可以更改列之间的间距并在列之间添加线条。

列间距
---

列之间的间距由 `column-gap` 属性控制。该属性最初在多列布局规范中定义。然而，现在它在盒子对齐中定义，以便统一其他规范（如 CSS 网格布局）中的盒子间距。

在多列中，`column-gap` 的初始值为 `1em`。这意味着你的列不会相互挤压。在其他布局方法中，`column-gap` 的初始值为 0。如果使用关键字值 "normal"，间距将设置为 1em。

你可以通过将 `column-gap` 的值设置为任何长度单位来更改间距。在下面的示例中，`column-gap` 设置为 40px。

`column-gap` 允许的值是 `<length-percentage>`，这意味着允许使用百分比。`column-gap` 的百分比值是根据多列容器宽度的百分比计算的。

分栏线条
----

该标准定义了 `column-rule-width`、`column-rule-style` 和 `column-rule-color`，并提供了简写 `column-rule`。这些属性的工作方式与 `border` 属性完全相同：任何有效的 `border-style` 都可以用作 `column-rule-style`。

这些属性应用于多列容器元素，因此所有列将具有相同的分栏线条。分栏线条仅在列之间绘制，而不在外部边缘绘制。分栏线条还应仅在具有内容的列之间绘制。

在接下来的示例中，使用长格式值创建了一个宽度为 5px、颜色为 `rebeccapurple` 的点状分栏线条。

请注意，分栏线条本身不占用任何空间：宽分栏线条不会将列分开以为分栏线条腾出空间。相反，分栏线条覆盖了间隙。

下面的示例使用了非常宽的 40px 分栏线条和 10px 间距。分栏线条在列内容的下方显示。为了在分栏线条两侧腾出空间，间距需要增加到大于 40px。

下一步
---

本文详细介绍了目前可以为列盒子设置样式的所有方法。在下一篇指南中，我们将讨论如何让容器内的元素跨越所有列。


Basic Concepts of Multicol - CSS：层叠样式表

Basic Concepts of Multicol
==========================

多列布局（通常称为 multicol）是一种规范，用于将内容布置到一组列框中，就像报纸中的列一样。本指南解释了规范如何与一些常见的用例示例一起使用。

关键概念和术语
-------

Multicol 与 CSS 中的任何其他布局方法不同，它将内容（包括所有后代元素）分段为列。这与在使用 CSS Paged Media 时将内容分段为页面的方式相同，例如通过创建打印样式表。

规范定义的属性有：

* `column-width` (en-US)
* `column-count`
* `columns`
* `column-rule-color`
* `column-rule-style`
* `column-rule-width`
* `column-rule`
* `column-span`
* `column-fill` (en-US)
* `column-gap`

通过给一个元素添加 column-count 或 column-width，该元素变成了多列容器，或简称为 multicol 容器。这些列是都是匿名的盒子，在规范中描述为列盒子。

columns 定义
----------

创建一个 multicol 容器必须使用至少一个 column-\* 属性，这些就是 column-count 和 column-width。

### `column-count` 属性

`column-count` 属性指定你想要显示内容的列的数量。浏览器会将正确分配的空间给每列并创建需要的列数。

在以下示例中，我们使用 column-count 属性在 `.container` 元素上创建三列。 `.container` 元素的内容包括其子元素都会分裂成三列。

在上面的例子中内容被段落 p 标签的默认样式包裹。因此，每段都有一个间距。你可以看到这个间距引起第一行文本被推了下来。这是因为 multicol 容器创建了一个新的块格式化上下文（BFC)，这意味着子元素的间距不会与父容器的间距互相重叠。

### `column-width` 属性

`column-width` 属性用于给每列设置一个最佳宽度。如果你声明 `column-width`,浏览器将算出 该宽度在 multicol 容器能分多少列，并且把额外的的空间填充到这些列当中。因此，应将列宽视为最小宽度，因为由于额外的空间，列可能而更宽。

当单个列的可用宽度小于 column-width 的值的情况下，列的宽度会缩小为小于所声明的列宽。

在以下示例中，我们使用 column-width 属性值为 200 px。但最终为了适配容器，列的宽度却大于 200 像素，额外的空间被平均分配了。

### 同时使用 `column-count` 和 `column-width`

如果在 multicol 容器上指定这两个属性，则 `column-count` 将作为最大列数。因此，将按`column-width` 的值计算，直到达到 `column-count` 定义的列数。在此之后，即使有足够的空间容纳指定列宽大小的列，也不再绘制，并且额外空间在现有列之间均匀分布。

同时使用这两个属性时，可能会获得的列数少于 `column-count` 数值中指定的列数。

在下一个例子中，我们使用 column-width 的值为 200px，column-count 的值为 2。即使有超过两列的空间，我们也得到两个。如果没有足够的空间容纳两列 200px，我们得到一个。

### `columns` 缩写

你可以使用 columns 缩写来设置 `column-count` 和 `column-width`。如果设置长度单位，这将用于 `column-width`，设置一个整数，它将用于 `column-count`。你可以设置两者，用空格分隔这两个值。

此 CSS 结果与示例 1 相同，column-count 设置为 3。
```

.container {
  columns: 3;
}
```

此 CSS 结果与示例 2 相同，column-width 为 200px。
```

.container {
  columns: 200px;
}
```

此 CSS 结果与示例 3 相同，同时设置 column-count 和 column-width。
```

.container {
  columns: 2 200px;
}
```

下一步
---

在本指南中，我们学习了多列布局的基本用法。在下一个指南中，我们将看看我们可以为列本身设置多少样式。


在选择器中使用 :target 伪类 - CSS：层叠样式表

在选择器中使用 :target 伪类
==================

为了辅助标识那些指向文档特定部分链接的目标，CSS3 选择器 引入了 `:target` 伪类. Netscape 7.1 已经在 Netscape 系列中加入了这个伪类的支持，这一新的举措让页面作者能够辅助用户在较大的页面中定位。

### 选择一个目标

`:target` 伪类用来指定那些包含片段标识符的 URI 的目标元素样式。例如 `https://developer.mozilla.org/zh-CN/docs/Web/CSS#参考` 这个 URI 包含了 `#参考` 片段标识符 在 HTML 中，标识符是元素的 `id` 或者 `name` 属性。由于这两者位于相同的命名空间，因此，这个示例 URI 指向的是文档顶层的“参考”。

假设你想修改 URI 指向的任何 h2 元素，但是又不想把样式应用到任何其他同类型的元素，那么以下示例足够简单有用：
```

h2:target {font-weight: bold;}
```

同样的，将样式应用于特定的文档片段也是可行的。这是通过使用 URI 中相同的标识符实现的。例如，要在 #Example 文档片段中加入边框，我们可以通过如下代码实现：
```

#Example:target {border: 1px solid black;}
```

### 定位所有元素

如果想要创建应用于所有目标元素的样式，那么可以使用通用选择器：
```

:target {color: red;}
```

### 示例

在以下示例中，5 个链接指向了同一文档中的元素。例如，选择 "First" 链接会导致 `<h1 id="one">` 成为目标元素。注意，由于目标元素有可能会被放置到浏览器窗口的顶层，因此文档可能会跳到新的滚动位置。
```

<h4 id="one">...</h4> <p id="two">...</p>
<div id="three">...</div> <a id="four">...</a> <em id="five">...</em>

<a href="#one">First</a>
<a href="#two">Second</a>
<a href="#three">Third</a>
<a href="#four">Fourth</a>
<a href="#five">Fifth</a>
```

### 结论

在片段标识符指向部分文档的情况下，读者可能会对到底应该阅读文档的哪一部分感到疑惑。通过对不同的目标元素的样式进行修饰，读者的相关疑惑会减少或者消除。

### 相关链接

* CSS3 Selectors #target-pseudo
* CSS Reference :target
### Original Document Information

* Author(s): Eric Meyer, Standards Evangelist, Netscape Communications
* Last Updated Date: Published 30 Jun 2003
* Copyright Information: Copyright © 2001-2003 Netscape. All rights reserved.
* Note: This reprinted article was originally part of the DevEdge site.


区块、绝对定位和表格布局中的盒子对齐 - CSS：层叠样式表

区块、绝对定位和表格布局中的盒子对齐
==================

盒子对齐规范详细说明了对齐在各种布局方法中的工作原理。在本页，我们研究盒子对齐在块布局上下文中的工作方式，包括浮动、定位和表格元素。由于本页旨在详细介绍专门与块布局和盒子对齐相关的内容，它应与主要的盒子对齐页面一起阅读，该页面详细介绍了盒子对齐在各种布局方法中的共同特性。

**备注：** 在撰写本文时（2018 年 5 月），块布局中实际上还不支持盒子对齐属性。本文详细介绍了这些属性在规范中如何期望被实现的情况，以求完整性，并可能会随着规范和浏览器实现的发展而改变。

align-content 和 justify-content
-------------------------------

`justify-content` 属性不适用于块容器或表格单元格。

`align-content` 属性适用于块向轴，以对容器中的内容进行对齐。如果请求了一个内容分布方法如 `space-between`、`space-around` 或 `space-evenly`，那么将使用后备对齐，因为内容被视为一个对齐主体 (en-US)。

justify-self
------------

`justify-self` 属性用于在行向轴上对包含块中的项目进行对齐。

此属性不适用于浮动元素或表格单元格。

align-self
----------

`align-self` 属性不适用于块级框（包括浮动），因为块轴上有多个项目。它也不适用于表格单元格。

### 使用绝对定位的元素

对齐容器是带有 top、left、bottom 和 right 偏移值的定位块。正常关键字解析为 `stretch`，除非定位项目是一个替换元素，在这种情况下它解析为 `start`。

在这些布局方法中进行对齐的现状
---------------

由于我们当前没有浏览器支持块布局中的盒子对齐，因此你可以选择使用现有的对齐方法之一，或者将容器内的单个项目设置为弹性项目，以使用弹性盒子中指定的的对齐属性。

区块水平对齐在弹性盒子之前通常通过对块设置自动边距来实现。`margin` 值为 `auto` 会吸收该维度中所有的可用空间，因此通过为块设置左右自动边距可以将其居中：

```css
.container {
  width: 20em;
  margin-left: auto;
  margin-right: auto;
}
```

在表格布局中，你可以使用 `vertical-align` 属性对单元格中的内容在该单元格内进行对齐。

对于许多使用场景，将块容器转换为弹性项目将为你提供所需的对齐能力。在下面的示例中，含有单个项目的容器已转换为弹性容器，以便能够使用对齐属性。

参考
--

### CSS 属性

* `justify-content`
* `align-content`
* `justify-self`
* `align-self`
### 术语条目

* 对齐主体 (en-US)
* 对齐容器 (en-US)
* 后备对齐 (en-US)


Box alignment in Flexbox - CSS：层叠样式表

Box alignment in Flexbox
========================

Box Alignment 规范详细说明了对齐 (alignment) 在各种布局方法中的工作原理; 在此页面中，我们将探讨盒子对齐（box aligment）在 Flexbox 环境中的工作原理。由于此页面旨在详细说明特定于 Flexbox 和框对齐的内容，因此应与Box Alignment 页面一起阅读，该页面详细说明了不同布局方法的框对齐的常见方法。

基础示例
----

在此示例中，使用`justify-content`在主轴上对齐三个弹性元素（flex items），并使用`align-items`在十字轴上对齐。第一个元素通过将`align-self`设置为居中来覆盖在父元素设置的 align-items 值。

轴 与 flex-direction
------------------

Flexbox 与文档的写入模式有关，因此如果你使用英语并将`justify-content`设置为 flex-end，则会将项目对齐到 Flex 容器的末尾。如果你将`flex-direction`设置为行，则此对齐将处于内联方向。

但是，在 Flexbox 中，你可以通过将 flex-direction 设置为 column 来更改主轴。在这种情况下，justify-content 将在块方向上对齐项目。因此，在 Flexbox 中工作时最容易考虑主轴和纵轴，如下所示：

* 主轴由`flex-direction`设置方向，通过`justify-content` 属性对齐
* 纵轴穿过主轴，通过`align-content`，`align-self` / `align-items`对齐
### 主轴

* `justify-content`
### 纵轴

* `align-self`
* `align-items`
* `align-content`
### justify-self 在 Flexbox 布局中失效

在主轴上，Flexbox 将我们的内容作为一个组进行处理。计算布置子元素所需的空间量，然后剩余空间可用于分配。 `justify-content`属性控制剩余空间的使用方式。设置`justify-content：flex-end`，额外空间放在所有子元素之前，`justify-content：space-around`，它放在该维度的子元素的两侧，等等。

这意味着在 Flexbox 中，`justify-self`属性没有意义，因为我们总是处理移动整个元素组。

在十字轴上，`align-self`是有意义的，因为我们可能在该维度中的 flex 容器中有额外的空间，其中单个元素可以移动到开始和结束位置。

对齐 与 auto margins
-----------------

在 Flexbox 中有一个特定的用例，我们可能会认为`justify-self`是我们需要的，这就是我们想要分割一组 flex items，也许是为了创建一个分割导航模式。对于此用例，我们可以使用自动边距。设置为 auto 的边距将吸收其维度中的所有可用空间。这就是以自动边距为中心的块的工作原理。通过将左右边距设置为 auto，我们块的两侧都会尝试占用所有可用空间，因此将盒子推入中心。

通过在一组弹性项目中的一个项目上设置 auto 的`margin`全部对齐以开始，我们可以创建拆分导航。这适用于 Flexbox 和对齐属性。一旦没有可用于自动边距的空间，该项目的行为与所有其他弹性项目的行为相同，并且收缩以尝试适合空间。

`gap` 属性
--------

* `row-gap`
* `column-gap`
* `gap`
### 在子元素之间创建固定大小的差距

在主轴上，`column-gap`属性将在相邻项之间创建固定大小的间隙。

在纵轴上，`row-gap`属性将在相邻的子元素之间创建间距，因此还必须将`flex-wrap`设置为`wrap`,以使其具有任何效果。

**备注：** 从 Firefox 63 开始，Firefox 是唯一实现 Flexbox gap 属性的浏览器。

Reference
---------

### CSS Properties

* `justify-content`
* `align-content`
* `place-content`
* `justify-items`
* `align-items`
* `place-items`
* `align-self`
* `row-gap`
* `column-gap`
* `gap`
### Glossary Entries

* Cross axis
* Main axis
Guides
------

* Alignment in flexbox
External Resources
------------------

* Box alignment cheatsheet
* CSS Grid, Flexbox and Box Alignment
* Thoughts on partial implementations of Box Alignment


Web 开放字体格式（WOFF） - CSS：层叠样式表

Web 开放字体格式（WOFF）
================

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

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

* Learn more
* See full compatibility
* Report feedback
**WOFF**（**Web Open Font Format**，Web 开放字体格式）是由 Mozilla 与 Type Supply、LettError 及其他组织协同开发的一种新的网页字体格式。它使用了与 TrueType、OpenType、Open Font 所采用的 `sfnt` 结构类似的压缩算法，不过还添加了元数据（metadata）及私有数据结构，其中包括了自定义空间，允许厂家和经销商在需要时提供许可证。

WOFF 有以下三点优势：

1. 字体采用压缩格式，因此，使用 WOFF 的网站将使用更少的带宽，并且比使用同等的未压缩的 TrueType 或 OpenType 文件加载更快。
2. 许多字体经销商并不愿意将 TrueType 或 OpenType 的许可证颁发给网站，他们更愿意颁发 WOFF 的许可证。这提高了网站设计者对字体的可用性。
3. 无论是收费还是免费的浏览器厂家都喜欢 WOFF 格式，因此它很可能成为真正通用的、可互操作的网络字体格式，这与目前其他的字体格式不同。

WOFF 有两个版本：WOFF 和 WOFF2。它们之间最大的差别体现在使用的压缩算法上。在 `@font-face` 属性中，它们使用 `'woff'` 和 `'woff2'` 这两个标识符来区分。

使用 WOFF
-------

通过 `@font-face` 这个 CSS 属性来为你的网站使用 WOFF 字体。它的工作原理与 OpenType 和 TrueType 格式的字体完全一样，只是由于增加了压缩功能，它可能会让你的内容下载更有效率。

用于处理 WOFF 字体的工具
---------------

* 用于处理 WOFF 字体的工具。`sfnt2woff` 和 `woff2sfnt` 可以在 WOFF 和 OpenType 之间相互转换。
规范
--

| Specification |
| --- |
| WOFF File Format 1.0 # OverallStructure |
| WOFF File Format 2.0 # FileStructure |

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

### css.at-rules.font-face.WOFF

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

### css.at-rules.font-face.WOFF\_2

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

参见
--

* `@font-face`


OpenType 字体特性指南 - CSS：层叠样式表

OpenType 字体特性指南
===============

字体特性（font feature）或变体（variant）指的是在同一个 OpenType 字体中包含的不同的字形或字母风格。它包括了连字（ligature，由字符组合而成的特殊字形，如“ﬁ”或“ﬄ” ），字偶距（kerning，调整特定字母组合的间距），分数形式，数字风格，和一票其他内容。这些都被称为 OpenType 特性，而且可以通过特定属性和一种底层属性指定（见 `font-feature-settings`）来控制。本文将介绍在 CSS 中使用 OpenType 字体特性的全部内容。

某些字体中启用了这些特性的一或多个（通常是字偶距 [kerning] 和默认连字），而其他特性留给设计师或开发者选择性地在特定场景中启用。

除了连字或齐行数字（数字排列均匀，而“老式”数字的看起来像小写字母）等广泛应用的特性，还有非常特殊的一部分，如样式集（stylistic set，可能含有几种特定的字形变体 [variant]，它们可以一起使用），甚至是特定的东亚文字的字形变化。最后一种情况，使用变更的字形对于恰当的表达非常必要，所以这些属性比起大部分样式集更加重要，也超过其他大部分 OpenType 特性。

**警告：** CSS 定义了很多的属性用以改变字体特性，然而很多没有完全实现。这里给出了所有属性的定义，但是大部分都只能用底层属性 `font-feature-settings` 来控制。可以同时使用两种方式定义 CSS，但是可能太笨重了。而只使用 `font-feature-settings` 控制一切的问题是，每次你要变动一个特性，就必须处理整个字符串（类似于用 `font-variation-settings` 操纵变量字体）。

了解字体的可用特性
---------

有时，最麻烦的问题在于你没有字体的说明文档（许多字体设计师和厂商会提供样张和 CSS 范例，以便用户了解字体特性）。不过，有一些网站可以方便地显示出字体特性。例如，访问 wakamaifondue.com，把你的字体文件拖到圈里（页面上有提示），过一会就可以得到该字体文件功能、特性的完整报告。Axis-praxis.org 也提供类似的功能，只需点击一下字体特性，就可以在相应的文本块中打开或关闭这些特性。

为什么使用字体特性？
----------

花工夫来了解和使用这些字体特性有些麻烦，因而提出这样的问题也是很正常的。问题的答案是，特定的字体特性可以使网站更有用、更易读、更优美：

* **连字**（比如“ﬀ”或“ﬁ”）可以使字母间距更均匀，阅读更流畅。
* **分数形式**，可以让家居装修、食谱网站变得更易阅读和理解。
* 文本段落中的“老式”**数字风格**和小写字母搭配更合适；“表格数字”在表格里的费用清单里排列得更整齐；而“齐行”数字单独使用或与大写单词搭配使用显得更为统一。

虽说一个网站即使不用上述任何一个特性，也不会变得没用，但这里的每一种特性都可以令网站更便于使用，并因其对细节的关注而令人印象深刻。

>
> OpenType 特性就像字体中的密室。打开它们，你将发现，你可以让字体或微妙或显著地展现出它的另一面。并非所有 OpenType 特性都可以不分场合地使用，但有些特性对于优秀的字体排印是至关重要的。*——Tim Brown（Adobe 字体排印负责人）*
>
>
>

### 有时它是实质，而不仅是样式

在有些情况下（比如 `font-variant-east-asian` (en-US)），OpenType 特性直接关系到特定字符的不同形式，涉及意义和易读性的差别。此时，字体特性不再只是为了美观，而成为内容本身不可或缺的一部分。

字体特性
----

开发者需要考虑许多不同的字体特性。在这里，我们根据 W3C 规范的主要属性和选项将它们分门别类加以介绍。

**备注：** 下列示例将展示各个属性及其组合，以及与之等价的底层语法。由于浏览器实现的差异，等价语法的效果可能不完全一致；但大多数情况下，两种示例是一模一样的。展示所用的字体有 Playfair Display，Source Serif Pro，IBM Plex Serif，Dancing Script，以及 Kokoro。以上字体均可获取并自由使用（大多可以从 Google Fonts 或其他字体服务中获取）。

### 字偶距（`font-kerning`）

字偶距（kerning）指的是特定字偶（字符组合）内部的间距。字偶距调整特性是默认打开的（OpenType 规范推荐）。应当注意的是，如果对文本同时设置了字偶距和词距（`letter-spacing`），词距调整会在字偶距调整之后进行。

### Alternates (`font-variant-alternates`)

Fonts can supply a number of different alternatives for various glyphs, such as different styles of lower case 'a' or more or less elaborate swashes in a script typeface. This property can activate an entire set of alternates or just a specific one, depending on the values supplied.The example below is showing several different aspects of working with alternate characters. Fonts with alternate glyphs can make them available across the board or individually in separate stylistic sets, or even individual characters. In this example you can see two different typefaces, and the introduction of the `@font-feature-values` at-rule. This is used to define shortcuts or named options that can be defined per font family. This way you can create a named option that applies to only a single font, or one that is shared and can be applied more generally

In this case, `@stylistic(alternates)` will show all the alternate characters for either font). Applying this to just the word 'My' alters the way the 'M' renders, and applying `@styleset(alt-a)` only changes the lower case 'a'.

Try changing the line

```css
font-variant-alternates: styleset(alt-a);
```

to

```css
font-variant-alternates: styleset(alt-g);
```

and notice that the lower case 'a' reverts to its regular form and the lower case 'g' changes instead.

#### More about alternates

* https://www.w3.org/TR/css-fonts-4/#propdef-font-variant-alternates
* https://developer.mozilla.org/zh-CN/docs/Web/CSS/font-variant-alternates
### 连字（`font-variant-ligatures`）

为了让两个或以上的字符（在间距、审美方面）显得更匀称，可以把它们替换成另一种字形，即连字（ligature）。最常见的连字包括“ﬁ，ﬂ，ﬄ”之类的字母连字；此外，也有许多其他类型的连字。有些连字经常使用，称为常用连字（common ligatures）；也有一些连字更为特殊，比如“任意连字（discretionary ligatures）”、“历史连字（historical ligatures）”和“上下文连字（contextual alternates）”。尽管后几种在技术上不算是连字，但在“将特定字母组合一起出现时替换成另一种字形”这一点上，它们和连字是基本一致的。

尽管连字在文字中更为常用，以下示例也展示了如何用连字功能生成箭头：

### 位置（`font-variant-position`）

位置变体用于调用排版中的上标和下标字形。设计这些上标、下标字形，是为了在不改变基线和行距的条件下，配合前后的文本使用。这是“位置”字体特性相比 `<sub>` 或 `<sup>` 元素的优势之一。

### 大写字母（`font-variant-caps`）

OpenType 特性最常用的情形之一，就是用来正确地呈现小型大写字母（small caps）。小型大写字母，是指尺寸经过调整，可以和小写字母更好搭配的大写字母，一般用于缩写词。

### 数字（`font-variant-numeric`）

字体中通常包含几种不同风格的数字：

* “齐行（lining）”数字的高度一致，都排在相同的基线上。
* “老式（oldstyle）”数字高度各异，像小写字母一样，在字形设计上有升部（ascender）和降部（descender）。设计老式数字是为了用在行内文本中，目的在于使数字在视觉上与前后的字形融为一体（作用类似于小型大写字母）。

数字风格也和字距有关。比例（proportional）字距是一般设定；而表格（tabular）字距可以让数字对齐排列，不受字宽差异的影响，用在需要对齐数字的财务表格中尤为合适。

本属性支持两种分数形式：

* 单层分数（以斜杠作为分数线）；
* 双层分数（分子、分母分别在分数线上下）。

本属性也支持序数（比如“1st”“3rd”）特性；如果字体中有带斜杠的零的字形，本属性也可以调用。

#### 齐行数字和老式数字

#### 分数、序数和带斜杠的零

### 东亚文字（`font-variant-east-asian` (en-US)）

本属性可以调用字体中的各种异体字形。下列示例展示了仅启用 OpenType“jis78”字符集的字符串。取消勾选，你会看到更多汉字显示了出来。

**备注：** 这些字是从字体样品中复制出来的，并无含义。

### 字体变体简写（`font-variant`）

本属性定义了以上所有属性的简写语法。设定 `normal` 值可以将所有属性重置为初始值。设定 `none` 值会把 `font-variant-ligatures` 设定为 `none` ，并重置其他属性为初始值。（这里的意思是说，如果字偶距特性是默认打开的，即使 `font-variant` 设置为 `none`，字偶距特性依然是打开的。）

Font feature settings
---------------------

`font-feature-settings` is the 'low level syntax' that allows explicit access to every named available OpenType feature. This gives a lot of control, but has some disadvantages in how it impacts inheritance and — as mentioned above — if you wish to change one setting, you have to redeclare the entire string (unless you're using CSS custom properties to set the values). Because of this, it's best to use the standard properties shown above wherever possible.

There a huge number of possible features. You can see examples of a number of them above, and there are several resources available for finding more of them.

The general syntax looks like this:

```css
.small-caps {
  font-feature-settings: "smcp", "c2sc";
}
```

According to the specification you can either supply just the 4-character feature code or supply a 1 following the code (for enabling that feature) or a 0 (zero) to disable it. This is helpful if you have a feature like ligatures enabled by default but you would like to turn them off, like so:

```css
.no-ligatures {
  font-feature-settings:
    "liga" 0,
    "dlig" 0;
}
```

#### More on font-feature-settings codes

* 'The Complete CSS Demo for OpenType Features' (can't vouch for the truth of the name, but it's pretty big)
* A list of OpenType features on Wikipedia
Using CSS feature detection for implementation
----------------------------------------------

Since not all properties are evenly implemented, it's good practice to set up your CSS using feature detection to utilize the correct properties, with `font-feature-settings` as the fallback.

For example, small caps can be set several ways, but if you want to ensure that no matter what the underlying capitalization is that you end up with everything in small caps, it requires 2 settings with `font-feature-settings` versus a single property value using `font-variant-caps`.

```css
.small-caps {
  font-feature-settings: "smcp", "c2sc";
}

@supports (font-variant-caps: all-small-caps) {
  .small-caps {
    font-feature-settings: normal;
    font-variant-caps: all-small-caps;
  }
}
```

相关链接
----

### CSS OpenType 特性演示

* The Complete CSS Demo for OpenType Features
### Web 字体分析工具

* Wakamai Fondue
* Axis Praxis
### W3C 规范

* Font Feature Properties in CSS Fonts Module Level 3
* font-variant-alternatives in CSS Fonts Module Level 4
### 其他资源

* Using OpenType features by Tim Brown, Head of Typography, Adobe
* Adobe's Syntax for OpenType features in CSS


Variable fonts guide - CSS：层叠样式表

Variable fonts guide
====================

\*\*可变字体（Variable fonts）\*\*是 OpenType 字体规范上的演进，它允许将同一字体的多个变体统合进单独的字体文件中。从而无需再将不同字宽、字重或不同样式的字体分割成不同的字体文件。你只需通过 CSS 与一行`@font-face`引用，即可获取包含在这个单一文件中的各种字体变体。本文将介绍如何在 Web 中使用可变字体。

**警告：** 为了能够在你的操作系统上正确地使用可变字体，请确定你的操作系统已经升级到最新版本。例如各 Linux 发行版，应将 Freetype 升级到最新版本。10.13 版本之前的 macOS 不支持可变字体。如果你的操作系统没有升级到最新版，你将无法在网页和 Firefox Developer Tools 中使用可变字体。

可变字体：何谓与何异
----------

为了更好的理解可变字体有什么不同，我们有必要回顾一下什么是非可变字体，并对二者进行一番比较。

### 标准（静态）字体

过去，一个字体家族往往由大量独立字体文件组成，每个字体文件都代表某一特定的宽度/字重/样式的组合。因此你会看到有单独的字体文件叫做“Roboto Regular”、“Roboto Bold”，或是“Roboto Bold Italic”——这意味着你可能需要 20 或 30 个不同的字体文件才能算是有了一整个字体家族（对于有着不同宽度的大型字体来说，这个数量还要翻上几倍）。

在这样的情景下，为了在一个单纯显示进行正文展示的页面中使用一个字体，你至少需要四个字体文件：常规、斜体、加粗、斜体加粗。如果你想添加更多的字重，比如让题注更轻或让额外强调的地方更重，意味着你需要更多文件。这就导致了更多大量 HTTP 请求的产生，同时也需要下载更多的数据（通常每个文件至少有 20k 或更多）。

### 可变字体

通过使用可变字体，所有这些情况的排列组合都可以被装进一个文件中。这个文件可能比常规的单个字体文件大一些，但通常情况下，都不会大于，并且常常是小于你因为要展示正文所需要下载的四个文件的尺寸总和。使用可变字体的优势是你可以直接使用所有可用的字重、宽度和样式的字体，而不必像过去一样仅仅受限于使用其中单独的某一种。

这允许使用常见的排版技术，例如在不同的字重中设置不同大小的标题，以便在每种大小下都具有更好的可读性，或者在数据密集展示时使用稍窄一点的字体宽度。相比之下，在杂志的印刷系统中，在整个出版物中使用 10-15 种或更多不同的字重和宽度组合是很典型的——这比目前在 web 上的典型样式提供了更广泛的样式范围 (或者仅从性能方面考虑确实很实用)。

#### 关于字体系列，字重和变体的说明

你可能注意到，我们一直在讨论为每种权重和样式 (即粗体，斜体以及斜体加粗) 创建特定的字体文件，而不是依赖于浏览器来合成它们。这样做的原因，是大多数字体对于粗体和斜体都有非常特殊的设计，它们通常包含完全不同的字符 (例如，小写字母的“a”和“g”在斜体中常常是完全不同的)。在使用非可变字体时，为了最准确地反映字体设计，避免浏览器之间的差异以及它们如何合成或不合成不同的样式，在需要的地方加载特定的字体文件会更为准确。

你可能还会发现一些可变字体分为两个文件：一个用于正体及其所有变体，另一个包含斜体变体。有时这样做是为了在不需要或不使用斜体的情况下减小整体文件大小。在所有情况下，仍然可以通过通用的 `font-family` 名称链接它们，以便你可以使用相同的 font-family 和相应的 `font-style` 来调用它们。

介绍“可变轴” (variation axis)
------------------------

可变字体新格式的核心是**可变轴**的概念，其描述了字体设计中某一特性的允许变化范围。例如‘字重轴’描述了字体的粗细；“宽度轴”描述了字体的宽窄；“斜体轴”描述是否使用斜体字形并且可相应地开关；等。请注意，轴既可以是范围选择又可以是开关选择。字重可能在 1-999 之间，而斜体可能只是简单的 0 或 1（关闭或打开）。

如规范中所定义，存在两种变形轴，**注册轴**和**自定义轴**：

* 注册轴最为常见，常见到制定规范的作者认为有必要进行标准化。目前注册的五个轴是字重，宽度，倾斜度，斜体和光学尺寸。W3C 已经将它们映射到现有的 CSS 属性，并在一个案例中引入了一个新的属性，你将在下面看到。
* 自定义轴实际上是无限的：字体设计师可以定义和界定他们喜欢的任何轴，并且只需要给它一个四个字母的标签以在字体文件格式本身中识别它。你可以在 CSS 中使用这些四个字母的标签来指定沿该变化轴的点，你也将在下面的代码示例中看到。
### 注册轴和现有的 CSS 属性

在本节中，我们将通过示例和相应的 CSS 来演示已定义的五个注册轴。在可能的情况下，包括标准语法和低级语法。较低级语法 (`font-variation-settings`) 是为了测试对可变字体支持的早期实现而实现的第一个机制，并且需要使用五个注册轴之外的新轴或自定义轴。但是，W3C 的意图是在其他属性可用时不使用此语法。因此，应尽可能使用相应的属性，`font-variation-settings`的低级语法仅用于设置值不可用的值或轴。

#### 注意

1. 当使用 `font-variation-settings` 时，请务必注意轴名称区分大小写。注册轴名称必须为小写，自定义轴必须为大写。例如：

```css
font-variation-settings:
  "wght" 375,
  "GRAD" 88;
```

`wght` (weight) 是一个注册轴， `GRAD` (grade) 是一个自定义轴。
2. 如果你使用 `font-variation-settings` 设置了值并想要更改其中一个值，则必须重新声明所有值。你可以通过对各个值使用CSS 自定义属性（CSS 变量）来解决此限制，并只需修改单个自定义属性的值。该指南末尾有示例代码。
### 字重

字重（由 `wght` 标签表示）是定义了字形的笔画粗细范围（在印刷术语中称为轻重）的设计轴。很长一段时间，CSS 都能够通过 `font-weight`) 这个采用 100 到 900 之间的以 100 为增量的数字值以及类似于 `normal` 或 `bold` 等这样有相应数字值的别名（在这种情况下为 400 和 700）的关键字的属性来实现。在处理非可变或可变字体时仍然会用到这些数值或关键字，但对于可变字体，1 到 1000 之间的任何数字都是有效的。

应该注意的是，此时 `@font-face` 声明中没有办法将变量字体变形轴上的特定点“映射”到关键字 `bold` （或任何其他关键字）。这通常可以很容易地解决，但在编写 CSS 时需要额外的步骤：

```css
font-weight: 375;

font-variation-settings: "wght" 375;
```

可以通过编辑下面实例的 CSS 来使用字重值。

### 字宽

字宽（由 `wdth` 标签表示）定义字形可以是多窄或多宽（印刷术语中称为压缩或扩展）的设计轴。这通常在 CSS 中通过使用 `font-stretch` 属性设置，该属性值表示为高于或低于“正常”的百分比（100％），任何大于 0 的数字在技术上都是有效的 - 尽管它的范围更有可能是接近 100％的，例如 75％-125％。如果提供的数字值超出了字体编码的范围，浏览器应该以允许的最接近值渲染字体。

**备注：** 在使用 `font-variation-settings` 时不需要使用%。

```css
font-stretch: 115%;

font-variation-settings: "wdth" 115;
```

可以通过编辑下面实例的 CSS 来使用字宽值。

### 斜体

Italic（`ital`）轴的工作方式不同，因为它仅可以打开或关闭; 而没有中间值。斜体设计通常包括与其正体截然不同的字形，因此在从正体到斜体的过渡中，通常会发生许多字形（或字符）替换。Italic 和 oblique 通常可以互换使用，但事实上实际上是完全不同的。在这种情况下，Oblique 定义为术语 `slant` （参见下面的部分），并且字体通常具有一个或另一个斜体，但不是两者都有。

在 CSS 中，使用 `font-style` 属性对文本应用 italic 和 oblique。

```css
font-style: italic;

font-variation-settings: "ital" 1;
```

可以通过编辑下面实例的 CSS 来使用斜体值。

### 倾斜

Slant（由 `slnt` 标签表示），或者它经常被称为“oblique” - 与真正的斜体不同之处在于它改变了字体的角度但不执行任何类型的字符替换。它也是可变的，因为它表示为数值范围。这允许字体沿该轴的任何位置变化。允许的范围通常为 0（直立）到 20 度 — 可以使用该范围内的任何数值，因此字体可以倾斜一点点。但是，-90-90 度的任何值都是有效的。

**备注：** 在使用 `font-variation-settings` 时不需要使用 `deg` 这个关键字。

```css
font-style: oblique 14deg;

font-variation-settings: "slnt" 14;
```

可以通过编辑下面实例的 CSS 来使用 slant/oblique 值。

### 视觉尺寸（Optical sizes）

这是数字字体和 CSS 的新功能，但其实对应于设计加工金属活字中的一项古老技艺。视觉尺寸是指基于物理尺寸改变字形的整体笔画厚度的做法。如果尺寸非常小（例如等于 10 或 12px），则字符将具有整体较粗的笔画，可能还会进行其他小的修改，以确保以较小的物理尺寸复制和可读性。相反，当使用更大尺寸（如 48 或 60px）时，笔画的粗细重量可能会有更大的变化，外观会更接近原始设计意图。

虽然这样做最初是为了在油墨和纸张印刷过程中提供补偿（小尺寸铅字上非常细的线会很难印上，导致字形外观残损），但现在它很好地转化为在数字显示中对屏幕质量和物理尺寸渲染的补偿。

光学尺寸值通常旨在根据 `font-size`自动应用，但也可以使用较低级别的 `font-variation-settings` 语法进行操作。

创建了一个在 CSS 中中支持可变字体的新属性 `font-optical-sizing` (en-US) 。使用 `font-optical-sizing` 时，唯一允许的值是 `auto` 或 `none` - 因此该属性仅允许打开或关闭光学尺寸。但是，当使用 `font-variation-settings: 'opsz' <num>`时，你可以使用数值。在大多数情况下，你可能希望将 `font-size`（正在渲染的类型的物理大小）与 `opsz` 值（使用 `auto`时应用光学尺寸的方式）进行匹配。提供了特定值，以便在必要时（为了易认性，美观或其他原因）可以应用特定值来覆盖默认值。

```css
font-optical-sizing: auto;

font-variation-settings: "opsz" 36;
```

可以通过编辑下面实例的 CSS 来使用视觉尺寸值。

### 自定义轴

自定义轴可以是字体设计师想象的任何设计变化轴。可能有一些会变得相当普遍，甚至演变成注册轴。

### Grade

由于在字体设计方面有着众所周知的历史，等级可能会成为更常见的自定义轴之一。设计不同等级的字体通常是根据预期的用途和印刷技术来进行的。 “等级”一词指的是字体设计的相对重量或密度，但与传统的“重量”不同之处在于文本占据的物理空间不会改变，因此改变文本等级并不会改变文本或其周围元素的整体布局。这使得等级成为有用的变化轴，因为它可以变化或动画而不会引起文本本身的回流。

```css
font-variation-settings: "GRAD" 88;
```

可以通过编辑下面实例的 CSS 来使用字体等级值。

### 使用可变字体：改变 @font-face

加载可变字体的语法与其他 web 字体非常相似，但有一些显著的差异，这些差异是通过对现代浏览器中可用的传统`@font-face`语法的升级提供的。

基本语法是相同的，但是字体技术是不一样的，并且可变字体可以提供像对 `font-weight` 和 `font-stretch` 等描述符的允许范围，而不是根据加载的字体文件来命名。

```css
@font-face {
  font-family: "MyVariableFontName";
  src: "path/to/font/file/myvariablefont.woff2" format("woff2-variations");
  font-weight: 125 950;
  font-stretch: 75% 125%;
}
```

**备注：** 并非所有浏览器都实现了字体格式的完整语法，因此请仔细测试。如果你将字体格式设置为仅文件格式，而不是格式变体（即 `woff2` 而不是 `woff2-variations`），那么支持可变字体的所有浏览器仍将渲染它们，但如果可能，最好使用正确的语法。

**备注：** 如果使用适当的属性（即 `font-weight`或 `font-stretch`），提供 `font-weight`， `font-stretch`和 `font-style`的值范围将使浏览器不会尝试渲染超出该范围的轴，但不会阻止你通过 `font-variation-settings` 使用无效值，因此请小心使用。

使用旧版本浏览器
--------

可以使用 CSS 特性查询检查是否支持可变字体（请参阅 `@supports`），因此在生产中，可以在特性查询块内使用可变字体。

```css
h1 {
  font-family: some-non-variable-font-family;
}

@supports (font-variation-settings: "wdth" 115) {
  h1 {
    font-family: some-variable-font-family;
  }
}
```

示例页面
----

以下示例页面展示了构造 CSS 的两种不同方法。第一种方法尽可能使用标准属性。第二个示例使用 CSS 自定义属性设置 `font-variation-settings` 字符串的值，并展示如何通过覆盖单个变量而不是重写整个字符串来更轻松地更新单个变量值。请注意 `h2`上的悬停效果，它只会改变等级轴自定义属性值。

资源
--

* W3C CSS Fonts Module 4 Specification (editor’s draft)
* W3C Github issue queue
* Microsoft Open Type Variations introduction
* Microsoft OpenType Design-Variation Axis Tag Registry
* Wakamai Fondue （通过简单的拖拽告诉你字体可以做什么的网站）
* Axis Praxis （独创的可变字体排版试验网站）
* V-Fonts.com （可变字体目录网站）
* Font Playground （另一个拥有独特用户界面的可变字体排版试验网站）


网格模板区域 - CSS：层叠样式表

网格模板区域
======

在上一篇指南中我们着眼于网格线以及如何依赖网格线定位项目。在使用 CSS 网格布局时，因为离不开网格线，所以最直接的方式就是使用网格线来定位项目。不过，还有另一种替代方法用于定位项目，你可以独立使用它，也可把它和基于网格线的定位结合起来。这个方法采用对模板区域命名的方式来定位项目，接下来我们就来弄清如何使用它。很快你就会知道为什么我们有时把这种方法称为网格布局的 ASCII 艺术方法！

命名网格区域
------

我们已经接触过 `grid-area` 属性了，它把网格线的 4 个属性值合为 1 个值，用于定位一个网格区域。

```css
.box1 {
  grid-area: 1 / 1 / 4 / 2;
}
```

在用网格线定义网格区域时，我们是通过指定围绕网格区域的四条线来定义的。

![The Grid Area defined by lines](/zh-CN/docs/Web/CSS/CSS_grid_layout/Grid_template_areas/4_area.png)

我们也可以先给一个区域命名，然后在 `grid-template-areas` 属性值中指定这个区域的位置。你可以随意为区域命名，比如，如果我要创建下面的布局，我可以先划分出 4 个主要的区域：

* 头部（header）
* 尾部（footer）
* 侧边栏（sidebar)
* 主要内容（content）

![An image showing a simple two column layout with header and footer](/zh-CN/docs/Web/CSS/CSS_grid_layout/Grid_template_areas/4_layout.png)

通过 `grid-area` 属性为这些区域各分配一个名字，这不会影响布局。我们现在已经有了用于布局的命名过的区域了。

```css
.header {
  grid-area: hd;
}
.footer {
  grid-area: ft;
}
.content {
  grid-area: main;
}
.sidebar {
  grid-area: sd;
}
```

有了这些名字，接下来就可以创建布局了。此前我们是通过在项目自身上指定线序号来定位项目，而现在，则要把完整的布局都写在网格容器中。

```css
.wrapper {
  display: grid;
  grid-template-columns: repeat(9, 1fr);
  grid-auto-rows: minmax(100px, auto);
  grid-template-areas:
    "hd hd hd hd hd hd hd hd hd"
    "sd sd sd main main main main main main"
    "ft ft ft ft ft ft ft ft ft";
}
```

```
\* {
  box-sizing: border-box;
}

.wrapper {
  border: 2px solid #f76707;
  border-radius: 5px;
  background-color: #fff4e6;
  max-width: 940px;
  margin: 0 auto;
}

.wrapper > div {
  border: 2px solid #ffa94d;
  border-radius: 5px;
  background-color: #ffd8a8;
  padding: 1em;
  color: #d9480f;
}
```

```html
<div class="wrapper">
  <div class="header">Header</div>
  <div class="sidebar">Sidebar</div>
  <div class="content">Content</div>
  <div class="footer">Footer</div>
</div>
```

用这种方法，我们不需要为任何网格项目单独指定属性，所有的定义都在网格容器中。请仔细观察在 `grid-template-areas` 属性中是怎样描述布局的。

留出空白的网格单元
---------

在上面的例子中，已经实现了用区域填充网格，不留空余空间，不过你也可以用这种布局方法留出空的网格单元。留出空单元的方法是使用句点符，“`.`”。假如想把尾部区域仅显示在主要内容的下方，就应该让侧边栏下面的三个单元格为空。

```css
.header {
  grid-area: hd;
}
.footer {
  grid-area: ft;
}
.content {
  grid-area: main;
}
.sidebar {
  grid-area: sd;
}
```

```
\* {
  box-sizing: border-box;
}

.wrapper {
  border: 2px solid #f76707;
  border-radius: 5px;
  background-color: #fff4e6;
  max-width: 940px;
  margin: 0 auto;
}

.wrapper > div {
  border: 2px solid #ffa94d;
  border-radius: 5px;
  background-color: #ffd8a8;
  padding: 1em;
  color: #d9480f;
}
```

```css
.wrapper {
  display: grid;
  grid-template-columns: repeat(9, 1fr);
  grid-auto-rows: minmax(100px, auto);
  grid-template-areas:
    "hd hd hd hd hd hd hd hd hd"
    "sd sd sd main main main main main main"
    ". . . ft ft ft ft ft ft";
}
```

```html
<div class="wrapper">
  <div class="header">Header</div>
  <div class="sidebar">Sidebar</div>
  <div class="content">Content</div>
  <div class="footer">Footer</div>
</div>
```

为了让布局更整齐，可以使用多个“`.`”符号，如果在多个句点符号之间没有空格，那它们就会被计为一个单元格。用多个句点表示一个单元格的好处是对于复杂的布局来说很容易让行列对齐，这意味着你在 CSS 中看到的，就像是实际布局看起来那样。

跨越多个网格单元
--------

在上面的例子中，每个区域都跨越了多个网格单元，为了实现这个效果，要把区域名字在它的区域内重复写多次，中间用空格分隔。你也可以在 `grid-template-areas` 中添加额外的空格以便让列对齐。你可以看到我把 `hd` 和 `ft` 都跟 `main` 对齐了。

用区域名连接起来的区域必须是矩形的，目前还不能创建 L 形的区域，尽管规范中指出未来的版本可能会提供这项功能。你可以像跨列那样实现跨行，举个例子，要让侧边栏向下跨到底部，只需要用 sd 标识替换掉 '.' 符号就可以了。

```css
.header {
  grid-area: hd;
}
.footer {
  grid-area: ft;
}
.content {
  grid-area: main;
}
.sidebar {
  grid-area: sd;
}
```

```
\* {
  box-sizing: border-box;
}

.wrapper {
  border: 2px solid #f76707;
  border-radius: 5px;
  background-color: #fff4e6;
  max-width: 940px;
  margin: 0 auto;
}

.wrapper > div {
  border: 2px solid #ffa94d;
  border-radius: 5px;
  background-color: #ffd8a8;
  padding: 1em;
  color: #d9480f;
}
```

```css
.wrapper {
  display: grid;
  grid-template-columns: repeat(9, 1fr);
  grid-auto-rows: minmax(100px, auto);
  grid-template-areas:
    "hd hd hd hd hd hd hd hd hd"
    "sd sd sd main main main main main main"
    "sd sd sd ft ft ft ft ft ft";
}
```

```
<div class="wrapper">
  <div class="header">Header</div>
  <div class="sidebar">Sidebar</div>
  <div class="content">Content</div>
  <div class="footer">Footer</div>
</div>
```

`grid-template-areas` 的值必须是一个完整的网格，否则无效（即这个属性会被忽略掉），这意味着你应该让每一行都有相同数量的单元格，如果出现句点符就表示这个单元格将被留空。如果创建的区域不是矩形，也是无效的网格。

用媒体查询重新定义网格
-----------

现在我们的布局已经成为了 CSS 的一部分，（通过媒体查询）在 CSS 的多个不同地方修改它也非常容易。你可以重新定义网格、重新定位网格中的项目、甚至完全改变它。

若要（通过媒体查询）重新定义网格，应该把区域名称定义在媒体查询之外，在这种情况下，主要内容区域就总是会被称为 main，不管它被（媒体查询语句）定位在网格中的什么位置。

对于上面的例子，我们可能希望在较窄的宽度下使用非常简单的布局，网格只定义一个列，所有的项目从上到下排列。
```

\* {
  box-sizing: border-box;
}

.wrapper {
  border: 2px solid #f76707;
  border-radius: 5px;
  background-color: #fff4e6;
  max-width: 940px;
  margin: 0 auto;
}

.wrapper > div {
  border: 2px solid #ffa94d;
  border-radius: 5px;
  background-color: #ffd8a8;
  padding: 1em;
  color: #d9480f;
}
```

```css
.header {
  grid-area: hd;
}
.footer {
  grid-area: ft;
}
.content {
  grid-area: main;
}
.sidebar {
  grid-area: sd;
}

.wrapper {
  display: grid;
  grid-auto-rows: minmax(100px, auto);
  grid-template-columns: 1fr;
  grid-template-areas:
    "hd"
    "main"
    "sd"
    "ft";
}
```

把目前的布局放到媒体查询里，并且调整为当空间变得足够宽时，把目前两列的布局改为三列的布局。注意对于宽布局仍保留 9 列轨道，而只是在 `grid-template-areas` 里重新定义了项目的位置。

```css
@media (min-width: 500px) {
  .wrapper {
    grid-template-columns: repeat(9, 1fr);
    grid-template-areas:
      "hd hd hd hd hd hd hd hd hd"
      "sd sd sd main main main main main main"
      "sd sd sd ft ft ft ft ft ft";
  }
}
@media (min-width: 700px) {
  .wrapper {
    grid-template-areas:
      "hd hd hd hd hd hd hd hd hd"
      "sd sd main main main main main ft ft";
  }
}
```

```
<div class="wrapper">
  <div class="header">Header</div>
  <div class="sidebar">Sidebar</div>
  <div class="content">Content</div>
  <div class="footer">Footer</div>
</div>
```

在 UI 元素上使用 `grid-template-areas`
--------------------------------

许多网上流传的网格例子都假定使用网格来做页面的整体布局，实际上网格对于小元素一样有用。使用 `grid-template-areas` 能令人特别愉快，因为你在代码里就能直观地看到的这些元素的布局效果。

### 媒体对象示例

下面我们举一个非常简单的例子，来创建一个“媒体对象”。这个组件由一侧的图片或其他媒体以及另一侧的内容组成，图片将显示在盒子的右边或左边。

![Images showing an example media object design](/zh-CN/docs/Web/CSS/CSS_grid_layout/Grid_template_areas/4_media_objects.png)

定义一个两个列轨道的网格，图片列的尺寸是 `1fr`，文本列的尺寸是 `3fr`。如果你想让图片区域占据固定的宽度，就可以把图片列的尺寸设定一个像素值，把文本区域的尺寸设定为 `1fr`。只有一个 `1fr` 的列轨道的意思是让它占据剩余的空间。

把图片区域命名为 `img`，把文本区域命名为 `content`，然后把它们摆放在 `grid-template-areas` 属性中。

```css
\* {
  box-sizing: border-box;
}

.media {
  border: 2px solid #f76707;
  border-radius: 5px;
  background-color: #fff4e6;
  max-width: 400px;
}
.media {
  display: grid;
  grid-template-columns: 1fr 3fr;
  grid-template-areas: "img content";
  margin-bottom: 1em;
}

.media .image {
  grid-area: img;
  background-color: #ffd8a8;
}

.media .text {
  grid-area: content;
  padding: 10px;
}
```

```html
<div class="media">
  <div class="image"></div>
  <div class="text">
    This is a media object example. We can use grid-template-areas to switch
    around the image and text part of the media object.
  </div>
</div>
```

### 把图片显示在盒子的另一侧

你也许习惯于把图片显示在盒子的另一侧，为了实现这个效果，只需要把网格的 `1fr` 轨道放到后边，把 `grid-template-areas` 里的值简单地调换个位置即可。

```css
\* {
  box-sizing: border-box;
}

.media {
  border: 2px solid #f76707;
  border-radius: 5px;
  background-color: #fff4e6;
  max-width: 400px;
}
.media {
  display: grid;
  grid-template-columns: 1fr 3fr;
  grid-template-areas: "img content";
  margin-bottom: 1em;
}

.media.flipped {
  grid-template-columns: 3fr 1fr;
  grid-template-areas: "content img";
}

.media .image {
  grid-area: img;
  background-color: #ffd8a8;
}

.media .text {
  grid-area: content;
  padding: 10px;
}
```

```html
<div class="media flipped">
  <div class="image"></div>
  <div class="text">
    This is a media object example. We can use grid-template-areas to switch
    around the image and text part of the media object.
  </div>
</div>
```

网格定义的简写规则
---------

至此我们已经演示了多种定位网格中项目的方法，而且有多个属性用于定义网格，现在我们来学习两个简写方式，它们可以把定义网格及与网格有关的很多内容写在一行 CSS 语句里，非常强大。

这两个简写方式会让别的开发者甚至未来的你自己在阅读你的代码时的感到困难。因为这是规范的一部分，所以你在看示例或者读别人写的代码时偶然会遇到它们，即使你自己选择不使用它们。

在使用难以记忆的简写方式之前，你要知道，简写方式不仅能够一口气把多个属性缩写成一行，它们还会把一些你没有设置过的值、或不能在简写中设置的值**重置成初始值**。所以如果要用简写方式，一定要意识到它可能会把你在别处已经设置过的值给重置了。

这两个用于网格容器的简写方式，分别是显式网格简写 `grid-template`，和网格定义简写 `grid`。

### `grid-template`

`grid-template` 属性可同时设置以下属性：

* `grid-template-rows`
* `grid-template-columns`
* `grid-template-areas`

这个属性之所以被称为显式网格简写，是因为它设置的都是在定义显式网格时要用到的属性，而不是那些与创建隐式的行或列轨道相关的属性。

下面的代码使用 `grid-template-areas` 创建了一个布局，效果与本文前面创建的布局是一样的。

```css
.wrapper {
  display: grid;
  grid-template:
    "hd hd hd hd hd hd hd hd hd" minmax(100px, auto)
    "sd sd sd main main main main main main" minmax(100px, auto)
    "ft ft ft ft ft ft ft ft ft" minmax(100px, auto)
    / 1fr 1fr 1fr 1fr 1fr 1fr 1fr 1fr 1fr;
}
```

第一个值是 `grid-template-areas` 的值，并且在每一行的末尾声明了行的大小，也就是 `minmax(100px, auto)` 的作用。

在 `grid-template-areas` 之后用一个左斜杠分隔，再之后是一个详细的列轨道清单。

### `grid`

`grid` 简写方式更进一步，它包含了与隐式网格相关的属性，所以通过它可以同时设置以下属性：

* `grid-template-rows`
* `grid-template-columns`
* `grid-template-areas`
* `grid-auto-rows`
* `grid-auto-columns`
* `grid-auto-flow`

这个属性会把 `grid-gap` (en-US) 属性的值重置为 `0`，而且你还不能在简写中设置间距值。

你可以像使用 `grid-template` 一样使用这个语法，不过要注意的是当它执行时，它会重置一些其他值。

```css
.wrapper {
  display: grid;
  grid:
    "hd hd hd hd hd hd hd hd hd" minmax(100px, auto)
    "sd sd sd main main main main main main" minmax(100px, auto)
    "ft ft ft ft ft ft ft ft ft" minmax(100px, auto)
    / 1fr 1fr 1fr 1fr 1fr 1fr 1fr 1fr 1fr;
}
```

在读过本指南后面的自动定位和 grid-auto-flow 属性之后，我们会回过头来再看看这个属性提供的其他功能。

如果你通过阅读本指南前面的几篇文章已经开始上手了，那么你应该是用基于线的定位方式或用命名区域的方式来创建网格布局的。花费一些时间用网格去创建常见的布局模式，虽然还有很多的术语要学习，不过语法是非常一目了然的。在你练习开发的过程中可能会遭遇到一些问题，并且用我们没有讲过的方法去解决它们。在本指南后面的文章中，我们将着眼于更多规范中的细节——目标是让你能用它创建出更加复杂的布局。


网格布局和其他布局方法的联系 - CSS：层叠样式表

网格布局和其他布局方法的联系
==============

CSS 网格布局作为实现布局的一个完整系统，其设计使之和 CSS 其他部分能协同合作。在这个指南中，我会向你解释网格布局是如何与你正在使用的其他技巧协同合作的。

网格和弹性盒
------

CSS **网格布局**和**弹性盒布局**的主要区别在于 CSS 弹性盒布局是为一维布局服务的（沿横向或纵向的），而网格布局是为二维布局服务的（同时沿着横向和纵向）。这两个规格有一些相同的特性。如果你已经掌握如何使用弹性盒布局的话，你可能会想知道这些相似之处怎样在能帮助你掌握网格布局。

### 一维布局 vs. 二维布局

一个简单的示例可以说明一维和二维布局的区别。

这个示例中我用弹性盒布置了一些盒子。容器中有 5 个元素，它们被设置了伸缩属性，在 150px 基准上伸缩。

我还设置了 `flex-wrap` 属性为 `wrap`，从而当容器变得太窄时，元素会换到新的一行。
```

\* {
  box-sizing: border-box;
}

.wrapper {
  border: 2px solid #f76707;
  border-radius: 5px;
  background-color: #fff4e6;
}

.wrapper > div {
  border: 2px solid #ffa94d;
  border-radius: 5px;
  background-color: #ffd8a8;
  padding: 1em;
  color: #d9480f;
}
```

```html
<div class="wrapper">
  <div>One</div>
  <div>Two</div>
  <div>Three</div>
  <div>Four</div>
  <div>Five</div>
</div>
```

```css
.wrapper {
  width: 500px;
  display: flex;
  flex-wrap: wrap;
}
.wrapper > div {
  flex: 1 1 150px;
}
```

你可以看到有两个元素被换到了新行。这两个元素共享了这行的可用空间，并没有与上一行的元素对齐。这是因为当你允许弹性元素换行时，每个新行都变成了一个新的弹性容器。空间分布只在行内进行。

从而产生了一个常见问题：如何能让这些元素对齐？这时你需要一种二维布局的方法，你希望通过行和列来控制对齐，是时候该网格登场了。

### 用 CSS 网格达成同样布局

下例中我用网格创建同样的布局。这次我们有 3 个 `1fr` 的列轨道。我们并不需要给这些子元素设置任何属性，它们会自动按顺序填充到网格的单元格中。你可以看到它们按网格规整的排列，行与行、列与列对齐。当有 5 个子元素时，第二行的尾部会留出一个空隙。
```

\* {
  box-sizing: border-box;
}

.wrapper {
  border: 2px solid #f76707;
  border-radius: 5px;
  background-color: #fff4e6;
}

.wrapper > div {
  border: 2px solid #ffa94d;
  border-radius: 5px;
  background-color: #ffd8a8;
  padding: 1em;
  color: #d9480f;
}
```

```html
<div class="wrapper">
  <div>One</div>
  <div>Two</div>
  <div>Three</div>
  <div>Four</div>
  <div>Five</div>
</div>
```

```css
.wrapper {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
}
```

当抉择该用网格还是弹性盒时，你可以问自己一个简单的问题：

* 我只需要按行或者列控制布局？那就用弹性盒子
* 我需要同时按行和列控制布局？那就用网格
### 从内容出发还是从布局入手？

除了一维和二维布局之间的区别，还有一种办法决定该使用弹性盒还是网格来布局。弹性盒从内容出发。一个使用弹性盒的理想情形是你有一组元素，希望它们能平均地分布在容器中。你让内容的大小决定每个元素占据多少空间。如果元素换到了新的一行，它们会根据新行的可用空间决定它们自己的大小。

网格则从布局入手。当使用 CSS 网格时，你先创建网格，然后再把元素放入网格中，或者让自动放置规则根据把元素按照网格排列。我们能创建根据内容改变大小的网格轨道，但整个轨道的大小都会随之改变。

当你使用弹性盒，并发现自己禁用了一些弹性特性，那你可能需要的是 CSS 网格布局。例如，你给一个弹性元素设置百分比宽度来使它和上一行的元素对齐。这种情况下，网格很可能是一个更好的选择。

### 盒对齐

对于很多人来说，弹性盒特性最让人激动的一点是我们第一次拥有了正当的对齐能力。这让一个盒子在页面里中心对齐变得简单。弹性元素还可以使自己延伸到和容器等高，意味我们能实现等高列。长久以来，我们都想实现这些行为，并一直在用一些所谓“技巧”去达到起码的视觉效果。

弹性盒特性已经被加入到新的规范 Box Alignment Level 3。意味它们能被用在包括网格布局的其他规范中。它们未来也可能被用在其他的布局方法中。

本系列后续的指南中我会正式介绍盒对齐（Box Alignment）和它在网格布局中是如何工作的。不过现在我们先看一个比较弹性盒和网格的简单示例。

在这第一个示例中，我使用了弹性盒，一个容器内有三个元素。wrapper 设定了 `min-height`，确定了弹性容器的高度。我还在弹性容器中设定 `align-items` 为 `flex-end`，因此子元素会从弹性容器尾部开始排列。我还在 `box1` 上设定了 `align-self` 属性，这会覆盖默认值，使它延长至容器的高度，而 `box2` 则与弹性容器的起点对齐。
```

\* {
  box-sizing: border-box;
}

.wrapper {
  border: 2px solid #f76707;
  border-radius: 5px;
  background-color: #fff4e6;
}

.wrapper > div {
  border: 2px solid #ffa94d;
  border-radius: 5px;
  background-color: #ffd8a8;
  padding: 1em;
  color: #d9480f;
}
```

```html
<div class="wrapper">
  <div class="box1">One</div>
  <div class="box2">Two</div>
  <div class="box3">Three</div>
</div>
```

```css
.wrapper {
  display: flex;
  align-items: flex-end;
  min-height: 200px;
}
.box1 {
  align-self: stretch;
}
.box2 {
  align-self: flex-start;
}
```

### CSS 网格中的对齐

这个第二个示例使用了网格创建一个同样的布局。这次我们使用了应用于网格布局的盒对齐属性。因此我们是相对网格而不是弹性盒的起始对齐。对于网格来说，我们是让元素在它们各自的网格区域中对齐。在本例中就是一个单元格，但它也可能是多个单元格组成的一个区域。
```

\* {
  box-sizing: border-box;
}

.wrapper {
  border: 2px solid #f76707;
  border-radius: 5px;
  background-color: #fff4e6;
}

.wrapper > div {
  border: 2px solid #ffa94d;
  border-radius: 5px;
  background-color: #ffd8a8;
  padding: 1em;
  color: #d9480f;
}
```

```html
<div class="wrapper">
  <div class="box1">One</div>
  <div class="box2">Two</div>
  <div class="box3">Three</div>
</div>
```

```css
.wrapper {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  align-items: end;
  grid-auto-rows: 200px;
}
.box1 {
  align-self: stretch;
}
.box2 {
  align-self: start;
}
```

### `fr` 单位和 `flex-basis` 属性

我们已经看到了 `fr` 单元如何在网格容器中分配一定比例的可用空间到我们的网格轨道。当与 `minmax()` 函数结合使用时，`fr` 单元可以给我们与弹性盒中的 `flex` 属性非常相似的行为——同时仍然可以创建二维布局。

之前我们通过示例验证了一维布局和二维布局的差异，可以发现这两种布局方式对响应式的处理存在着不同。对于弹性布局，当我们拖拽以改变浏览器大小时，弹性盒会根据可用空间适当的调整行中元素的个数。当有足够的空间时，全部的 5 个元素全部在一行展示，当容器变的过窄时，每行则只能展示一个元素。

相较而言，网格布局则始终保持 3 列轨道。轨道会自动拉伸，但始终会保持我们定义网格时的轨道数量，也就是 3 个。

#### 自动填充网格轨道

我们可以通过使用 `repeat` 方法，配合 `auto-fill` 和 `auto-fit` 属性，创建类似弹性盒的效果，同时保证内容严格按照行和列的固定规则排列。

在接下来的示例中，在 `repeat` 方法中使用 `auto-fill` 属性替换整数值，并且设置轨道的宽度为 200px。这意味着网格布局将会根据容器的宽度创建最多的宽度为 200px 的列轨道。
```

\* {
  box-sizing: border-box;
}

.wrapper {
  border: 2px solid #f76707;
  border-radius: 5px;
  background-color: #fff4e6;
}

.wrapper > div {
  border: 2px solid #ffa94d;
  border-radius: 5px;
  background-color: #ffd8a8;
  padding: 1em;
  color: #d9480f;
}
```

```html
<div class="wrapper">
  <div>One</div>
  <div>Two</div>
  <div>Three</div>
</div>
```

```css
.wrapper {
  display: grid;
  grid-template-columns: repeat(auto-fill, 200px);
}
```

### 灵活的轨道数量

到这为止就和弹性盒布局不太一样了。在弹性盒布局示例中，子元素在被包裹起来之前大于基准的 200px。我们可以用使用网格布局中的 `auto-fill` 和 `minmax()` 函数实现同样的功能。在这个示例中，我创建了一个用 `minmax` 自动填充的轨道。我想要这个轨道的元素最小有 200px，最大 `1fr` 的宽度。一旦浏览器计算出有多少个 200px 会填充到这个容器里面，并算好网格间距，那么，浏览器就会把剩余的空间等分成以最大 `1fr` 单位计算的区域给其他元素。
```

\* {
  box-sizing: border-box;
}

.wrapper {
  border: 2px solid #f76707;
  border-radius: 5px;
  background-color: #fff4e6;
}

.wrapper > div {
  border: 2px solid #ffa94d;
  border-radius: 5px;
  background-color: #ffd8a8;
  padding: 1em;
  color: #d9480f;
}
```

```html
<div class="wrapper">
  <div>One</div>
  <div>Two</div>
  <div>Three</div>
</div>
```

```css
.wrapper {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
}
```

我们现在创建了具有灵活的轨道数量的网格，但可以看到网格中的元素同时按行和列对齐。

网格和绝对定位元素
---------

网格可以与绝对定位的元素进行交互，如果要将某个元素放置在网格或网格区域内，这可能很有用。该规范定义了当网格容器是包含块并且网格容器是绝对定位的元素的父级时的行为。

### 作为包含块的网格容器

要使网格容器成为一个包含块，需要为容器增加 `position` 属性，并把它的值设置为 `relative`，就像为任何其他绝对定位的元素创建一个包含块一样。接下来，如果再把一个网格元素设置为 `position: absolute`，那么网格容器就成为包含块，或者如果该元素具有网格定位的属性，那么被放置的网格就成为包含块。

在下面的示例中，一个容器中包含了四个子项。第三项是绝对定位的，并且使用基于行定位的方式把自己放置在网格中。网格容器具有 `position: relative` 属性，因此网格就成为该元素的定位上下文。
```

\* {
  box-sizing: border-box;
}

.wrapper {
  border: 2px solid #f76707;
  border-radius: 5px;
  background-color: #fff4e6;
}

.wrapper > div {
  border: 2px solid #ffa94d;
  border-radius: 5px;
  background-color: #ffd8a8;
  padding: 1em;
  color: #d9480f;
}
```

```html
<div class="wrapper">
  <div class="box1">One</div>
  <div class="box2">Two</div>
  <div class="box3">
    This block is absolutely positioned. In this example the grid container is
    the containing block and so the absolute positioning offset values are
    calculated in from the outer edges of the area it has been placed into.
  </div>
  <div class="box4">Four</div>
</div>
```

```css
.wrapper {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  grid-auto-rows: 200px;
  gap: 20px;
  position: relative;
}
.box3 {
  grid-column-start: 2;
  grid-column-end: 4;
  grid-row-start: 1;
  grid-row-end: 3;
  position: absolute;
  top: 40px;
  left: 40px;
}
```

可以看到该元素占据的区域是纵向的第 2 条线到第 4 条线，横向起于第 1 条线。然后使用 `top` 和 `left` 属性在该区域中进行偏移。就像通常绝对定位的元素会脱离标准文档流一样，该元素也脱离了文档流，被自动定位规则定位在包含块中。因为该元素脱离了文档流，所以不会再创建一个跨越纵向第 3 条线的轨道。

你可以试试看，如果把规则 `position: absolute` 从 `.box3` 的样式中移除掉，没有定位的元素会如何显示。

### 作为父级的网格容器

如果具有绝对定位的子元素的父级是网格容器，即使网格容器没有被设置为新的定位上下文，该子元素仍会脱离文档流。定位是基于定位上下文的，和这其他布局方式没有区别。在我们的示例中，如果把容器的 `position: relative` 属性移除掉，定位上下文就变成了当前视口，像下图中显示的那样。

![包含父级的网格容器的图像](/zh-CN/docs/Web/CSS/CSS_grid_layout/Relationship_of_grid_layout_with_other_layout_methods/2_abspos_example.png)

此外，该元素不再被视为网格布局的一部分，当网格中其他元素调整尺寸或自动布局时，都与该元素无关。

### 以网格区域作为父级

如果绝对定位的元素嵌套在网格区域内，该区域则成为该元素的参照语境。在下面的示例中，网格和上例相同，但是这次我们在网格 `.box3` 里嵌套了一个元素。

`.box3` 被设置了 `position: relative` 属性，其子元素设置了定位的偏移属性。此时，子元素的定位的参照语境就变成了网格区域。
```

\* {
  box-sizing: border-box;
}

.wrapper {
  border: 2px solid #f76707;
  border-radius: 5px;
  background-color: #fff4e6;
}

.wrapper > div {
  border: 2px solid #ffa94d;
  border-radius: 5px;
  background-color: #ffd8a8;
  padding: 1em;
  color: #d9480f;
}
```

```html
<div class="wrapper">
  <div class="box1">One</div>
  <div class="box2">Two</div>
  <div class="box3">
    Three
    <div class="abspos">
      This block is absolutely positioned. In this example the grid area is the
      containing block and so the absolute positioning offset values are
      calculated in from the outer edges of the grid area.
    </div>
  </div>
  <div class="box4">Four</div>
</div>
```

```css
.wrapper {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  grid-auto-rows: 200px;
  gap: 20px;
}
.box3 {
  grid-column-start: 2;
  grid-column-end: 4;
  grid-row-start: 1;
  grid-row-end: 3;
  position: relative;
}
.abspos {
  position: absolute;
  top: 40px;
  left: 40px;
  background-color: rgba(255, 255, 255, 0.5);
  border: 1px solid rgba(0, 0, 0, 0.5);
  color: #000;
  padding: 10px;
}
```

网格和 display: contents
---------------------

最后一个值得关注的与其他布局规范的交互是 CSS 网格布局与 `display: contents` 之间的交互。`display` 属性的 `contents` 值是显示规范中描述的新值，如下所示：

>
> “元素本身不会生成任何盒子，但其子元素和伪元素仍然会像平常一样生成盒子。（用户代理）为了生成盒子和布局，必须将元素视为已在文档树中被其子元素和伪元素替换。“
>
>
>

如果将元素设置为 `display: contents`，通常自身的盒子会消失，子元素的盒子仍显示，就像子元素在文档树中上升了一层。这意味着一个网格元素的子元素可以成为网格元素。听起来很奇怪？下面是一个简单的示例。

### 网格布局与子元素嵌套

在下面的网格中，第一个元素设置为跨越三个列轨道，它包含三个嵌套的元素，由于这些元素不是直接子元素，因此它们不会成为网格布局的一部分，因此使用常规的块布局进行显示。
```

\* {
  box-sizing: border-box;
}

.wrapper {
  border: 2px solid #f76707;
  border-radius: 5px;
  background-color: #fff4e6;
}

.box {
  border: 2px solid #ffa94d;
  border-radius: 5px;
  background-color: #ffd8a8;
  padding: 1em;
  color: #d9480f;
}
.nested {
  border: 2px solid #ffec99;
  border-radius: 5px;
  background-color: #fff9db;
  padding: 1em;
}
```

```html
<div class="wrapper">
  <div class="box box1">
    <div class="nested">a</div>
    <div class="nested">b</div>
    <div class="nested">c</div>
  </div>
  <div class="box box2">Two</div>
  <div class="box box3">Three</div>
  <div class="box box4">Four</div>
  <div class="box box5">Five</div>
</div>
```

```css
.wrapper {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  grid-auto-rows: minmax(100px, auto);
}
.box1 {
  grid-column-start: 1;
  grid-column-end: 4;
}
```

### 使用 display: contents

现在如果将 `display：contents` 添加到 `box1` 的样式规则中，则该元素的盒子将消失，子元素成为网格元素，并且应用自动定位规则放置在网格中。
```

\* {
  box-sizing: border-box;
}

.wrapper {
  border: 2px solid #f76707;
  border-radius: 5px;
  background-color: #fff4e6;
}

.box {
  border: 2px solid #ffa94d;
  border-radius: 5px;
  background-color: #ffd8a8;
  padding: 1em;
  color: #d9480f;
}
.nested {
  border: 2px solid #ffec99;
  border-radius: 5px;
  background-color: #fff9db;
  padding: 1em;
}
```

```html
<div class="wrapper">
  <div class="box box1">
    <div class="nested">a</div>
    <div class="nested">b</div>
    <div class="nested">c</div>
  </div>
  <div class="box box2">Two</div>
  <div class="box box3">Three</div>
  <div class="box box4">Four</div>
  <div class="box box5">Five</div>
</div>
```

```css
.wrapper {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  grid-auto-rows: minmax(100px, auto);
}
.box1 {
  grid-column-start: 1;
  grid-column-end: 4;
  display: contents;
}
```

这可以让元素嵌套到网格中，就好像它们是网格的一部分一样，并且可以用它解决 `subgrid` 值尚未实现时要解决的一些问题。也可以在弹性盒布局中用类似的方法通过 `display: contents` 使嵌套的元素成为弹性元素。

正如本文中所述，CSS 网格布局只是你的工具包的一部分。不要害怕在布局时将它与其他布局方法混用，大胆用它获得你想要的效果吧。

参见
--

* 弹性盒子指南
* 多列布局指南