repeating-radial-gradient() - CSS：层叠样式表

repeating-radial-gradient()
===========================

CSS 函数 **`repeating-radial-gradient()`** 创建一个从原点辐射的重复渐变组成的 `<image>`，类似于 `radial-gradient()` 并且采用相同的参数，但是它会在所有方向上无限重复色标，以覆盖其整个容器，类似于 `repeating-linear-gradient()`。函数的结果是 `<gradient>` 数据类型的对象，此对象是一种特殊的 `<image>` 类型。

尝试一下
----

每次重复时，色标（color stop）的位置的偏移量都是基准径向渐变长度（最后一个色标和第一个之间的距离）的倍数。因此，最后色标的颜色应该与第一个颜色的颜色保持一致；如果不一致，会导致非常突兀的渐变效果，可以通过将第一个色标重复添加到最后一个中来解决。

与其他渐变一样，径向重复渐变没有内在尺寸，也就是说，它没有固有或首选的尺寸，也没有首选的比例，其实际大小取决于所应用的元素的大小。

由于 `<gradient>` 属于 `<image>` 数据类型，因此只能用在可以使用 `<image>` 的地方。因此，`repeating-radial-gradient()` 在`background-color` 以及其他使用 `<color>` 数据类型上不起作用。

语法
--

```css
/\* 位于容器中间的渐变，
 由红色开始，改变为蓝色，以绿色结束，
 颜色每 30px 重复一次 \*/
repeating-radial-gradient(circle at center, red 0, blue, green 30px);

/\* 接近容器左上角的椭圆形渐变，
 由红色开始，改变为绿色，然后再变回红色，
 在中心和右下角之之间重复五次，
 在中心和左上角之间只重复一次 \*/
repeating-radial-gradient(farthest-corner at 20% 20%, red 0, green, red 20%);
```

### 值

`<position>`

渐变的位置，和 `background-position` 或者 `transform-origin` 以相同方式解析。如果没有指定，默认为 `center`。

`<shape>`

渐变的结束形状。值可以是 `circle`（圆形，渐变的形状是一个半径不变的正圆）或 `ellipse`（椭圆，形状为轴对称椭圆）。如果没有指定，默认为 `ellipse`。

`<extent-keyword>`

关键字，描述结束形状应该有多大。可能的值包括：

| 关键字 | 描述 |
| --- | --- |
| `closest-side` | 渐变结束形状如果是圆形，与容器距离渐变中心点最近的一边相切，如果是椭圆，则与距离渐变中心点最近的垂直和水平边相切。 |
| `closest-corner` | 渐变结束形状与容器距离渐变中心点最近的一个角相交。 |
| `farthest-side` | 类似于 `closest-side`，结束形状与容器距离渐变中心点最远的一边（或最远的垂直和水平边）相切。 |
| `farthest-corner` | 渐变的结束形状与容器距离渐变中心点最远的一个角相交。 |

**备注：** 早期的函数实现中还包含其他关键字（`cover` 和 `contain`），分别相当于标准关键字 `farthest-corner` 和 `closest-side`。但因为在某些实现中丢弃了这些旧的关键字，所以请仅使用标准关键字。

`<color-stop>`

色标（color stop）的 `<color>` 值，然后是一个或两个可选的色标位置（沿渐变轴的 `<percentage>` 或 `<length>`）。百分比值 `0%`，或者长度值 `0`，表示渐变中心点；百分比值 `100%` 表示渐变射线与结束形状相交的点。其间的百分比值线性对应渐变射线上的点。

### 形式语法
```

<repeating-radial-gradient()> =
  repeating-radial-gradient( [ <radial-gradient-syntax> ] )

<radial-gradient-syntax> =
  [ <radial-shape> || <radial-size> ]? [ at <position> ]? , <color-stop-list>

<radial-shape> =
  circle   |
  ellipse

<radial-size> =
  <radial-extent>               |
  <length [0,∞]>                |
  <length-percentage [0,∞]>{2}

<position> =
  [ left | center | right | top | bottom | <length-percentage> ]  |
  [ left | center | right ] && [ top | center | bottom ]  |
  [ left | center | right | <length-percentage> ] [ top | center | bottom | <length-percentage> ]  |
  [ [ left | right ] <length-percentage> ] && [ [ top | bottom ] <length-percentage> ]

<color-stop-list> =
  <linear-color-stop> , [ <linear-color-hint>? , <linear-color-stop> ]#

<radial-extent> =
  closest-corner   |
  closest-side     |
  farthest-corner  |
  farthest-side

<length-percentage> =
  <length>      |
  <percentage>

<linear-color-stop> =
  <color> <length-percentage>?

<linear-color-hint> =
  <length-percentage>

```

示例
--

### 黑白相间的渐变
```

<div class="radial-gradient"></div>
```

```
.radial-gradient {
  width: 120px;
  height: 120px;
}
```

```css
.radial-gradient {
  background: repeating-radial-gradient(
    black,
    black 5px,
    white 5px,
    white 10px
  );
}
```

### Farthest-corner 渐变
```

<div class="radial-gradient"></div>
```

```
.radial-gradient {
  width: 240px;
  height: 120px;
}
```

```css
.radial-gradient {
  background: repeating-radial-gradient(
    ellipse farthest-corner at 20% 20%,
    red,
    black 5%,
    blue 5%,
    green 10%
  );
  background: repeating-radial-gradient(
    ellipse farthest-corner at 20% 20%,
    red 0 5%,
    green 5% 10%
  );
}
```

这个椭圆形渐变会位于左上角靠中心 20% 的位置，在中心和最远角（右下角）之间重复 10 次。支持多位置色标的浏览器会显示为红色和绿色条纹的椭圆形。不支持这个语法的浏览器仍会从红色到黑色再由蓝色到绿色的渐变。

**备注：** 更多例子请见使用 CSS 渐变。

规范
--

| Specification |
| --- |
| CSS Images Module Level 3 # repeating-gradients |

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

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

参见
--

* 使用 CSS 渐变
* 其他渐变函数：`radial-gradient()`、`linear-gradient()`、`repeating-linear-gradient()`、`conic-gradient()`、`repeating-conic-gradient()` (en-US)
* `<image>`
* `image()` (en-US)
* `element()`
* `image-set()` (en-US)
* `cross-fade()` (en-US)


conic-gradient() - CSS：层叠样式表

conic-gradient()
================

CSS 函数 **`conic-gradient()`** 创建一个由渐变组成的图像，渐变的颜色围绕一个中心点旋转（而不是从中心辐射）进行过渡。锥形渐变的例子包括饼图和色轮 (en-US)。`conic-gradient()` 函数的结果是 `<gradient>` 数据类型的对象，此对象是一种特殊的 `<image>` 数据类型。

尝试一下
----

语法
--

```css
/\* 一个旋转 45 度的锥形渐变，从蓝色渐变到红色 \*/
conic-gradient(from 45deg, blue, red);

/\* 一个蓝紫色框：从蓝色渐变到红色，但只有右下象限可见，因为锥形渐变的中心位于左上角 \*/
conic-gradient(from 90deg at 0 0, blue, red);

/\* 色轮 \*/
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%)
);
```

### 值

`<angle>`

在 `from` 关键字之前，以角度作为其值，定义顺时针方向的渐变旋转。

`<position>`

使用与 background-position 属性相同的长度、顺序和关键字值，定义渐变的中心。如果省略，默认值是 `center`，表示渐变是居中的。

`<angular-color-stop>`

色标（color stop）的 `<color>` 值，然后是一个或两个可选的色标位置（沿着渐变圆周轴的 `<angle>`）。

`<color-hint>`

插值 (en-US)提示，定义了在相邻色标之间的渐变如何进行。这个长度定义了渐变色应在两个色标之间的哪一点到达颜色过渡的中点。如果省略，颜色过渡的中点是两个色标之间的中点。

**备注：** CSS 渐变中的色标的渲染与 SVG 渐变中的色标遵循相同的规则。

描述
--

与其他渐变一样，锥形渐变没有内在尺寸，也就是说没有固有或首选的尺寸，也没有首选的比例，其实际大小取决于所应用的元素的大小。

要创建重复的锥形渐变来填充 360 度旋转，应该使用 `repeating-conic-gradient()` (en-US) 函数。

由于 `<gradient>` 属于 `<image>` 数据类型，因此只能用在能使用 `<image>` 的地方。因此，`conic-gradient()` 在 `background-color` 以及其他使用 `<color>` 数据类型的属性上不起作用。

**备注：** 为什么它被称为“锥形”渐变？如果色块的一侧比另一侧亮得多，则从上面看，它可能看起来像一个圆锥体。

### 锥形渐变的合成

锥形渐变语法与径向渐变语法类似，但色标放置在渐变圆弧（圆的周长）周围，而不是从渐变中心出现的渐变线上。使用锥形渐变时，颜色会围绕圆心旋转，从顶部开始顺时针旋转。在径向渐变中，颜色从椭圆中心向各个方向向外过渡。

![沿着锥形渐变的圆周和径向渐变的轴的色标](/zh-CN/docs/Web/CSS/gradient/conic-gradient/screenshot_2018-11-29_21.09.19.png)

锥形渐变是通过指示旋转角度、渐变中心，然后指定色标列表来指定的。与线性渐变和径向渐变不同，线性渐变和径向渐变的色标是通过长度指定的，而锥形渐变的色标是通过角度指定的。单位包括角度 `deg`、梯度 `grad`、弧度 `rad` 和整圈的 `turn`。在一个圆中有 360 度，400 个梯度，2π 弧度，1 圈。支持锥形渐变的浏览器也接受百分比值，100% 等于 360 度，但这不在规范中。

与径向渐变类似，锥形渐变语法用于将渐变中心定位在图像内部甚至外部的任何位置。位置的值类似于两个值的 background-position 语法。

渐变的弧度是渐变的周长。渐变或弧度的*起始点*方向是北，或 12:00pm 方向。然后通过 *from* 角度来旋转。渐变的颜色由倾斜的色标、它们的起点、终点，以及介于两者之间的可选的倾斜的色标决定。颜色之间的过渡可以通过相邻颜色的色标之间的颜色提示来改变。

#### 自定义渐变

通过在渐变弧上添加更多角度的色标，可以在多种颜色之间创建高度定制的过渡。色标的位置可以通过使用 `<angle>` 来明确地定义。如果不指定色标的位置，它将位于其前面的色标和后面的色标之间。如果没有为第一个或最后一个色标指定角度，则其值分别为 0 度和 360 度。以下两种渐变是等效的：

```css
conic-gradient(red, orange, yellow, green, blue);
conic-gradient(red 0deg, orange 90deg, yellow 180deg, green 270deg, blue 360deg);
```

默认情况下，颜色从一个色标处的颜色平滑过渡到下一个色标处的颜色，颜色之间的中点是颜色过渡之间的中点。通过添加颜色提示，可以将此颜色过渡中点移动到两个色标之间的任何点，指示颜色过渡的中间位置。以下是从起点到 10% 标记的纯红色，在经过整圈的 80% 时从红色过渡到蓝色，最后 10% 为纯蓝色。然而，红色到蓝色渐变变化的中点位于 20% 标记处，而不是在没有 80 梯度或 20% 颜色提示的情况下发生的 50% 标记处。

```css
conic-gradient(red 40grad, 80grad, blue 360grad);
```

如果两个及以上色标位于同一位置，则转换将是在该位置声明的第一个和最后一个颜色之间的硬线。要使用锥形渐变创建饼图（这不是创建饼图的正确方法，因为背景图像并非无障碍），请使用硬色标——其中两个相邻色标的色标角度相同。最简单的方法是使用多个位置的色标。以下两种声明是等效的：

```css
conic-gradient(#fff 0.09turn, #bbb 0.09turn, #bbb 0.27turn, #666 0.27turn, #666 0.54turn, #000 0.54turn);
conic-gradient(#fff 0turn 0.09turn, #bbb 0.09turn 0.27turn, #666 0.27turn 0.54turn, #000 0.54turn 1turn);
```

色标应按升序排列。值较低的后续色标将覆盖上一个色标的值，从而创建硬过渡。以下内容在 30% 标记处从红色变为黄色，然后在 35% 的渐变范围内从黄色变为蓝色：

```css
conic-gradient(red .8rad, yellow .6rad, blue 1.3rad);
```

使用锥形渐变还可以创建其他效果，棋盘格就是其中之一。通过创建具有左上角和右下角白色象限以及左下角和右上角黑色象限的象限，然后重复 16 次渐变（四次横切，四次向下），就可以制作棋盘。

```css
conic-gradient(#fff 90deg, #000 0.25turn 0.5turn, #fff 1rad 1.5rad, #000 300grad);
background-size: 25% 25%;
```

你可以混合和匹配不同的角度单位，但最好不要这样做，以上的内容就已经很难理解。

### 形式语法
```

<conic-gradient()> =
  conic-gradient( [ <conic-gradient-syntax> ] )

<conic-gradient-syntax> =
  [ [ [ from <angle> ]? [ at <position> ]? ] || <color-interpolation-method> ]? , <angular-color-stop-list>

<position> =
  [ left | center | right | top | bottom | <length-percentage> ]  |
  [ left | center | right ] && [ top | center | bottom ]  |
  [ left | center | right | <length-percentage> ] [ top | center | bottom | <length-percentage> ]  |
  [ [ left | right ] <length-percentage> ] && [ [ top | bottom ] <length-percentage> ]

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

<angular-color-stop-list> =
  <angular-color-stop> , [ <angular-color-hint>? , <angular-color-stop> ]#

<length-percentage> =
  <length>      |
  <percentage>

<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

<angular-color-stop> =
  <color> <color-stop-angle>?

<angular-color-hint> =
  <angle-percentage>

<color-stop-angle> =
  <angle-percentage>{1,2}

<angle-percentage> =
  <angle>       |
  <percentage>

```

无障碍考虑
-----

浏览器不向辅助技术提供任何关于背景图像的特殊信息。这主要对屏幕阅读器来说很重要，因为屏幕阅读器不会宣布其存在，因此不会向用户传达任何信息。虽然可以创建饼图、棋盘和其他带有圆锥梯度的效果，但 CSS 图像不提供指定替代文本的原生方式，因此屏幕阅读器用户无法访问由锥形渐变表示的图像。如果图像包含对理解页面的总体用途至关重要的信息，那么最好在文档中对其进行语义描述。

* MDN 理解 WCAG，指南 1.1 解释 (en-US)
* 理解成功标准 1.1.1 | W3C 理解 WCAG 2.0
示例
--

### 40 度渐变
```

div {
  width: 100px;
  height: 100px;
}
```

```
<div></div>
```

```css
div {
  background-image: conic-gradient(from 40deg, #fff, #000);
}
```

### 偏移中心的渐变
```

div {
  width: 100px;
  height: 100px;
}
```

```
<div></div>
```

```css
div {
  background: conic-gradient(from 0deg at 0% 25%, blue, green, yellow 180deg);
}
```

### 渐变饼图

本示例使用多位置色标，相邻颜色具有相同的色标值，从而创建出条纹效果。
```

div {
  width: 100px;
  height: 100px;
}
```

```
<div></div>
```

```css
div {
  background: conic-gradient(red 36deg, orange 36deg 170deg, yellow 170deg);
  border-radius: 50%;
}
```

### 棋盘格
```

div {
  width: 100px;
  height: 100px;
}
```

```
<div></div>
```

```css
div {
  background: conic-gradient(
      #fff 0.25turn,
      #000 0.25turn 0.5turn,
      #fff 0.5turn 0.75turn,
      #000 0.75turn
    ) top left / 25% 25% repeat;
  border: 1px solid;
}
```

### 更多锥形渐变的例子

更多示例请参见使用 CSS 渐变。

规范
--

| Specification |
| --- |
| CSS Images Module Level 4 # conic-gradients |

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

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

参见
--

* 使用 CSS 渐变
* 其他渐变函数：`repeating-conic-gradient()` (en-US)、`linear-gradient()`、`repeating-linear-gradient()`、`radial-gradient()`、`repeating-radial-gradient()`
* `<image>`
* `image()` (en-US)
* `element()`
* `image-set()` (en-US)
* `cross-fade()` (en-US)


linear-gradient() - CSS：层叠样式表

linear-gradient()
=================

**`linear-gradient()`** CSS 函数创建一个由两种或多种颜色沿一条直线进行线性过渡的图像，其结果是 `<gradient>` 数据类型的对象，此对象是一种特殊的 `<image>` 数据类型。

尝试一下
----

语法
--

```css
/\* 渐变轴为 45 度，从蓝色渐变到红色 \*/
linear-gradient(45deg, blue, red);

/\* 从右下到左上、从蓝色渐变到红色 \*/
linear-gradient(to left top, blue, red);

/\* 色标：从下到上，从蓝色开始渐变，到高度 40% 位置是绿色渐变开始，最后以红色结束 \*/
linear-gradient(0deg, blue, green 40%, red);

/\* 颜色提示：从左到右的渐变，由红色开始，沿着渐变长度到 10% 的位置，然后在剩余的 90% 长度中变成蓝色 \*/
linear-gradient(.25turn, red, 10%, blue);

/\* 多位置色标：45% 倾斜的渐变，左下半部分为红色，右下半部分为蓝色，中间有一条硬线，在这里渐变由红色转变为蓝色 \*/
linear-gradient(45deg, red 0 50%, blue 50% 100%);
```

### 值

`<side-or-corner>`

 渐变线的起始点位置。如果指定了，则包含 `to` 和最多两个关键字：一个指定水平位置（`left` 或 `right`），另一个指定竖直位置（`top` 或 `bottom`）。关键词的先后顺序无影响。如果没有指定，则默认为 `to bottom`。
 `to top`、`to bottom`、`to left` 和 `to right` 分别等价于 `0deg`、`180deg`、`270deg` 和 `90deg`。其余值会被转换为角度。

`<angle>`

渐变线的方向的角度。`0deg` 等价于 `to top`，增加值相当于顺时针旋转。

`<linear-color-stop>`

色标（color stop）的 `<color>` 值，然后是一个或两个可选的色标位置（沿渐变轴的 `<percentage>` 值或 `<length>` 值）。

`<color-hint>`

插值提示，定义渐变色在相邻色标之间的渐变过程。其中的长度定义了渐变色应在两个色标之间的哪个点到达颜色过渡的中点。如果省略该值，颜色过渡的中点就是两个色标之间的中点。

**备注：** CSS 渐变中的色标 的渲染与 SVG 渐变中的色标遵循相同的规则。

描述
--

和其他渐变一样，线性渐变没有内在尺寸，也就是说，它没有固有或首选的尺寸，也没有首选的比例，其实际大小取决于所应用的元素的大小。

要创建一个能够重复填满容器的线性渐变，请使用 `repeating-linear-gradient()` 函数。

由于 `<gradient>` 属于 `<image>` 数据类型，因此只能用在能使用 `<image>` 的地方。因此，`linear-gradient()` 在 `background-color` 以及其他使用 `<color>` 数据类型的属性上不起作用。

### 线性渐变的合成

线性渐变是在一个轴——*渐变线*和两个或者更多个*色标*构成的。轴上的每个点都是一个单独的颜色，要创建平滑的渐变，`linear-gradient()` 函数会绘制出一系列与渐变线垂直的彩色线，每条线都匹配与渐变线相交点的颜色。

![linear-gradient.png](/zh-CN/docs/Web/CSS/gradient/linear-gradient/linear-gradient.png)

渐变线由包含渐变图形的容器的中心点和一个角度来定义的。渐变线上的颜色值是由不同的点来定义，包括起始点、终点，以及两者之间的可选的中间点（中间点可以有多个）。

*起点*是渐变线上代表起始颜色值的点。*终点*是渐变线上代表最终颜色值的点。这两个点都是由渐变线和从最近的顶点发出的垂直线之间的交叉点定义的，然而从起点的对称点来定义终点是更容易理解的一种方式，因为终点是起点关于容器的中心点的反射点。这一复杂的定义导致了一个有趣的效果，有时称为 *magic corners*：起点附近的点具有跟起点相同的颜色值，终点附近的点具有跟终点相同的颜色值。

#### 自定义渐变

通过提供额外的色标，可以在多种颜色之间创建高度个性化的过渡效果。色标的位置可以由 `<length>` 值或 `<percentage>` 值清晰地指定。如果你不指定颜色的位置，那么将会位于前面和后面两点的中点。以下两个渐变是等价的：

```css
linear-gradient(red, orange, yellow, green, blue);
linear-gradient(red 0%, orange 25%, yellow 50%, green 75%, blue 100%);
```

默认情况下，颜色会从一个色标的颜色到后续的色标的颜色平滑过渡，颜色的中点是颜色过渡中的中间点。你可以将这个中点移动到两个色标之间的任何位置，方法就是在两个颜色之间的中点所在的位置添加一个没有加标签的 % 颜色提示。下面这个例子中，起始点到 10% 是纯红色，90% 到结束点是纯蓝色。10% 和 90% 之间是颜色从红色过渡到蓝色的地方，但是，过渡的中点是 30% 的位置，假如没有这个 30% 的颜色提示，就会是 50% 的位置。

```css
linear-gradient(red 10%, 30%, blue 90%);
```

如果两个及以上色标位于同一个位置，那么过渡会在这个位置的第一个和最后一个颜色之间产生一条硬线。

色标应该以递增的顺序列出。后面的更低值的色标会覆盖前面的值并创建硬过渡线。下面的渐变在 40% 处由红色变为黄色，然后在 25% 处由黄色变为蓝色：

```css
linear-gradient(red 40%, yellow 30%, blue 65%);
```

允许有多个位置的色标。一个颜色可以声明为多个相邻的色标，方法就是在 CSS 声明中包括这两个位置。以下的三个渐变是等价的：

```css
linear-gradient(red 0%, orange 10%, orange 30%, yellow 50%, yellow 70%, green 90%, green 100%);
linear-gradient(red, orange 10% 30%, yellow 50% 70%, green 90%);
linear-gradient(red 0%, orange 10% 30%, yellow 50% 70%, green 90% 100%);
```

默认情况下，如果 `0%` 的地方没有颜色，那么那里就是声明的第一个颜色。类似地，最后一个颜色也会持续到 `100%` 的位置，或者如果最后一个色标没有声明长度，那么就是在 `100%` 的位置。

形式语法
----
```

<linear-gradient()> =
  linear-gradient( [ <linear-gradient-syntax> ] )

<linear-gradient-syntax> =
  [ <angle> | to <side-or-corner> ]? , <color-stop-list>

<side-or-corner> =
  [ left | right ]  ||
  [ top | bottom ]

<color-stop-list> =
  <linear-color-stop> , [ <linear-color-hint>? , <linear-color-stop> ]#

<linear-color-stop> =
  <color> <length-percentage>?

<linear-color-hint> =
  <length-percentage>

<length-percentage> =
  <length>      |
  <percentage>

```

示例
--

### 45 度渐变
```

body {
  width: 100vw;
  height: 100vh;
}
```

```css
body {
  background: linear-gradient(45deg, red, blue);
}
```

### 从渐变线 60% 处开始的渐变
```

body {
  width: 100vw;
  height: 100vh;
}
```

```css
body {
  background: linear-gradient(135deg, orange 60%, cyan);
}
```

### 有多位置色标的渐变

这个示例使用了多位置的色标，两个相邻的颜色有相同的色标值，形成了条纹效果。
```

body {
  width: 100vw;
  height: 100vh;
}
```

```css
body {
  background: linear-gradient(
    to right,
    red 20%,
    orange 20% 40%,
    yellow 40% 60%,
    green 60% 80%,
    blue 80%
  );
}
```

### 更多线性渐变示例

更多示例请见使用 CSS 渐变。

规范
--

| Specification |
| --- |
| CSS Images Module Level 4 # linear-gradients |

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

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

参见
--

* 使用 CSS 渐变
* 其他渐变函数：`repeating-linear-gradient()`、`radial-gradient()`、`repeating-radial-gradient()`、`conic-gradient()`、`repeating-conic-gradient()` (en-US)
* `<image>`
* `element()`
* `image()` (en-US)
* `image-set()` (en-US)
* `cross-fade()` (en-US)
* CSS 图像模块 (en-US)
* MDN 博客中的文章 CSS 颜色中的新功能、渐变和色调（级别 4）（2023 年）


pad - CSS：层叠样式表

pad
===

\*\*`pad`\*\*属性和自定义记数样式一起使用时，可以用来限定记数样式的最小长度。如果某个记数样式小于 pad 所指定的长度，那么会用 pad 指定的填充字符串来填充至指定长度。如果比 pad 所指定的长度长，则会正常显示。Pad 属性的第一个参数是最小长度，第二个参数是填充字符串。一个常见的用处是序号编号需要填充两位的时候，即需要编号"01","02","03",……, 而不仅仅是 1, 2, 3...

|  |  |
| --- | --- |
| Related at-rule | `@counter-style` |
| 初始值 | `0 ""` |
| 计算值 | as specified |

参数
--

```css
pad: 3 "0";
```

### 参数值

`<integer> && <symbol>`

`<integer>` 表示所有计数样式必须达到的最小长度 (必须是非负整数). 如果指定的最小长度没有达到，将会用`<symbol>`来填充直到最小长度。

### 形式语法
```

pad =
  <integer [0,∞]>  &&
  <symbol>

<symbol> =
  <string>        |
  <image>         |
  <custom-ident>

<image> =
  <url>       |
  <gradient>

<url> =
  <url()>  |
  <src()>

<url()> =
  url( <string> <url-modifier>\* )  |
  <url-token>

<src()> =
  src( <string> <url-modifier>\* )

```

示例
--

### HTML

```html
<ul class="list">
  <li>One</li>
  <li>Two</li>
  <li>Three</li>
  <li>Four</li>
  <li>Five</li>
</ul>
```

### CSS

```css
@counter-style pad-example {
  system: numeric;
  symbols: "0" "1" "2" "3" "4" "5";
  pad: 2 "0";
}

.list {
  list-style: pad-example;
}
```

### 结果

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

| Specification |
| --- |
| CSS Counter Styles Level 3 # counter-style-pad |

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

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

参见
--

* `list-style`, `list-style-image`, `list-style-position`
* `symbols()` (en-US), 该功能符号创建匿名计数器样式 .


speak-as - CSS：层叠样式表

speak-as
========

当已明确定义 `@counter-style` 后，可以用 **`speak-as`** 定义在口语场景中如何表述这个 counter 符号。比如作为一篇文章的作者可以指定，当计算机读出这篇文章时，是以数字序号表示 counter，还是仅仅用语音提示。

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

语法
--

```css
/\* Keyword values \*/
speak-as: auto;
speak-as: bullets;
speak-as: numbers;
speak-as: words;
speak-as: spell-out;

/\* @counter-style name value \*/
speak-as: <counter-style-name>;
```

### 值

`auto`

如果 **`speak-as`** 的值是 **`auto`**，那么它的实际值是由 `system` (en-US) 的值决定的：

* 如果 `system` 的值是 `alphabetic`，**`speak-as`** 的值是 `spell-out`**。**
* 如果 `system` 的值是 `cyclic`，**`speak-as`** 的值是 `bullets`。
* 如果 `system` 的值是 `extends`，当被继承的样式上也定义了 **`speak-as: auto`**，那么 **`speak-as`** 的值就和被继承样式的值相同。
* 其他场景下，表现都与 **`speak-as: numbers`** 相同。

`bullets`

用于表示无序的列表项，具体的发音由user agent决定。

`numbers`

根据文档语言的规范，读出计数器标明的数字的值。

`words`

在显示上，由用户代理决定计数器的值，读的时候以单词为单位。

`spell-out`

依然是用户代理决定了计数器，但它将会以逐个字母的形式被读出。如果遇到某个计数器，用户代理不知道要如何读时，会将它当做 `numbers` 处理。

`<counter-style-name>`

The name of another counter style, specified as a `<custom-ident>`. If included, the counter will be spoken out in the form specified in that counter style, kind of like specifying the `fallback` (en-US) descriptor. If the specified style does not exist, `speak-as` defaults to `auto`.它的另一个名称是 `<custom-ident>`。使用了这个值后，计数器将以被指定的样式名的形式读出，和声明了 `fallback` (en-US) 的效果类似。如果被指定的样式不存在，`speak-as` 将回退为`auto`。

### 语法
```

speak-as =
  auto                  |
  bullets               |
  numbers               |
  words                 |
  spell-out             |
  <counter-style-name>

```

例子
--

### HTML

```html
<ul class="list">
  <li>One</li>
  <li>Two</li>
  <li>Three</li>
  <li>Four</li>
  <li>Five</li>
</ul>
```

### CSS

```css
@counter-style speak-as-example {
  system: fixed;
  symbols:     ;
  suffix: " ";
  speak-as: numbers;
}

.list {
  list-style: speak-as-example;
}
```

### 结果

无障碍问题
-----

这个属性的无障碍支持度不太友好。请别指望靠它能正确地传递出页面的核心信息。

Let's Talk About Speech CSS | CSS Tricks

规范
--

| Specification |
| --- |
| CSS Counter Styles Level 3 # counter-style-speak-as |

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

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

参考
--

* `list-style`, `list-style-image`, `list-style-position`
* `symbols()` (en-US), the functional notation creating anonymous counter styles.


additive-symbols - CSS：层叠样式表

additive-symbols
================

`additive-symbols` 描述符定义符号，用于值可累积的可数的 `system` (en-US)的项。 `additive-symbols` 定义累积的的元组（tuples）,每个元组项都包含一个符号和一个非负整数的权重。`additive system` 被用于构造 sign-value numbering （符号 - 值，指数字的值就是是符号加在一起的值）系统，比如罗马数字。

```css
additive-symbols: 3 "0";
additive-symbols:
  3 "0",
  2 "\2E\20";
additive-symbols:
  3 "0",
  2 url(symbol.png);
```

当系统描述符是循环，数字，拼音，象征，或固定的时候，使用 `symbols()` (en-US)代替`additive-symbols`

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

语法
--

### Formal syntax
```

additive-symbols =
  [ <integer [0,∞]> && <symbol> ]#

<symbol> =
  <string>        |
  <image>         |
  <custom-ident>

<image> =
  <url>       |
  <gradient>

<url> =
  <url()>  |
  <src()>

<url()> =
  url( <string> <url-modifier>\* )  |
  <url-token>

<src()> =
  src( <string> <url-modifier>\* )

```

示例
--

### HTML

```html
<ul class="list">
  <li>One</li>
  <li>Two</li>
  <li>Three</li>
  <li>Four</li>
  <li>Five</li>
</ul>
```

### CSS

```css
@counter-style additive-symbols-example {
  system: additive;
  additive-symbols:
    V 5,
    IV 4,
    I 1;
}
.list {
  list-style: additive-symbols-example;
}
```

### 结果

规范
--

| Specification |
| --- |
| CSS Counter Styles Level 3 # counter-style-symbols |

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

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

相关链接
----

* `list-style`, `list-style-image`, `list-style-position`
* The `symbols()` (en-US), functional notation is used for creating anonymous counter styles.


在 CSS 中实现图像合并 - CSS：层叠样式表

在 CSS 中实现图像合并
=============

CSS **图像合并**（**Image sprites**）技术，亦作 CSS 贴图定位、图像精灵（sprite，意为精灵），被运用于众多使用大量小图标的网页应用之上。它可取图像的一部分来使用，使得使用一个图像文件替代多个小文件成为可能。相较于一个小图标一个图像文件，单独一张图片所需的 HTTP 请求更少，对内存和带宽更加友好。

**备注：** 备注：当使用 HTTP/2 时，使用多个小流量请求实际上可能更为带宽友好。

实现
--

若要为所有类名为 `toolbtn` 的元素附加上一张图片：

```css
.toolbtn {
  background: url(myfile.png);
  display: inline-block;
  height: 20px;
  width: 20px;
}
```

为设置 `background-position` 以使每个按钮得到合并后图片中的正确部分，可以在 `background` 属性中的 `url()` 后添加 x, y 两个坐标值，或直接使用 `background-position` 属性。例如：

```css
#btn1 {
  background-position: -20px 0px;
}
#btn2 {
  background-position: -40px 0px;
}
```

这会将 ID 为 btn1 的元素的背景向左移 20px，ID 为 btn2 的元素的背景向左移 40px（假设这两个元素都带有 `toolbtn` 这个类且应用了上面 `background` 属性中定义的图片背景）

类似的，你也可以使用下面的代码添加悬停效果：

```css
#btn:hover {
  background-position: <pixels shifted right>px <pixels shifted down>px;
}
```

### 深入阅读

CSS Tricks 上的完整 Demo：http://css-tricks.com/snippets/css/perfect-css-sprite-sliding-doors-button/


使用 CSS 渐变 - CSS：层叠样式表

使用 CSS 渐变
=========

**CSS 渐变**由 `<gradient>` 数据类型表示，它是 `<image>` 的一种特殊类型，由两种或多种颜色之间的渐变过渡构成。你可以选择三种类型的渐变：*线性*（由 `linear-gradient()` 函数创建）、*径向*（由 `radial-gradient()` 函数创建）和*锥形*（由 `conic-gradient()` 函数创建）。你还可以使用 `repeating-linear-gradient()` 和 `repeating-conic-gradient()` (en-US) 函数创建重复渐变。

渐变可以在任何使用 `<image>` 的地方使用，例如在背景中。由于渐变是动态生成的，因此可以消除对传统用于实现类似效果的栅格图像文件的需求。此外，由于渐变是由浏览器生成的，因此在放大时看起来比栅格图像更好，并且可以动态调整大小。

我们将从线性渐变开始介绍，然后以线性渐变为例介绍所有渐变类型支持的功能，然后继续介绍径向渐变、锥形渐变和重复渐变。

使用线性渐变
------

线性渐变创建了一条沿直线前进的颜色带。

### 基础线性渐变

要创建最基本的渐变类型，你只需指定两种颜色即可。这些被称为色标（color stop）。至少指定两个色标，也可以指定任意数量。
```

<div class="simple-linear"></div>
```

```
div {
  width: 120px;
  height: 120px;
}
```

```css
.simple-linear {
  background: linear-gradient(blue, pink);
}
```

### 改变渐变方向

默认情况下，线性渐变的方向是从上到下，你可以指定一个值来改变渐变的方向。
```

<div class="horizontal-gradient"></div>
```

```
div {
  width: 120px;
  height: 120px;
}
```

```css
.horizontal-gradient {
  background: linear-gradient(to right, blue, pink);
}
```

### 对角线渐变

你甚至可以设置渐变方向为从一个对角到另一个对角。
```

<div class="diagonal-gradient"></div>
```

```
div {
  width: 200px;
  height: 100px;
}
```

```css
.diagonal-gradient {
  background: linear-gradient(to bottom right, blue, pink);
}
```

### 设置渐变角度

如果你想要更精确地控制渐变的方向，你可以给渐变设置一个具体的角度。
```

<div class="angled-gradient"></div>
```

```
div {
  width: 120px;
  height: 120px;
}
```

```css
.angled-gradient {
  background: linear-gradient(70deg, blue, pink);
}
```

在使用角度的时候，`0deg` 代表渐变方向为从下到上，`90deg` 代表渐变方向为从左到右，诸如此类正角度都属于顺时针方向。而负角度意味着逆时针方向。

![四个显示角度和相关渐变的盒子。0deg 从顶部到底部，90deg 从右到左，180deg 从底部到顶部，-90deg 从左到右](/zh-CN/docs/Web/CSS/CSS_images/Using_CSS_gradients/linear_red_angles.png)

声明颜色和创建效果
---------

所有的 CSS 渐变类型都是一个位置依赖的颜色范围。CSS 渐变产生的颜色可以随位置不断变化，从而产生平滑的颜色过渡。也可以创建纯色带和两种颜色之间的硬过渡。以下内容适用于所有渐变函数：

### 使用多种颜色

无需局限于使用两种颜色，你想使用多少种颜色都可以！默认情况下，所设置颜色会均匀分布在渐变路径中。
```

<div class="auto-spaced-linear-gradient"></div>
```

```
div {
  width: 120px;
  height: 120px;
}
```

```css
.auto-spaced-linear-gradient {
  background: linear-gradient(red, yellow, blue, orange);
}
```

### 色标位置

你不需要将你的色标设置在默认的位置。你可以为径向和线性渐变设置 0、1 或 2 个百分比值或者绝对长度值来调整它们的位置。如果你将位置设置为百分数，`0%` 表示起始点，而 `100%` 表示终点，但是如果需要的话你也可以设置这个范围之外的其他值来达到你想要的效果。如果有些位置你没有明确设置，那么将会自动计算，第一个色标在 `0%` 处，最后一个色标在 `100%`，其他的色标则位于其相邻的两个色标中间。
```

<div class="multicolor-linear"></div>
```

```
div {
  width: 120px;
  height: 120px;
}
```

```css
.multicolor-linear {
  background: linear-gradient(to left, lime 28px, red 77%, cyan);
}
```

### 创建硬线

要在两种颜色之间创建一条硬线，即创建一个条纹而不是逐渐过渡，可以将相邻的颜色停止设置为相同的位置。在此示例中，两种颜色在 `50%` 标记处共享一个颜色停止点，即渐变的一半：
```

<div class="striped"></div>
```

```
div {
  width: 120px;
  height: 120px;
}
```

```css
.striped {
  background: linear-gradient(to bottom left, cyan 50%, palegoldenrod 50%);
}
```

### 渐变提示

默认情况下，渐变会平滑地从一种颜色过渡到另一种颜色。你可以通过设置一个值来将渐变的中心点移动到指定位置。在如下示例中，我们将渐变的中心点由 50% 设为 10%。
```

<div class="color-hint"></div>
<div class="simple-linear"></div>
```

```
div {
  width: 120px;
  height: 120px;
  float: left;
  margin-right: 10px;
}
```

```css
.color-hint {
  background: linear-gradient(blue, 10%, pink);
}
.simple-linear {
  background: linear-gradient(blue, pink);
}
```

### 创建色带和条纹

要在渐变中包含一个实心、非过渡的颜色区域，请包含色标的两个位置。色标可以有两个位置，这相当于两个连续颜色在不同位置具有相同的色标。颜色将在第一个色标时达到完全饱和，保持该饱和度到第二个色标，并通过相邻色标的第一个位置过渡到相邻色标的颜色。
```

<div class="multiposition-stops"></div>
<div class="multiposition-stop2"></div>
```

```
div {
  width: 120px;
  height: 120px;
  float: left;
  margin-right: 10px;
  box-sizing: border-box;
}
```

```css
.multiposition-stops {
  background: linear-gradient(
    to left,
    lime 20%,
    red 30%,
    red 45%,
    cyan 55%,
    cyan 70%,
    yellow 80%
  );
  background: linear-gradient(
    to left,
    lime 20%,
    red 30% 45%,
    cyan 55% 70%,
    yellow 80%
  );
}
.multiposition-stop2 {
  background: linear-gradient(
    to left,
    lime 25%,
    red 25%,
    red 50%,
    cyan 50%,
    cyan 75%,
    yellow 75%
  );
  background: linear-gradient(
    to left,
    lime 25%,
    red 25% 50%,
    cyan 50% 75%,
    yellow 75%
  );
}
```

在上面的第一个例子中，黄绿色从 0% 的位置中开始（这是推断出来的），然后到 20% 的位置，在之后的渐变宽度的 10% 内，开始由黄绿色转换为红色，在 30% 的位置到达纯红色，然后一直保持为红色，直到渐变中的 45% 的位置，然后淡化到青色，这持续了渐变的 15% 的过程，然后然后继续。

在第二个例子中，每个颜色的第二个色标都是相邻颜色的第一个色标，创建一个条纹效果。

在这两个例子中，渐变都写了两次：第一个是 CSS Images Level 3 方法，可为每个色标重复颜色，第二个是 CSS Images Level 4 多个色标方法，在一个线性的色标声明中包含两个色标长度。

### 控制渐变的进程

默认情况下，渐变在两个相邻的色标之间都是均匀推进的，两个色标之间的中点是颜色值的中点。你可以控制两个色标之间的插值 (en-US)，或者过程，方法是添加一个颜色提示位置。在这个例子中，颜色在渐变过程的 20% 而不是 50% 的位置到达黄绿色和青色之间的中点。第二个例子没有提示，因此可以通过对比看出颜色提示的效果。
```

<div class="colorhint-gradient"></div>
<div class="regular-progression"></div>
```

```
div {
  width: 120px;
  height: 120px;
  float: left;
  margin-right: 10px;
  box-sizing: border-box;
}
```

```css
.colorhint-gradient {
  background: linear-gradient(to top, lime, 20%, cyan);
}
.regular-progression {
  background: linear-gradient(to top, lime, cyan);
}
```

### 叠加渐变

渐变支持透明度，所以你可以将多个背景叠加起来以实现一些非常好看的效果。背景是从顶部到底部堆叠的，指定的第一个就是顶部。
```

<div class="layered-image"></div>
```

```
div {
  width: 300px;
  height: 150px;
}
```

```css
.layered-image {
  background: linear-gradient(to right, transparent, mistyrose),
    url("critters.png");
}
```

### 堆叠渐变

你可以将渐变与其他的渐变堆叠起来。只要顶部的渐变不是完全不透明的，那么下面的渐变就会依然可见。
```

<div class="stacked-linear"></div>
```

```
div {
  width: 200px;
  height: 200px;
}
```

```css
.stacked-linear {
  background: linear-gradient(
      217deg,
      rgba(255, 0, 0, 0.8),
      rgba(255, 0, 0, 0) 70.71%
    ), linear-gradient(127deg, rgba(0, 255, 0, 0.8), rgba(0, 255, 0, 0) 70.71%),
    linear-gradient(336deg, rgba(0, 0, 255, 0.8), rgba(0, 0, 255, 0) 70.71%);
}
```

使用径向渐变
------

径向渐变类似于线性渐变，除了是从一个中心点向外辐射的。你可以指定中心点的位置。你还可以使其为圆形或者是椭圆形。

### 基本的径向渐变

和线性渐变一样，创建径向渐变所需要的就是两个颜色。默认情况下，渐变的中心点是 50% 50% 的位置，且渐变是椭圆的以匹配盒的比例。
```

<div class="simple-radial"></div>
```

```
div {
  width: 240px;
  height: 120px;
}
```

```css
.simple-radial {
  background: radial-gradient(red, blue);
}
```

### 设置径向色标的位置

和线性渐变一样，你可以用百分比或者绝对长度指定每个径向色标的位置。
```

<div class="radial-gradient"></div>
```

```
div {
  width: 120px;
  height: 120px;
}
```

```css
.radial-gradient {
  background: radial-gradient(red 10px, yellow 30%, #1e90ff 50%);
}
```

### 设置渐变的中心

你可以使用关键字、百分比或者绝对长度、长度和百分比值的重复（如果存在，否则就是从左侧位置和顶部位置开始的）以指定渐变的中心。
```

<div class="radial-gradient"></div>
```

```
div {
  width: 120px;
  height: 240px;
}
```

```css
.radial-gradient {
  background: radial-gradient(at 0% 30%, red 10px, yellow 30%, #1e90ff 50%);
}
```

### 设置径向渐变的大小

和线性渐变不同，你可以指定径向渐变的大小。可能的值包括 `closest-corner`、`closest-side`、`farthest-corner` 和 `farthest-side`，其中 `farthest-corner` 是默认值。圆的大小为长度，椭圆则是长度和百分比。

#### 示例：椭圆渐变的 closet-side 值

这个例子使用了 `closest-side` 大小值，意思就是大小是通过开始点（中心）和包围盒的最近一侧的距离设置的。
```

<div class="radial-ellipse-side"></div>
```

```
div {
  width: 240px;
  height: 100px;
}
```

```css
.radial-ellipse-side {
  background: radial-gradient(
    ellipse closest-side,
    red,
    yellow 10%,
    #1e90ff 50%,
    beige
  );
}
```

#### 示例：椭圆渐变的 farthest-corner 值

这个例子和前一个类似，但是其大小是以 `farthest-corner` 指定的，这会将渐变的大小设置为从开始点到包围盒的距离开始点的最远角的距离设置的。
```

<div class="radial-ellipse-far"></div>
```

```
div {
  width: 240px;
  height: 100px;
}
```

```css
.radial-ellipse-far {
  background: radial-gradient(
    ellipse farthest-corner at 90% 90%,
    red,
    yellow 10%,
    #1e90ff 50%,
    beige
  );
}
```

#### 示例：圆形渐变的 closet-side 值

这个例子使用了 `closest-side`，使得圆的半径是渐变中心到最近一侧的距离。在这个例子中，半径是中心到底部的距离，因为渐变位于左侧 25%、底部 25% 的位置，而 div 元素的高度小于宽度。
```

<div class="radial-circle-close"></div>
```

```
div {
  width: 240px;
  height: 120px;
}
```

```css
.radial-circle-close {
  background: radial-gradient(
    circle closest-side at 25% 75%,
    red,
    yellow 10%,
    #1e90ff 50%,
    beige
  );
}
```

#### 示例：椭圆形渐变长度或百分比

对于椭圆，你可以使用长度或者百分比来设置其大小，第一个值代表了水平半径，第二个值是竖直半径，你可以使用百分比以表示相对于盒在那个维度上的的大小的值。在下面这个例子中，我使用了百分比以表示水平半径。
```

<div class="radial-ellipse-size"></div>
```

```
div {
  width: 240px;
  height: 120px;
}
```

```css
.radial-ellipse-size {
  background: radial-gradient(
    ellipse 50% 50px,
    red,
    yellow 10%,
    #1e90ff 50%,
    beige
  );
}
```

#### 示例：圆形渐变的长度

对于圆，尺寸可以用 <length> 提供，这就是圆的尺寸。
```

<div class="radial-circle-size"></div>
```

```
div {
  width: 240px;
  height: 120px;
}
```

```css
.radial-circle-size {
  background: radial-gradient(circle 50px, red, yellow 10%, #1e90ff 50%, beige);
}
```

### 堆叠径向渐变

就像线性渐变一样，你也可以堆叠径向渐变。指定的第一个位于顶部，最后一个位于底部。
```

<div class="stacked-radial"></div>
```

```
div {
  width: 200px;
  height: 200px;
}
```

```css
.stacked-radial {
  background:
    radial-gradient(
      circle at 50% 0,
      rgba(255, 0, 0, 0.5),
      rgba(255, 0, 0, 0) 70.71%
    ),
    radial-gradient(
      circle at 6.7% 75%,
      rgba(0, 0, 255, 0.5),
      rgba(0, 0, 255, 0) 70.71%
    ),
    radial-gradient(
        circle at 93.3% 75%,
        rgba(0, 255, 0, 0.5),
        rgba(0, 255, 0, 0) 70.71%
      ) beige;
  border-radius: 50%;
}
```

使用锥形渐变
------

**`conic-gradient()`** CSS 函数创建包含颜色围绕中心点旋转（而不是从中心点辐射）产生的渐变的图像。锥形渐变的例子包括了饼图和色轮 (en-US)，但是也可以用于创建棋盘格和其他有趣的效果。

锥形渐变的语法和径向渐变的语法类似，但是色标是围绕渐变弧（圆的圆周）进行的，而不是从渐变中心出现的渐变线上，并且色标是百分比或度数：绝对长度无效。

在径向渐变中，颜色从椭圆中心的位置在各个方向上向外过渡。在锥形渐变中，颜色围绕圆的中心在圆周上旋转过渡，从顶部开始，顺时针进行。类似于径向渐变，你可以设置渐变的中心。类似于线性渐变，你可以改变渐变的角度。

### 基本的锥形渐变

和线性和径向的渐变类似，创建锥形渐变所需要的就是两个颜色。默认情况下，渐变的中心位于 50% 50% 的位置，渐变的开始点是朝上的。
```

<div class="simple-conic"></div>
```

```
div {
  width: 120px;
  height: 120px;
}
```

```css
.simple-conic {
  background: conic-gradient(red, blue);
}
```

### 设置锥形渐变的位置

和锥形渐变类似，你可以使用关键词、百分比或者绝对长度，以及关键字“at”来设置锥形渐变的中心位置。
```

<div class="conic-gradient"></div>
```

```
div {
  width: 120px;
  height: 120px;
}
```

```css
.conic-gradient {
  background: conic-gradient(at 0% 30%, red 10%, yellow 30%, #1e90ff 50%);
}
```

### 改变角度

默认情况下，你指定的不同色标是围绕着圆均等分布的。你可以在开始时使用“from”关键字以及一个角度或者长度以指定锥形渐变的起始点，然后你可以在后面包括角度或者长度以指定不同的位置。
```

<div class="conic-gradient"></div>
```

```
div {
  width: 120px;
  height: 120px;
}
```

```css
.conic-gradient {
  background: conic-gradient(from 45deg, red, orange 50%, yellow 85%, green);
}
```

使用重复渐变
------

`linear-gradient()`、`radial-gradient()` 和 `conic-gradient()` 函数不支持自动重复的色标。但是，`repeating-linear-gradient()`、`repeating-radial-gradient()` 和 `repeating-conic-gradient()` (en-US) 函数可以用于提供此功能。

重复渐变线或弧的大小，是第一个色标和最后一个色标之间的长度。如果第一个色标只有颜色没有色标长度，那么值默认为 0。如果最后一个色标只有颜色没有色标长度，那么值默认为 100%。如果都没有指定，那么渐变线是 100%，意味着线性和锥形的渐变都不会重复，径向渐变只会在渐变的半径小于中心点和最远角之间的距离时重复。如果第一个色标声明了，其值大于 0，渐变也会重复，因为线或弧的大小就是第一个色标和最后一个色标之间的距离，小于 100% 或 360 度。

### 重复的线性渐变

这个例子使用了 `repeating-linear-gradient()` 以创建一个沿着直线重复推进的渐变。随渐变进行，颜色会重复循环。在这个例子中，渐变线的长度为 10px。
```

<div class="repeating-linear"></div>
```

```
div {
  width: 120px;
  height: 120px;
}
```

```css
.repeating-linear {
  background: repeating-linear-gradient(
    -45deg,
    red,
    red 5px,
    blue 5px,
    blue 10px
  );
}
```

### 多个线性渐变

和常规的线性和径向渐变类似，你可以包含多个渐变，一个在另一个的顶部。这只有在渐变部分透明时有效，以允许的后续的渐变穿透透明区域显示，或者你为每个渐变图像指定不同的 background-size，还可以有不同的 background-position 属性值。我们使用透明。

在这个例子中，渐变线的长度为 300px、230px 和 300px。
```

<div class="multi-repeating-linear"></div>
```

```
div {
  width: 600px;
  height: 400px;
}
```

```css
.multi-repeating-linear {
  background: repeating-linear-gradient(
      190deg,
      rgba(255, 0, 0, 0.5) 40px,
      rgba(255, 153, 0, 0.5) 80px,
      rgba(255, 255, 0, 0.5) 120px,
      rgba(0, 255, 0, 0.5) 160px,
      rgba(0, 0, 255, 0.5) 200px,
      rgba(75, 0, 130, 0.5) 240px,
      rgba(238, 130, 238, 0.5) 280px,
      rgba(255, 0, 0, 0.5) 300px
    ), repeating-linear-gradient(
      -190deg,
      rgba(255, 0, 0, 0.5) 30px,
      rgba(255, 153, 0, 0.5) 60px,
      rgba(255, 255, 0, 0.5) 90px,
      rgba(0, 255, 0, 0.5) 120px,
      rgba(0, 0, 255, 0.5) 150px,
      rgba(75, 0, 130, 0.5) 180px,
      rgba(238, 130, 238, 0.5) 210px,
      rgba(255, 0, 0, 0.5) 230px
    ), repeating-linear-gradient(23deg, red 50px, orange 100px, yellow 150px, green
        200px, blue 250px, indigo 300px, violet 350px, red 370px);
}
```

### 格纹渐变

要创建格纹，我们使用了几个重叠的带有透明的渐变。在第一个背景声明中，我们分别列举出了每个色标。第二个背景属性声明使用了色标的多个位置的语法：
```

<div class="plaid-gradient"></div>
```

```
div {
  width: 200px;
  height: 200px;
}
```

```css
.plaid-gradient {
  background: repeating-linear-gradient(
      90deg,
      transparent,
      transparent 50px,
      rgba(255, 127, 0, 0.25) 50px,
      rgba(255, 127, 0, 0.25) 56px,
      transparent 56px,
      transparent 63px,
      rgba(255, 127, 0, 0.25) 63px,
      rgba(255, 127, 0, 0.25) 69px,
      transparent 69px,
      transparent 116px,
      rgba(255, 206, 0, 0.25) 116px,
      rgba(255, 206, 0, 0.25) 166px
    ), repeating-linear-gradient(
      0deg,
      transparent,
      transparent 50px,
      rgba(255, 127, 0, 0.25) 50px,
      rgba(255, 127, 0, 0.25) 56px,
      transparent 56px,
      transparent 63px,
      rgba(255, 127, 0, 0.25) 63px,
      rgba(255, 127, 0, 0.25) 69px,
      transparent 69px,
      transparent 116px,
      rgba(255, 206, 0, 0.25) 116px,
      rgba(255, 206, 0, 0.25) 166px
    ), repeating-linear-gradient(
      -45deg,
      transparent,
      transparent 5px,
      rgba(143, 77, 63, 0.25) 5px,
      rgba(143, 77, 63, 0.25) 10px
    ), repeating-linear-gradient(45deg, transparent, transparent 5px, rgba(
          143,
          77,
          63,
          0.25
        ) 5px, rgba(143, 77, 63, 0.25) 10px);

  background: repeating-linear-gradient(
      90deg,
      transparent 0 50px,
      rgba(255, 127, 0, 0.25) 50px 56px,
      transparent 56px 63px,
      rgba(255, 127, 0, 0.25) 63px 69px,
      transparent 69px 116px,
      rgba(255, 206, 0, 0.25) 116px 166px
    ), repeating-linear-gradient(
      0deg,
      transparent 0 50px,
      rgba(255, 127, 0, 0.25) 50px 56px,
      transparent 56px 63px,
      rgba(255, 127, 0, 0.25) 63px 69px,
      transparent 69px 116px,
      rgba(255, 206, 0, 0.25) 116px 166px
    ), repeating-linear-gradient(
      -45deg,
      transparent 0 5px,
      rgba(143, 77, 63, 0.25) 5px 10px
    ), repeating-linear-gradient(45deg, transparent 0 5px, rgba(
          143,
          77,
          63,
          0.25
        ) 5px 10px);
}
```

### 重复的径向渐变

这个例子使用了 `repeating-radial-gradient()` 以创建从中心点重复向外辐射的渐变。颜色会随渐变重复而循环。
```

<div class="repeating-radial"></div>
```

```
div {
  width: 120px;
  height: 120px;
}
```

```css
.repeating-radial {
  background: repeating-radial-gradient(
    black,
    black 5px,
    white 5px,
    white 10px
  );
}
```

### 多个重复的径向渐变
```

<div class="multi-target"></div>
```

```
div {
  width: 250px;
  height: 150px;
}
```

```css
.multi-target {
  background:
    repeating-radial-gradient(
        ellipse at 80% 50%,
        rgba(0, 0, 0, 0.5),
        rgba(0, 0, 0, 0.5) 15px,
        rgba(255, 255, 255, 0.5) 15px,
        rgba(255, 255, 255, 0.5) 30px
      ) top left no-repeat,
    repeating-radial-gradient(
        ellipse at 20% 50%,
        rgba(0, 0, 0, 0.5),
        rgba(0, 0, 0, 0.5) 10px,
        rgba(255, 255, 255, 0.5) 10px,
        rgba(255, 255, 255, 0.5) 20px
      ) top left no-repeat yellow;
  background-size:
    200px 200px,
    150px 150px;
}
```

参见
--

* 渐变函数：`linear-gradient()`、`radial-gradient()`、`conic-gradient()`、`repeating-linear-gradient()`、`repeating-radial-gradient()`、`repeating-conic-gradient()` (en-US)
* 和渐变有关的 CSS 数据类型：`<gradient>`、`<image>`
* 和渐变有关的 CSS 属性：`background`、`background-image`
* CSS 渐变纹样图集，作者 Lea Verou
* CSS 渐变库，作者 Estelle Weyl
* 渐变 CSS 生成器


滚动吸附的基本概念 - CSS：层叠样式表

滚动吸附的基本概念
=========

CSS 滚动吸附模块中的属性可以定义用户在滚动文档时滚动吸附到指定点的方式。

滚动吸附特性可以定义吸附位置。滚动容器的滚动口在完成滚动操作后可能会停在或“吸附到”这些位置。

CSS 滚动吸附的关键属性
-------------

在定义滚动吸附前，需要在滚动容器上启用滚动。通过确保滚动容器指定了尺寸且启用 `overflow` 可启用滚动。

然后可以在滚动容器上使用下列关键属性定义滚动吸附：

* `scroll-snap-type`——使用这个属性可定义滚动式视口是否可被吸附、必须还是可选吸附以及吸附应当出现在哪些轴上。
* `scroll-snap-align`——这个属性设置在滚动容器的每个子元素上，可用于定义每个子元素的吸附位置或没有吸附位置。
* `scroll-snap-stop`——这个属性确保在滚动中吸附到而不是越过某个子元素。
* `scroll-margin`——这个属性可以设置在在滚动中可以被吸附的子元素上，用于在指定盒子上创建吸附外边距。
* `scroll-padding`——这个属性可以设置在滚动容器上，用于创建吸附偏移。

下列示例演示了由 `scroll-snap-type` 所定义的纵轴方向的滚动吸附。此外，`scroll-snap-align` 被应用于 `<section>` 元素的所有子元素，决定了每个子元素的滚动止点。

使用 scroll-snap-type
-------------------

`scroll-snap-type` 属性需要知道在哪个方向上有滚动吸附。方向可以是 `x`、`y` 或者逻辑对应关系 `block`、`inline`。还可以用关键字 `both` 使两个轴都有滚动吸附。

你还可以传入关键字 `mandatory` 或 `proximity`。关键字 `mandatory` 告诉浏览器无论滚动到哪个位置，内容都*必须*吸附到特定的点，而关键字 `proximity` 意味着内容可以吸附而不是必须吸附到点上。

使用 `mandatory` 可以创造非常一致的滚动效果——你知道浏览器总会吸附到每个指定的点。这意味着有把握相信在滚动结束时，你希望出现在屏幕顶部的东西就会出现在那里。然而，如果内容比预想的大，那么会产生问题——用户可能会沮丧地发现他们永远无法滚动并查看内容中特定的某处。因此，使用 `mandatory` 应当仔细考虑，而且只用于你知道屏幕上或滚动式区域在任何时刻有多少内容的情形。

**备注：** 如果某个子元素的内容会溢出父容器，那么请务必不要使用 `mandatory`，这是因为用户会无法把溢出内容滚入视野。

`proximity` 值只在子元素靠近某个位置时把它吸附到这个位置，具体的距离由浏览器决定。

在下列示例中，可以在 `mandatory` 和 `proximity` 之间改变取值，看看对滚动产生的效果。

在上述示例中的滚动容器上同时设置了 `height: 300px;` 和 `overflow-y: scroll;`。

如果内容没有溢出容器，那么没有用于滚动的内容。

使用 scroll-snap-align
--------------------

`scroll-snap-align` 属性的有效值包括 `start`、`end`、`center` 和 `none`。这些值用于标示内容应当吸附到滚动容器中的哪个点。在下列示例中，可以改变 `scroll-snap-align` 的值，看看滚动行为如何变化。

如果 `scroll-snap-type` 是 `mandatory` 而且某个子元素上的 `scroll-snap-align` 被设置为 `none` 或者未被设置（此时默认为 `none`），那么用户会无法把这个元素滚入视野。

使用 scroll-padding
-----------------

如果你在使用 `start` 或 `end` 时不想将内容恰好吸附到滚动容器的边上，或者在使用 `center` 时想让吸附位置略微偏离中心，请使用 `scroll-padding` 属性或者等价的全称属性添加一点内边距。

在下列示例中，`scroll-padding` 被设置为 `40px`。当内容吸附到第二和第三节的开头时，滚动会停在离章节开头 40 像素远的位置。试试改变 `scroll-padding` 的值，看看距离如何变化。

如果有像导航栏这种可能遮盖滚动内容的固定元素，那么这个属性可以派上用场。使用 `scroll-padding` 可以为固定元素留出空间。例如在下列示例中，当内容在 `<h1>` 元素下方滚动时，`<h1>` 在屏幕上保持不动。如果没有内边距，那么在发生吸附时，标题会遮盖一些内容。

使用 scroll-margin
----------------

在子元素上可以设置 `scroll-margin` 属性或者全称滚动外边距值，用于定义指定盒子的外边距。这可以让不同的子元素有不同大小的空间，而且可以和父元素上的 `scroll-padding` 一起使用。在下列示例中尝试一下。

使用 scroll-snap-stop
-------------------

使用 `scroll-snap-stop` 属性可以指定滚动是否必须吸附到指定的吸附点。在上述示例中，这意味着滚动究竟是会停在每个章节的开头还是可以跳过章节。

这个属性可以确保用户看见滚动区域的每个章节而不会不小心滚过章节。然而这个设置会阻止用户快速滚动到想要的内容，因而对用户体验产生负面影响。

参见
--

* CSS 滚动吸附模块
* 用 CSS 滚动吸附明确控制滚动（载于 web.dev，2021 年）
* 实用 CSS 滚动吸附（载于 CSS-Tricks，2020 年）
* CSS 滚动吸附（载于 12 Days of Web，2019 年）
* 滚动吸附示例（载于 Codepen）


blur() - CSS：层叠样式表

blur()
======

**`blur()`** CSS 方法将高斯模糊应用于输出图片。结果为 `<filter-function>`.

尝试一下
----

语法
--
```

blur(radius)
```

### 值

`radius`

模糊的半径，值为`<length>`。它定义了高斯函数的标准偏差值，即屏幕上有多少像素相互融合; 因此，较大的值会产生更多模糊。值为 0 会使输入保持不变。该值为空则为 0。

示例
--

```css
blur(0)        /\* No effect \*/
blur(8px)      /\* Blur with 8px radius \*/
blur(1.17rem)  /\* Blur with 1.17rem radius \*/
```

参见
--

* `<filter-function>`
* `brightness()`
* `contrast()`
* `drop-shadow()`
* `grayscale()`
* `hue-rotate()` (en-US)
* `invert()` (en-US)
* `opacity()`
* `saturate()` (en-US)
* `sepia()` (en-US)


grayscale() - CSS：层叠样式表

grayscale()
===========

**`grayscale()`** : 对图片进行灰度转换，它是 `<filter-function>` 的子属性。

尝试一下
----

语法
--
```

grayscale(amount)
```

### 参数

`amount`

转换值的大小，可以是`<number>` 或 `<percentage>`. 当值为 100% 时，灰度最大。0% 时与原图没有区别。0% 到 100% 之间的值会使灰度线性变化。amount 为空时使用值为`1`.

例子
--

```css
grayscale(0)     /\* 无效果 \*/
grayscale(.7)    /\* 70% 灰度 \*/
grayscale(100%)  /\* 灰度最大 \*/
```

更多
--

* `<filter-function>`


contrast() - CSS：层叠样式表

contrast()
==========

**`contrast()`** CSS 函数调整输入图像的对比度。结果是一个 `<filter-function>`.

尝试一下
----

语法
--
```

contrast(amount)
```

### 参数

`amount`

输出的对比度取决于 `<number>`或者`<percentage>`的大小。低于 `100%` 的值会降低对比度，高于 `100%` 的值会增加对比度。值为 `0%` 将创建完全灰色的图像，值为 `100%` 时不会有任何变化。该值为空时默认为 `1`.

例子
--

```css
contrast(0)     /\* 完全灰色 \*/
contrast(65%)   /\* 65% 对比度 \*/
contrast(1)     /\* 无效果 \*/
contrast(200%)  /\* 两倍对比度 \*/
```

参见
--

* `<filter-function>`
* `blur()`
* `brightness()`
* `drop-shadow()`
* `grayscale()`
* `hue-rotate()` (en-US)
* `invert()` (en-US)
* `opacity()`
* `saturate()` (en-US)
* `sepia()` (en-US)


opacity() - CSS：层叠样式表

opacity()
=========

The **`opacity()`** CSS 函数在输入的图片实例上应用透明度属性，它的结果是一个 `<filter-function>`.

尝试一下
----

**备注：** 这个函数与其他既有的`opacity`属性类似，区别在于有了 filters，有些浏览器会提供硬件加速以获取更好的性能表现。

语法
--
```

opacity(amount)
```

### 参数

`amount`

转化的数值，要求是一个 `<number>` 或一个 `<percentage>`（百分比）。值为 `0%` 是完全透明的，值为 100% 会保留原来的效果。值在 0% 与 100% 之间效果为线性变化的，参数的最小差值为 1。

Examples
--------

```css
opacity(0%)   /\* 完全透明\*/
opacity(50%)  /\* 50% 透明 \*/
opacity(1)    /\* 无效果 \*/
```

See also
--------

* `<filter-function>`
* CSS `opacity` property


brightness() - CSS：层叠样式表

brightness()
============

**`brightness()`** CSS函数将线性乘数应用于输入图像，使其看起来更亮或更暗。结果是一个`<filter-function>`.

尝试一下
----

语法
--
```

brightness(amount)
```

### 值

`amount`

输出的亮度值取决于`<number>`或`<percentage>`的大小。低于`100%` 的值会使图片变暗，超过`100%`的值将会使其变亮。当值为`0%`时将会创建一个全黑的图像，当值为`100%`时不会有任何变化。该值为空时默认为`1`.

例子
--

```css
brightness(0%)   /\* 全黑 \*/
brightness(0.4)  /\* 40% 亮度 \*/
brightness(1)    /\* 无效果 \*/
brightness(200%) /\* 两倍亮度 \*/
```

参见
--

* `<filter-function>`


drop-shadow() - CSS：层叠样式表

drop-shadow()
=============

The **`drop-shadow()`** CSS function applies a drop shadow effect to the input image. Its result is a `<filter-function>`.

尝试一下
----

投影实际上是输入图像的 alpha 蒙版的一个模糊的、偏移的版本，用特定的颜色绘制并合成在图像下面。

**备注：** 这个函数有点类似于 `box-shadow` 属性。`box-shadow` 属性在元素的整个框后面创建一个矩形阴影，而 `drop-shadow()` 过滤器则是创建一个符合图像本身形状 (alpha 通道) 的阴影。

Syntax
------
```

drop-shadow(offset-x offset-y blur-radius spread-radius color)
```

The `drop-shadow()` function accepts a parameter of type `<shadow>` (defined in the `box-shadow` property), with the exception that the `inset` keyword is not allowed.

### Parameters

`offset-x` `offset-y` (required)

`offset-x`指定水平距离，其中负值将阴影放置到元素的左侧。`offset-y`指定垂直距离，其中负值将阴影置于元素之上。如果两个值都为 `0`，则阴影直接放置在元素后面。

`blur-radius` (optional)

阴影的模糊半径，指定为 `<length>`。值越大，阴影就越大，也越模糊。如果未指定，则默认为 `0`，从而产生清晰、不模糊的边缘。不允许有负值。

`spread-radius` (optional)

阴影的扩展半径，指定为 `<length>`. 正的值会导致阴影扩大和变大，而负的值会导致阴影缩小。如果未指定，则默认为 0，阴影的大小将与输入图像相同。

**警告：** 大多数浏览器不支持这个参数;如果使用，效果将不会呈现。截止 2020 年 10,14 日，Chrome v.85.0.4183.121（正式版本）,Microsoft Edge Beta v85.0.564.63(64 位), Firefox v.85.0.564.63 暂未支持

`color` (optional)

阴影的颜色，指定为 `<color>`。如果未指定，则使用 `color` 属性的值。

Examples
--------

```css
/\* Black shadow with 10px blur \*/
drop-shadow(16px 16px 10px black)

/\* Reddish shadow with 1rem blur and .3rem spread \*/
/\* WARNING: not generally supported by browsers \*/
drop-shadow(.5rem .5rem 1rem .3rem #e23)
```

See also
--------

* `<filter-function>`
* CSS `box-shadow` property
* `blur()`
* `brightness()`
* `contrast()`
* `grayscale()`
* `hue-rotate()` (en-US)
* `invert()` (en-US)
* `opacity()`
* `saturate()` (en-US)
* `sepia()` (en-US)


掌握外边距折叠 - CSS：层叠样式表

掌握外边距折叠
=======

区块的上下外边距有时会合并（折叠）为单个边距，其大小为两个边距中的最大值（或如果它们相等，则仅为其中一个），这种行为称为**外边距折叠**。注意：有设定浮动和绝对定位的元素不会发生外边距折叠。

有三种情况会形成外边距折叠：

相邻的兄弟元素

相邻的同级元素之间的外边距会被折叠（除非后面的元素需要清除之前的浮动）。

没有内容将父元素和后代元素分开

如果没有设定边框（border）、内边距（padding）、行级（inline）内容，也没有创建区块格式化上下文或*间隙*来分隔块级元素的上边距（`margin-top`）与其内一个或多个子代块级元素的上边距（`margin-top`）；或者没有设定边框、内边距、行级内容、高度（`height`）或最小高度（`min-height`）来分隔块级元素的下边距（`margin-bottom`）与其内部的一个或多个后代后代块元素的下边距（`margin-bottom`），则会出现这些外边距的折叠，重叠部分最终会溢出到父代元素的外面。

空的区块

如果块级元素没有设定边框、内边距、行级内容、高度（`height`）、最小高度（`min-height`）来分隔块级元素的上边距（`margin-top`）及其下边距（`margin-bottom`），则会出现其上下外边距的折叠。

一些需要注意的地方：

* 上述情况的组合会产生更复杂的（超过两个外边距的）外边距折叠。
* 即使某一外边距为 0，这些规则仍然适用。因此就算父元素的外边距是 0，第一个或最后一个子元素的外边距仍然会（根据上述规则）“溢出”到父元素的外面。
* 如果包含负边距，折叠后的外边距的值为最大的正边距与最小（绝对值最大）的负边距的和。
* 如果所有的外边距都为负值，折叠后的外边距的值为最小（绝对值最大）的负边距的值。这一规则适用于相邻元素和嵌套元素。
* 外边距折叠仅与垂直方向有关。
* `display` 设置为 `flex` 或 `grid` 的容器中不会发生外边距折叠。
示例
--

### HTML

```html
<p>这一段落的下边距与…</p>
<p>
  … 这一段落的上边距被折叠了，在两者之间产生了一个
  <code>1.2rem</code> 的边距。
</p>

<div>
  这个父元素包含两个段落！
  <p>该段落与上面的文本之间有一个 <code>.4rem</code> 的边距。</p>
  <p>我的下边距与我的父元素折叠，产生了一个 <code>2rem</code> 的边距。</p>
</div>

<p>我在上面元素的下方 <code>2rem</code> 处。</p>
```

### CSS

```css
div {
  margin: 2rem 0;
  background: lavender;
}

p {
  margin: 0.4rem 0 1.2rem 0;
  background: yellow;
}
```

### 结果

参见
--

* CSS 关键概念：
    + CSS 语法
    + At 规则
    + 注释
    + 优先级
    + 继承
    + 盒模型
    + 布局模式
    + 视觉格式化模型
    + 值
        - 初始值
        - 计算值
        - 应用值
        - 实际值
    + 属性值定义语法
    + 简写属性
    + 可替换元素


CSS 基础框盒模型介绍 - CSS：层叠样式表

CSS 基础框盒模型介绍
============

当对一个文档进行布局（lay out）的时候，浏览器的渲染引擎会根据标准之一的 **CSS 基础框盒模型**（**CSS basic box model**），将所有元素表示为一个个矩形的盒子（box）。CSS 决定这些盒子的大小、位置以及属性（例如颜色、背景、边框尺寸…）。

每个盒子由四个部分（或称*区域*）组成，其效用由它们各自的边界（Edge）所定义（原文：defined by their respective edges，可能意指容纳、包含、限制等）。如图，与盒子的四个组成区域相对应，每个盒子有四个边界：*内容边界* *Content edge*、*内边距边界* *Padding Edge*、*边框边界* *Border Edge*、*外边框边界* *Margin Edge*。

![CSS 盒模型](/zh-CN/docs/Web/CSS/CSS_box_model/Introduction_to_the_CSS_box_model/boxmodel.png)

内容区域
----

**内容区域**（content area）由内容边界限制，容纳着元素的“真实”内容，例如文本、图像，或是一个视频播放器。它的尺寸为内容宽度（或称 *content-box 宽度*）和内容高度（或称 *content-box 高度*）。它通常含有一个背景颜色（默认颜色为透明）或背景图像。

如果 `box-sizing` 为 `content-box`（默认），则内容区域的大小可明确地通过 `width`、`min-width`、`max-width`、`height`、`min-height` 和 `max-height` 控制。

内边距区域
-----

**内边距区域**（padding area）由内边距边界限制，扩展自内容区域，负责延伸内容区域的背景，填充元素中内容与边框的间距。它的尺寸是 *padding-box 宽度* 和 *padding-box 高度*。

内边距的粗细可以由 `padding-top`、`padding-right`、`padding-bottom`、`padding-left`，和简写属性 `padding` 控制。

边框区域
----

**边框区域**（border area）由边框边界限制，扩展自内边距区域，是容纳边框的区域。其尺寸为 *border-box 宽度*和 *border-box 高度*。

边框的粗细由 `border-width` 和简写的 `border` 属性控制。如果 `box-sizing` 属性被设为 `border-box`，那么边框区域的大小可明确地通过 `width`、`min-width`, `max-width`、`height`、`min-height`，和 `max-height` 属性控制。假如框盒上设有背景（`background-color` 或 `background-image`），背景将会一直延伸至边框的外沿（默认为在边框下层延伸，边框会盖在背景上）。此默认表现可通过 CSS 属性 `background-clip` 来改变。

外边距区域
-----

**外边距区域**（margin area）由外边距边界限制，用空白区域扩展边框区域，以分开相邻的元素。它的尺寸为 *margin-box 宽度*和 *margin-box 高度*。

外边距区域的大小由 `margin-top`、`margin-right`、`margin-bottom`、`margin-left`，和简写属性 `margin` 控制。在发生外边距合并的情况下，由于盒之间共享外边距，外边距不容易弄清楚。

最后，请注意，除可替换元素外，对于行内元素来说，尽管内容周围存在内边距与边框，但其占用空间（每一行文字的高度）则由 `line-height` 属性决定，即使边框和内边距仍会显示在内容周围。

参见
--

* 布局与包含块
* CSS 层叠介绍
* 层叠和继承
* CSS 重要概念：
    + CSS 语法
    + @ 规则
    + 注释
    + 优先级
    + 继承
    + 盒模型
    + 布局模式
    + 视觉格式化模型
    + 外边距合并
    + 值
        - 初始值
        - 计算值
        - 解析值
        - 指定值
        - 应用值
        - 实际值
    + 属性值定义语法
    + 简写属性
    + 可替换元素


使用 CSS 变换 - CSS：层叠样式表

使用 CSS 变换
=========

通过改变坐标空间，**CSS 变换**（CSS transform）可以在不影响正常文档流的情况下改变作用内容的位置。这篇指南提供了有关使用 CSS 变换的介绍。

CSS 变换通过一系列 CSS 属性实现，通过使用这些属性，可以对 HTML 元素进行线性仿射变换（affine linear transformation）。可以进行的变换包括旋转、倾斜、缩放以及位移，这些变换同时适用于平面与三维空间。

**警告：** 只有使用盒模型（Box Model）来定位的元素可以*被变换*（`transform`ed）。拥有 `display: block` 的元素是由盒模型定位的。

CSS 变换属性
--------

有两个主要的属性被用来定义 CSS 变换：`transform`（或单独的 `translate`、`rotate` 以及 `scale` 属性）和 `transform-origin`。

`transform-origin`

指定原点的位置。默认值为元素的中心，可以被移动。很多变换需要用到这个属性，比如旋转、缩放和倾斜，它们都需要一个指定的点作为参数。

`transform`

指定作用在元素上的变换。取值为空格分隔的一系列变换的列表，它们会像被组合操作请求一样被分别执行。复合变换按从右到左的顺序高效地应用。

示例
--

这是一个未经任何变换的 MDN 标志：

![MDN Logo](/zh-CN/docs/Web/CSS/CSS_transforms/Using_CSS_transforms/logo.png)

### 旋转

这是从左下角开始旋转 90 度后的 MDN 徽标。

```html
<img
 style="rotate: 90deg;
 transform-origin: bottom left;"
 src="logo.png"
 alt="MDN Logo" />
```

### 倾斜与位移

还是 MDN 的标志，倾斜了 10 度，并从 X 轴位移了 150 个像素。

```html
<img
 style="transform: skewx(10deg) translatex(150px);
 transform-origin: bottom left;"
 src="logo.png"
 alt="MDN logo" />
```

适用于三维的属性
--------

在三维空间中使用 CSS 变换会稍微复杂一点。你必须先设置一个透视点（perspective）以便配置 3D 空间，再去定义 2D 元素在空间中的行为。

### 透视

首先需要设置的属性是透视值（`perspective`）。透视正是三维空间的立体感的源泉。元素与观察者之间的距离越远，它们就越小。

#### 设定 perspective

该实例展示了一个以不同的位置进行透视的立方体。立方体收缩的的速度由 `perspective` 属性定义。其值越小，视角越深。

##### HTML

下面的 HTML 创建了同一个框的四个副本，设定不同的透视值。

```html
<table>
  <tbody>
    <tr>
      <th><code>perspective: 250px;</code></th>
      <th><code>perspective: 350px;</code></th>
    </tr>
    <tr>
      <td>
        <div class="container">
          <div class="cube pers250">
            <div class="face front">1</div>
            <div class="face back">2</div>
            <div class="face right">3</div>
            <div class="face left">4</div>
            <div class="face top">5</div>
            <div class="face bottom">6</div>
          </div>
        </div>
      </td>
      <td>
        <div class="container">
          <div class="cube pers350">
            <div class="face front">1</div>
            <div class="face back">2</div>
            <div class="face right">3</div>
            <div class="face left">4</div>
            <div class="face top">5</div>
            <div class="face bottom">6</div>
          </div>
        </div>
      </td>
    </tr>
    <tr>
      <th><code>perspective: 500px;</code></th>
      <th><code>perspective: 650px;</code></th>
    </tr>
    <tr>
      <td>
        <div class="container">
          <div class="cube pers500">
            <div class="face front">1</div>
            <div class="face back">2</div>
            <div class="face right">3</div>
            <div class="face left">4</div>
            <div class="face top">5</div>
            <div class="face bottom">6</div>
          </div>
        </div>
      </td>
      <td>
        <div class="container">
          <div class="cube pers650">
            <div class="face front">1</div>
            <div class="face back">2</div>
            <div class="face right">3</div>
            <div class="face left">4</div>
            <div class="face top">5</div>
            <div class="face bottom">6</div>
          </div>
        </div>
      </td>
    </tr>
  </tbody>
</table>
```

##### CSS

CSS 设定了可用于将透视值设定为不同距离的类。它还包括容器和与立方体本身（以及它的每一个面）的类。

```css
/\* Shorthand classes for different perspective values \*/
.pers250 {
  perspective: 250px;
}

.pers350 {
  perspective: 350px;
}

.pers500 {
  perspective: 500px;
}

.pers650 {
  perspective: 650px;
}

/\* Define the container div, the cube div, and a generic face \*/
.container {
  width: 200px;
  height: 200px;
  margin: 75px 0 0 75px;
  border: none;
}

.cube {
  width: 100%;
  height: 100%;
  backface-visibility: visible;
  perspective-origin: 150% 150%;
  transform-style: preserve-3d;
}

.face {
  display: block;
  position: absolute;
  width: 100px;
  height: 100px;
  border: none;
  line-height: 100px;
  font-family: sans-serif;
  font-size: 60px;
  color: white;
  text-align: center;
}

/\* Define each face based on direction \*/
.front {
  background: rgba(0, 0, 0, 0.3);
  transform: translateZ(50px);
}

.back {
  background: rgba(0, 255, 0, 1);
  color: black;
  transform: rotateY(180deg) translateZ(50px);
}

.right {
  background: rgba(196, 0, 0, 0.7);
  transform: rotateY(90deg) translateZ(50px);
}

.left {
  background: rgba(0, 0, 196, 0.7);
  transform: rotateY(-90deg) translateZ(50px);
}

.top {
  background: rgba(196, 196, 0, 0.7);
  transform: rotateX(90deg) translateZ(50px);
}

.bottom {
  background: rgba(196, 0, 196, 0.7);
  transform: rotateX(-90deg) translateZ(50px);
}

/\* Make the table a little nicer \*/
th,
p,
td {
  background-color: #eeeeee;
  padding: 10px;
  font-family: sans-serif;
  text-align: left;
}
```

##### 结果

要配置的第二个元素是观察者（viewer）的位置，带有 `perspective-origin` 属性。默认情况下，视角以观察者为中心，但这并不总是足够的。

#### 改变透视原点

该实例展示了带有流行的 `perspective-origin` 值的立方体。

##### HTML

```html
<section>
  <figure>
    <figcaption><code>perspective-origin: top left;</code></figcaption>
    <div class="container">
      <div class="cube potl">
        <div class="face front">1</div>
        <div class="face back">2</div>
        <div class="face right">3</div>
        <div class="face left">4</div>
        <div class="face top">5</div>
        <div class="face bottom">6</div>
      </div>
    </div>
  </figure>

  <figure>
    <figcaption><code>perspective-origin: top;</code></figcaption>
    <div class="container">
      <div class="cube potm">
        <div class="face front">1</div>
        <div class="face back">2</div>
        <div class="face right">3</div>
        <div class="face left">4</div>
        <div class="face top">5</div>
        <div class="face bottom">6</div>
      </div>
    </div>
  </figure>

  <figure>
    <figcaption><code>perspective-origin: top right;</code></figcaption>
    <div class="container">
      <div class="cube potr">
        <div class="face front">1</div>
        <div class="face back">2</div>
        <div class="face right">3</div>
        <div class="face left">4</div>
        <div class="face top">5</div>
        <div class="face bottom">6</div>
      </div>
    </div>
  </figure>

  <figure>
    <figcaption><code>perspective-origin: left;</code></figcaption>
    <div class="container">
      <div class="cube poml">
        <div class="face front">1</div>
        <div class="face back">2</div>
        <div class="face right">3</div>
        <div class="face left">4</div>
        <div class="face top">5</div>
        <div class="face bottom">6</div>
      </div>
    </div>
  </figure>

  <figure>
    <figcaption><code>perspective-origin: 50% 50%;</code></figcaption>
    <div class="container">
      <div class="cube pomm">
        <div class="face front">1</div>
        <div class="face back">2</div>
        <div class="face right">3</div>
        <div class="face left">4</div>
        <div class="face top">5</div>
        <div class="face bottom">6</div>
      </div>
    </div>
  </figure>

  <figure>
    <figcaption><code>perspective-origin: right;</code></figcaption>
    <div class="container">
      <div class="cube pomr">
        <div class="face front">1</div>
        <div class="face back">2</div>
        <div class="face right">3</div>
        <div class="face left">4</div>
        <div class="face top">5</div>
        <div class="face bottom">6</div>
      </div>
    </div>
  </figure>

  <figure>
    <figcaption><code>perspective-origin: bottom left;</code></figcaption>
    <div class="container">
      <div class="cube pobl">
        <div class="face front">1</div>
        <div class="face back">2</div>
        <div class="face right">3</div>
        <div class="face left">4</div>
        <div class="face top">5</div>
        <div class="face bottom">6</div>
      </div>
    </div>
  </figure>

  <figure>
    <figcaption><code>perspective-origin: bottom;</code></figcaption>
    <div class="container">
      <div class="cube pobm">
        <div class="face front">1</div>
        <div class="face back">2</div>
        <div class="face right">3</div>
        <div class="face left">4</div>
        <div class="face top">5</div>
        <div class="face bottom">6</div>
      </div>
    </div>
  </figure>

  <figure>
    <figcaption><code>perspective-origin: bottom right;</code></figcaption>
    <div class="container">
      <div class="cube pobr">
        <div class="face front">1</div>
        <div class="face back">2</div>
        <div class="face right">3</div>
        <div class="face left">4</div>
        <div class="face top">5</div>
        <div class="face bottom">6</div>
      </div>
    </div>
  </figure>

  <figure>
    <figcaption><code>perspective-origin: -200% -200%;</code></figcaption>
    <div class="container">
      <div class="cube po200200neg">
        <div class="face front">1</div>
        <div class="face back">2</div>
        <div class="face right">3</div>
        <div class="face left">4</div>
        <div class="face top">5</div>
        <div class="face bottom">6</div>
      </div>
    </div>
  </figure>

  <figure>
    <figcaption><code>perspective-origin: 200% 200%;</code></figcaption>
    <div class="container">
      <div class="cube po200200pos">
        <div class="face front">1</div>
        <div class="face back">2</div>
        <div class="face right">3</div>
        <div class="face left">4</div>
        <div class="face top">5</div>
        <div class="face bottom">6</div>
      </div>
    </div>
  </figure>

  <figure>
    <figcaption><code>perspective-origin: 200% -200%;</code></figcaption>
    <div class="container">
      <div class="cube po200200">
        <div class="face front">1</div>
        <div class="face back">2</div>
        <div class="face right">3</div>
        <div class="face left">4</div>
        <div class="face top">5</div>
        <div class="face bottom">6</div>
      </div>
    </div>
  </figure>
</section>
```

##### CSS

```css
/\* perspective-origin values (unique per example) \*/
.potl {
  perspective-origin: top left;
}
.potm {
  perspective-origin: top;
}
.potr {
  perspective-origin: top right;
}
.poml {
  perspective-origin: left;
}
.pomm {
  perspective-origin: 50% 50%;
}
.pomr {
  perspective-origin: right;
}
.pobl {
  perspective-origin: bottom left;
}
.pobm {
  perspective-origin: bottom;
}
.pobr {
  perspective-origin: bottom right;
}
.po200200neg {
  perspective-origin: -200% -200%;
}
.po200200pos {
  perspective-origin: 200% 200%;
}
.po200200 {
  perspective-origin: 200% -200%;
}

/\* Define the container div, the cube div, and a generic face \*/
.container {
  width: 100px;
  height: 100px;
  margin: 24px;
  border: none;
}

.cube {
  width: 100%;
  height: 100%;
  backface-visibility: visible;
  perspective: 300px;
  transform-style: preserve-3d;
}

.face {
  display: block;
  position: absolute;
  width: 100px;
  height: 100px;
  border: none;
  line-height: 100px;
  font-family: sans-serif;
  font-size: 60px;
  color: white;
  text-align: center;
}

/\* Define each face based on direction \*/
.front {
  background: rgba(0, 0, 0, 0.3);
  transform: translateZ(50px);
}
.back {
  background: rgba(0, 255, 0, 1);
  color: black;
  transform: rotateY(180deg) translateZ(50px);
}
.right {
  background: rgba(196, 0, 0, 0.7);
  transform: rotateY(90deg) translateZ(50px);
}
.left {
  background: rgba(0, 0, 196, 0.7);
  transform: rotateY(-90deg) translateZ(50px);
}
.top {
  background: rgba(196, 196, 0, 0.7);
  transform: rotateX(90deg) translateZ(50px);
}
.bottom {
  background: rgba(196, 0, 196, 0.7);
  transform: rotateX(-90deg) translateZ(50px);
}

/\* Make the layout a little nicer \*/
section {
  background-color: #eee;
  padding: 10px;
  font-family: sans-serif;
  text-align: left;
  display: grid;
  grid-template-columns: repeat(3, 1fr);
}
```

##### Result

完成此操作后，你可以在 3D 空间中处理元素。

参见
--

* CSS `transform` 属性和 CSS `<transform-function>` 数据类型
* 单独的变换属性：`translate`、`rotate` 和 `scale`（没有 `skew` 属性）
* 将设备方向与 3D 变换结合使用 (en-US)
* CSS 3D 变换简介（由 David DeSandro 撰写的博客）
* CSS 变换 Playground（CSS 变换函数可视化的在线工具）


使用特性查询 - CSS：层叠样式表

使用特性查询
======

**特性查询** 使用 CSS 的 at 规则 @supports 创建。它给予 web 开发者一种测试浏览器是否有对某个确定特性的支持，而后提供基于测试结果生效的 CSS 的方法。在此指南中你将学习如何使用特性查询实现渐进式增强。

语法
--

CSS 特性查询是 CSS Conditional Rules module 标准的一部分，这一标准也包含了媒体查询 @media 规则；在你使用特性查询的时候，你会发现它们的行为方式与媒体查询类似。不同点在于媒体查询是测试网页运行的环境相关内容，但特性查询测试的是浏览器对 CSS 特性的支持。

特性查询由 `@supports` 规则组成，紧跟着是属性名以及你想测试的属性值。你不能测试一个单单的属性名比如 `display`；规则需要你提供一个属性名以及一个值：

```css
@supports (property: value) {
  将要应用的 CSS 规则
}
```

比如，若你想检测一个浏览器是否支持 `row-gap` 属性，你应当写下如下的特性查询。大部分情况下这个查询结果与你所使用的值无关——也就是如果你想仅仅检测浏览器是否支持这个 CSS 属性，那么任何有效的属性值都可以。

若你测试的是某个属性的新值，那么属性 - 值对中值的那一部分就更加关键。`display` 属性就是一个很好的例子。所有的浏览器都支持 `display` 属性，这可以追溯到 CSS1 中的 `display: block` 。然而 `display: flex` 和 `display: grid` 这些值是新出现的。CSS 属性经常会有额外的新值加入，所以你必须检测属性与值的事实意味着你可以检测那些值的浏览器支持性。（原文：There are often additional values added to properties in CSS, and so the fact that you have to test for property and value means that you can detect support for these values.）

测试是否缺少支持
--------

除了测试浏览器是否支持某个特性外，你也可以通过添加 `not` 关键字测试浏览器是否不支持某个特性。

```css
@supports not (property: value) {将要应用的 CSS 规则
}
```

下述特性查询中的 CSS 规则仅会在浏览器不支持 `row-gap` 属性的情况下生效。

测试多个特性
------

你可能需要在功能查询中测试对多个属性的支持。为此，你应当包含要测试的功能的列表，使用 `and` 关键字分隔：

```css
@supports (property1: value) and (property2: value) {
  将要应用的 CSS 规则
}
```

比如，若你想要应用的 CSS 需要浏览器支持 CSS Shape 与 CSS Grid，你可以创建可以同时检测这两个特性的规则。下述规则只有在浏览器同时支持 `shape-outside: circle()` 和`display: grid` 的时候才会返回 true。

你也可以使用 `or`，如果所有规则中有一个规则可以匹配那么你想应用的 CSS 样式就会被启用。

```css
@supports (property1: value) or (property2: value) {
  将要应用的 CSS 规则
}
```

你可以在测试时为任何标准属性加上浏览器引擎前缀，然后测试特定引擎的 CSS 支持性，这非常有用。

特性查询的局限性
--------

`@supports` 规则测试浏览器是否能解析一个或多个属性以及其值，以及是否浏览器是否觉得支持这些属性以及其值。如果浏览器理解这些属性和值，那么它就会给一个肯定的回答。因此，特性查询不能检测浏览器是否**正确地表现**这些属性和值，以及是否没有 bug 存在。

另外，特性查询无法检测*局部实现* （*partial implementations）。一个很好的例子就是* `gap` 属性。所有支持 CSS Grid 的浏览器都支持 `gap` 在 CSS Grid 中，然而只有 Firefox 浏览器支持 Flexbox 中的 `gap`。若你为了在 Flexbox 中使用 `gap` 属性而测试其浏览器支持，就算它还没有（在 Flexbox 中）实现你也会得到浏览器肯定的回答。

如何使用特性查询进行渐进式增强
---------------

在逐步增强一个站点时，特性查询是一个非常有用的工具。它们使你能够为所有浏览器提供良好的解决方案，并为那些支持新特性的浏览器提供增强的解决方案。

然而，某些浏览器既不支持特性查询，也不支持我们希望使用的特性。例如，我们也许希望使用 CSS Grid，但 IE11 不支持它。我们也不能为其创建一个针对没有 Grid 支持的浏览器的后备样式，因为 IE11 也不支持特性查询。然而在实践中，当使用特性查询进行渐进增强时，然而这并不重要。你确实需要有一个组织 CSS 的方式，那么应当先为不支持新特性的浏览器编写 CSS 样式，然后在特性查询中进行覆盖。

让我们看一个非常简单的例子，在这个例子中，特性查询就派上用场了，它使用上述的方式来组织 CSS。

假设我们想要创建一行三个盒子的布局，理想情况下，我们想要使用 CSS Grid Layout 布局。但是，我们希望有一个使用浮动（floats）的旧浏览器的布局。我们可以先用下面的代码创建浮动布局，它提供了三个列。

浏览器会忽略其无法识别的 CSS 属性或者值。所以我们可以开始使用 CSS Grid 来增强我们的布局。不支持 Grid 的浏览器将会忽略 `display` 属性的 `grid` 值。一旦一个浮动项成为网格项，浮动就会被移除——你可以阅读 Supporting Older Browsers 来了解更多。因此浮动的版本就会被网格的版本替代。

然而问题来了，起因于我们为了使浮动项目显示为三列而在上面设置的 `width` 属性，它现在被网格解释为列在网格中的宽度，而不是容器的宽度（相对于浮动布局）。

如果 `display: grid` 是被浏览器支持的，我们就需要一个方法去移除 width 属性。这正是特性查询所解决的问题，当 Grid 被支持的时候，我们就能将 `width` 设置回 `auto` 。

在上述场景中，IE11 是否支持特性查询或者 CSS Grid 已经无关紧要——不论何时它都能获得 float 的版本，然后在支持 Grid 的浏览器中这一行为就会被覆盖。

编写上述代码的另一种方法是将所有网格代码包装在一个特性查询中，如下所示。

这意味着你可能需要一些额外代码，但也有好处，你可以通过故意写错属性或者值的名字来测试你的后备代码。你可以通过修改上面在线例子中的 `display: grid` 为 `display: grip` 或者其他无效值来尝试。

总结
--

功能查询可以帮助你开始使用更新的功能，它可以增强旧浏览器使用的简单的站点的显示。由于可以针对其支持的浏览器而打包 CSS，因此不会有后退显示使用的样式漏出的风险（原文：you do not run the risk of styles used for the fallback display leaking through），就像上面的 Grid 示例那样。

### 参见

* @supports 规则
* 学习布局：Supporting Older Browsers
* CSS Grid Layout and Progressive Enhancement
* Using Feature Queries in CSS


逻辑属性与逻辑值的基本概念 - CSS：层叠样式表

逻辑属性与逻辑值的基本概念
=============

逻辑属性与逻辑值规范为 CSS 中的许多属性和值引入了相对于流的对应关系。本文介绍此规范，并解释相对于流的属性与值。

为什么我们需要逻辑属性？
------------

传统的 CSS 根据屏幕的实体尺度设置物体尺寸。因此我们说盒子具有宽度（`width`）和高度（`height`），参照上侧（`top`）和左侧（`left`）为元素定位，将物体浮动至左侧，为上侧（`top`）、右侧（`right`）、下侧（`bottom`）、左侧（`left`）赋予边框和内外边距，等等。逻辑属性与逻辑值规范定义了从这些实体值到与之等价的逻辑值（即相对于流的值）的对应关系——如 `left` 和 `right`，或者 `top` 和 `bottom` 对应于 `start` 和 `end`。

举个例子说明为什么会需要这些对应关系。我有一个布局用了 CSS 网格，网格容器应用了宽度属性，而且我用 `align-self` 和 `justify-self` 属性对齐元素。这些属性是相对于流的——`justify-self: start` 将元素对齐到行首，`align-self: start` 在块向上的效果类似。

![横排书写模式中的网格](/zh-CN/docs/Web/CSS/CSS_logical_properties_and_values/Basic_concepts_of_logical_properties_and_values/grid-horizontal-width-sm.png)

如果我现在用 `writing-mode` 属性把这个组件的书写模式改成 `vertical-rl`，那么对齐方式还是一样的。现在行向是竖直方向而块向是水平方向。然而网格变了样，这是因为给容器赋的宽度是水平尺度，与它挂钩的是文本的实体延伸方向，而非逻辑或相对于流的延伸方向。

![竖排书写模式中的网格](/zh-CN/docs/Web/CSS/CSS_logical_properties_and_values/Basic_concepts_of_logical_properties_and_values/grid-vertical-width-sm.png)

如果我们不用 `width` 属性而用逻辑属性 `inline-size`，那现在无论用什么书写模式显示组件都没有问题。

![竖排书写模式中的网格](/zh-CN/docs/Web/CSS/CSS_logical_properties_and_values/Basic_concepts_of_logical_properties_and_values/grid-vertical-inline-size-small.png)

你可以在下面的运行实例里尝试一下。把 `.grid` 的 `writing-mode` 从 `vertical-rl` 改成 `horizontal-tb`，看看不同的属性是怎么改变布局的。

在不是从横排上到下的书写模式里做网站，或者在用书写模式做创意的时候，能够对应到内容的流向上是非常合理的。

块向与行向尺度
-------

在使用相对于流的属性和值时，一个关键的概念是块向与行向这两个方向。上文我们已经看到在对齐元素时，诸如弹性盒和网格布局等新的 CSS 布局方法所用的概念是块向（`block`）和行向（`inline`），而非右侧（`right`）和左侧（`left`），或者上侧（`top`）和下侧（`bottom`）。

行向是指在所用的书写模式中，一行文本延伸的方向。因此在从左到右横排的英文文档，或者从右到左横排的阿拉伯文文档中，行向为*水平方向*。若切换至竖排书写模式（如日文文档）则行向变为*竖直方向*，这是因为文本在这种书写模式中竖直延伸。

块向是指另一方向，即块——例如段落——依次显示的方向。在英文和阿拉伯文中，块沿竖直方向依次排列，而块在任意竖排书写模式中沿水平方向依次排列。

下图展示了横排书写模式中的行向与块向：

![行向轴与块向轴分别水平和竖直延伸的图示](/zh-CN/docs/Web/CSS/CSS_logical_properties_and_values/Basic_concepts_of_logical_properties_and_values/mdn-horizontal.png)

此图展示了竖排书写模式中的块向与行向：

![块向轴与行向轴分别水平和竖直延伸的图示](/zh-CN/docs/Web/CSS/CSS_logical_properties_and_values/Basic_concepts_of_logical_properties_and_values/mdn-vertical.png)

参见
--

* 网格布局中的盒对齐
* 弹性布局中的盒对齐
* Understanding Logical Properties and Values
* 书写模式


逻辑尺寸属性 - CSS：层叠样式表

逻辑尺寸属性
======

实体尺度属性和逻辑属性用于在页面上设置元素尺寸，而我们将在本指南中解释两者之间相对于流的对应关系。

在指定元素的尺寸时，标示实体尺寸参照的是水平和竖直方向（如左和右）的实体尺度，而逻辑属性与逻辑值规范使你可以参照文本流向（行向与块向）标示尺寸。虽然对于我们中的大多数而言，这些相对于流的对应关系很可能都是默认的，但是在设计中你很可能会同时用到实体尺寸和逻辑尺寸。你可能想要某些特性在任何书写模式里参照的都是实体尺度。

尺度的对应关系
-------

下表提供了逻辑属性与实体属性的对应关系。这些对应关系假定你在 `horizontal-tb` 的书写模式里——例如英文或者阿拉伯文，此时 `width` 会对应到 `inline-size`。

假如你在竖排书写模式里，那么 `inline-size` 会对应到 `height`。

| 逻辑属性 | 实体属性 |
| --- | --- |
| `inline-size` | `width` |
| `block-size` | `height` |
| `min-inline-size` | `min-width` |
| `min-block-size` | `min-height` |
| `max-inline-size` | `max-width` |
| `max-block-size` (en-US) | `max-height` |

宽度和高度的示例
--------

`width` 和 `height` 对应的逻辑属性为 `inline-size`（设置行向长度）和 `block-size`（设置块向长度）。在英文文本中，将 `width` 换为 `inline-size`，`height` 换为 `block-size`，所得布局相同。

在下面的运行实例里，我把书写模式设置成了 `horizontal-tb`。把它改成 `vertical-rl`，你会看到第一个例子——用的 `width` 和 `height`——尽管文本变成竖排，但是在每个方向上的尺寸保持不变。第二个例子——用的 `inline-size` 和 `block-size`——会跟着文本的方向变化，就像旋转了整个块。

最小宽度和最小高度的示例
------------

`min-width` 和 `min-height` 也有对应的属性——即 `min-inline-size` 和 `min-block-size`。这些属性的用法与 `inline-size` 和 `block-size` 属性相同，但是设置的是最小尺寸而不是固定尺寸。

试试把下面的例子像第一个例子一样改成 `vertical-rl` 看看效果。我在第一个例子里用了 `min-height`，在第二个里用了 `min-block-size`。

最大宽度和最大高度的示例
------------

最后你可以用逻辑属性 `max-inline-size` 和 `max-block-size` (en-US) 替代 `max-width` 和 `max-height`。用和之前一样的方式玩玩下面的例子。

用于 resize 的逻辑关键词
----------------

`resize` 属性用于设置元素是否可调整尺寸，有实体值 `horizontal` 和 `vertical`。`resize` 也有逻辑关键词值。使用 `resize: inline` 允许沿行向调整尺寸，而 `resize: block` 允许沿块向调整尺寸。

无论你按实体还是按逻辑理解，`resize` 属性的关键词值 `both` 的效果都一样。这个值同时设置两个方向的尺度。玩玩下面的例子。


用于浮动和定位的逻辑属性 - CSS：层叠样式表

用于浮动和定位的逻辑属性
============

逻辑属性与逻辑值规范包含了 `float` 和 `clear` 的实体值的逻辑对应关系，以及用于定位布局的定位属性的逻辑对应关系。本指南介绍如何使用这些对应关系。

属性的和值的对应关系
----------

下表详列了本指南所论述的属性和值，以及其实体对应关系。假设书写模式（`writing-mode`）为横排，行内方向为从左到右。

| 逻辑属性或逻辑值 | 实体属性或实体值 |
| --- | --- |
| `float`: inline-start | `float`: left |
| `float`: inline-end | `float`: right |
| `clear`: inline-start | `clear`: left |
| `clear`: inline-end | `clear`: right |
| `inset-inline-start` | `left` |
| `inset-inline-end` | `right` |
| `inset-block-start` | `top` |
| `inset-block-end` | `bottom` |
| `text-align`: start | `text-align`: left |
| `text-align`: end | `text-align`: right |

除了这些有对应关系的属性，另有可以处理块向和行向尺度的简写属性。除 `inset` 属性外，这些属性没有与实体属性的对应关系。

| 逻辑属性 | 用途 |
| --- | --- |
| `inset-inline` | 为行向尺度同时设置上述两个偏移值。 |
| `inset-block` | 为块向尺度同时设置上述两个偏移值。 |
| `inset` | 同时设置四个偏移值，多值语法使用实体对应关系。 |

浮动和清除浮动的示例
----------

`float` 和 `clear` 属性所用的实体值为 `left`、`right` 和 `both`。逻辑属性规范定义 `inline-start` 和 `inline-end` 值对应于 `left` 和 `right`。

在下面的例子里，我有两个盒子——第一个用 `float: left` 设置了浮动，第二个用了 `float: inline-start`。如果把 `writing-mode` 改成 `vertical-rl` 或者把 `direction` 改成 `rtl`，你会看到浮动到左侧的盒子总是贴在左侧，而浮动到 `inline-start` 的元素随着 `direction` 和 `writing-mode` 变动。

示例：定位布局的偏移属性
------------

定位通常可以让我们相对于元素的包含块放置元素——我们就是参照元素在正常流里的位置给元素设置偏移。过去我们用实体属性 `top`、`right`、`bottom` 和 `left` 做这件事。

这些属性的取值是长度或百分比，而且参照的是用户屏幕的尺度。

逻辑属性规范创造了新的属性，你可以用来在你的书写模式里参照文本的流向定位。这些属性有：`inset-block-start`、`inset-block-end`、`inset-inline-start` 和 `inset-inline-end`。

在下面的例子里，带灰色点状边框的区域设置了 `position: relative`。为了在这个区域里用绝对定位放置蓝色盒子，我用了 `inset-block-start` 和 `inset-inline-end` 属性。把 `writing-mode` 属性改成 `vertical-rl`，或者加上 `direction: rtl`，看看相对于流的盒子是怎么根据文本方向保持位置的。

新的二值和四值简写属性
-----------

和规范里的其他属性一样，我们也有新的简写属性可以同时设置两个或者四个值。

* `inset`——使用实体对应关系同时设置四边。
* `inset-inline`——设置两个逻辑行向偏移。
* `inset-block`——设置两个逻辑块向偏移。
示例：text-align 的逻辑值
------------------

`text-align` 属性有参照文本方向的逻辑值——我们可以不用 `left` 和 `right` 而用 `start` 和 `end`。在下面的例子里，我在第一个块里设置了 `text-align: right`，在第二个里设置了 `text-align: end`。

如果把 `direction` 改成 `rtl`，你会看到第一个块还是右对齐的，但是第二个跑到了在左边的逻辑行末。

相比用实体方向对齐，在使用盒对齐的时候用首和末得到的效果更一致。


用于外边距、边框和内边距的逻辑属性 - CSS：层叠样式表

用于外边距、边框和内边距的逻辑属性
=================

逻辑属性与逻辑值规范为各种外边距、边框和内边距属性及其简写属性定义了相对于流的对应关系。本指南介绍这些对应关系。

如果你看过 CSS 逻辑属性与逻辑值的汇总页面就会看到那里列了一大堆属性。这主要是因为外边距、边框和内边距每个都有四个全称属性，还有所有的简写属性。

外边距、边框和内边距的对应关系
---------------

规范详述了每个逻辑值到实体值的对应关系。假设用的是 `horizontal-tb` 的书写模式（`writing-mode`）和从左到右的行内方向，我在下面的表格里给出了这些对应的属性。这时行向是水平方向——从左到右——而且 `margin-inline-start` 会等价于 `margin-left`。

如果你用了 `horizontal-tb` 的书写模式和从右到左的行内方向，那么 `margin-inline-start` 会和 `margin-right` 一样，而在竖排书写模式里 `margin-inline-start` 会和用 `margin-top` 一样。

| 逻辑属性 | 实体属性 |
| --- | --- |
| `border-block-end` | `border-bottom` |
| `border-block-end-color` | `border-bottom-color` |
| `border-block-end-style` | `border-bottom-style` |
| `border-block-end-width` | `border-bottom-width` |
| `border-block-start` | `border-top` |
| `border-block-start-color` | `border-top-color` |
| `border-block-start-style` | `border-top-style` |
| `border-block-start-width` | `border-top-width` |
| `border-inline-end` | `border-right` |
| `border-inline-end-color` | `border-right-color` |
| `border-inline-end-style` | `border-right-style` |
| `border-inline-end-width` | `border-right-width` |
| `border-inline-start` | `border-left` |
| `border-inline-start-color` | `border-left-color` |
| `border-inline-start-style` | `border-left-style` |
| `border-inline-start-width` | `border-left-width` |
| `border-start-start-radius` | `border-top-left-radius` |
| `border-end-start-radius` | `border-bottom-left-radius` |
| `border-start-end-radius` | `border-top-right-radius` |
| `border-end-end-radius` | `border-bottom-right-radius` (en-US) |
| `margin-block-end` | `margin-bottom` |
| `margin-block-start` | `margin-top` |
| `margin-inline-end` | `margin-right` |
| `margin-inline-start` | `margin-left` |
| `padding-block-end` | `padding-bottom` |
| `padding-block-start` | `padding-top` |
| `padding-inline-end` | `padding-right` |
| `padding-inline-start` | `padding-left` |

还有一些简写属性可以用于让我们同时设置盒子块向或者行向的两侧。这些简写属性没有等价的实体属性。

| 属性 | 用途 |
| --- | --- |
| `border-block` | 为两个块向边框设置 `border-color`、`border-style` 和 `border-width`。 |
| `border-block-color` | 为两个块向边框设置 `border-color`。 |
| `border-block-style` | 为两个块向边框设置 `border-style`。 |
| `border-block-width` | 为两个块向边框设置 `border-width`。 |
| `border-inline` | 为两个行向边框设置 `border-color`、`border-style` 和 `border-width`。 |
| `border-inline-color` | 为两个行向边框设置 `border-color`。 |
| `border-inline-style` | 为两个行向边框设置 `border-style`。 |
| `border-inline-width` | 为两个行向边框设置 `border-width`。 |
| `margin-block` | 设置所有块向外边距（`margin`）。 |
| `margin-inline` | 设置所有行向外边距（`margin`）。 |
| `padding-block` | 设置块向内边距（`padding`）。 |
| `padding-inline` | 设置行向内边距（`padding`）。 |

外边距示例
-----

有对应关系的外边距属性 `margin-inline-start`、`margin-inline-end`、`margin-block-start` 和 `margin-inline-end` 可用于替代对应的实体属性。

在下面的例子里我创建了两个盒子，给每条边加上了不同大小的外边距。为了让外边距更明显，我另外加上了带边框的容器。

一个盒子用的实体属性，另一个用的逻辑属性。试试把 `direction` 属性改成 `rtl`，让盒子显示在从右到左的行内方向里，第一个盒子的外边距会保持不动，而第二个盒子行向的外边距会发生切换。

你也可以试试把 `writing-mode` 从 `horizontal-tb` 改成 `vertical-rl`。注意到第一个盒子的外边距还是保持不动，但是第二个的跟着文本的行内方向四处切换。

### 外边距简写属性

既然我们现在可以同时设置盒子的两侧——要么行向要么块向的两侧——那就有新的简写属性 `margin-inline` 和 `margin-block` 可以接受两个值。第一个值会应用到那个方向的首侧，第二个应用到末侧。如果你只用一个值，那么这个值应用到两侧。

在横排书写模式里，这段 CSS 会给盒子上侧 5px 的外边距，下侧 10px 的外边距。

```css
.box {
  margin-block: 5px 10px;
}
```

内边距示例
-----

有对应关系的内边距属性 `padding-inline-start`、`padding-inline-end`、`padding-block-start` 和 `padding-inline-end` 可用于替代对应的实体属性。

在下面的例子里我有两个盒子，一个用的实体内边距属性，而另一个用的逻辑内边距属性。在 `horizontal-tb` 的书写模式（`writing-mode`）里，两个盒子应该看起来一样。

试试把 `direction` 属性改成 `rtl`，让盒子显示在从右到左的行内方向里。第一个盒子的内边距会保持不动，而第二盒子行向的内边距会发生切换。

你也可以试试把 `writing-mode` 从 `horizontal-tb` 改成 `vertical-rl`。注意到第一个盒子的内边距还是保持不动，但是第二个的跟着文本的行内方向四处切换。

### 内边距简写属性

和外边距一样，内边距也有二值简写属性——`padding-inline` 和 `padding-block`——可以让你分别设置行向和块向的两个内边距。

在横排书写模式里，这段 CSS 会给盒子上侧 5px 的内边距，下侧 10px 的内边距：

```css
.box {
  padding-block: 5px 10px;
}
```

边框示例
----

边框属性是导致逻辑属性与逻辑值规范有如此之多的属性的主要原因，盒子每侧边框的颜色、宽度和线型都有全称属性，每侧还有同时设置这三个的简写属性。和内外边距一样，每个实体属性都有对应的属性。

下面的演示用了几个全称属性和三个简写属性。和其他演示一样，试试把 `direction` 属性改成 `rtl`，让盒子显示在从右到左的行内方向里，或者把 `writing-mode` 从 `horizontal-tb` 改成 `vertical-rl`。

### 新的边框简写属性

有在块向或者行向上设置宽度、线型和颜色二值简写属性，也有在块向或者行向上同时设置三个值的简写属性。下面的代码在横排书写模式里会给盒子的上侧和下侧 2px 的绿色实线边框，左侧和右侧 4px 的点状紫色边框。

```css
.box {
  border-block: 2px solid green;
  border-inline-width: 4px;
  border-inline-style: dotted;
  border-inline-color: rebeccapurple;
}
```

### 相对于流的 border-radius 属性

规范为 `border-radius` 全称属性提供了相对于流的等价属性。下列示例在横排书写模式（`writing-mode`）中会将右上角的边框半径设置为 1em，右下角的为 0，左下角的为 20px，左上角的为 40px。

```css
.box {
  border-end-start-radius: 1em;
  border-end-end-radius: 0;
  border-start-end-radius: 20px;
  border-start-start-radius: 40px;
}
```

为四值简写属性语法标示逻辑值
--------------

规范为 `margin` 属性等四值简写属性提出了相关建议，然而尚未最终确定如何标示逻辑值，讨论见此议题。

目前使用如 `margin`、`padding` 或 `border` 等任意四值简写属性将使用实体属性，因此若跟随文档的流向很重要，则暂时使用全称属性。


使用 CSS 动画 - CSS：层叠样式表

使用 CSS 动画
=========

**CSS animations** 使得可以将从一个 CSS 样式配置转换到另一个 CSS 样式配置。动画包括两个部分：描述动画的样式规则和用于指定动画开始、结束以及中间点样式的关键帧。

相较于传统的脚本实现动画技术，使用 CSS 动画有三个主要优点：

1. 能够非常容易地创建简单动画，你甚至不需要了解 JavaScript 就能创建动画。
2. 动画运行效果良好，甚至在低性能的系统上。渲染引擎会使用跳帧或者其他技术以保证动画表现尽可能的流畅。而使用 JavaScript 实现的动画通常表现不佳（除非经过很好的设计）。
3. 让浏览器控制动画序列，允许浏览器优化性能和效果，如降低位于隐藏选项卡中的动画更新频率。
配置动画
----

创建动画序列，需要使用 `animation` 属性或其子属性，该属性允许配置动画时间、时长以及其他动画细节，但该属性不能配置动画的实际表现，动画的实际表现是由 `@keyframes` 规则实现，具体情况参见使用 keyframes 定义动画序列小节部分。

`animation` 的子属性有：

**`animation-delay`**

设置延时，即从元素加载完成之后到动画序列开始执行的这段时间。

**`animation-direction`**

设置动画在每次运行完后是反向运行还是重新回到开始位置重复运行。

**`animation-duration`**

设置动画一个周期的时长。

**`animation-iteration-count`**

设置动画重复次数，可以指定 infinite 无限次重复动画

**`animation-name`**

指定由`@keyframes`描述的关键帧名称。

**`animation-play-state`**

允许暂停和恢复动画。

**`animation-timing-function`**

设置动画速度，即通过建立加速度曲线，设置动画在关键帧之间是如何变化。

**`animation-fill-mode`**

指定动画执行前后如何为目标元素应用样式。

使用 keyframes 定义动画序列
-------------------

一旦完成动画的时间设置，接下来就需要定义动画的表现。通过使用`@keyframes`建立两个或两个以上关键帧来实现。每一个关键帧都描述了动画元素在给定的时间点上应该如何渲染。

因为动画的时间设置是通过 CSS 样式定义的，关键帧使用 `<percentage>` 来指定动画发生的时间点。`0%` 表示动画的第一时刻，`100%` 表示动画的最终时刻。因为这两个时间点十分重要，所以还有特殊的别名：`from` 和 `to`。这两个都是可选的，若 `from/0%` 或 `to/100%` 未指定，则浏览器使用计算值开始或结束动画。

也可包含额外可选的关键帧，描述动画开始和结束之间的状态。

示例
--

**备注：** 这里的示例没有在 CSS 动画属性上使用任何前缀，Webkit 内核浏览器或者早期版本浏览器可能需要前缀，下面的实例包含了`-webkit-`前缀。

### 文本滑过浏览器窗口

该例中`<p>` 元素由浏览器窗口右边滑至左边

```css
p {
  animation-duration: 3s;
  animation-name: slidein;
}

@keyframes slidein {
  from {
    margin-left: 100%;
    width: 300%;
  }

  to {
    margin-left: 0%;
    width: 100%;
  }
}
```

`animation-duration` 属性指定 `<p>` 上的动画从开始到结束耗费 3 秒，`@keyframes` 指定使用名字为“slidein”的关键帧。

如果希望在不支持 CSS 动画的浏览器中使用自定义样式，应该将其写在这里；然而，在该例中，我们不需要除动画效果以外的任何自定义样式。

关键帧是用 `@keyframes` 定义的。该例中，我们只使用了两个关键帧。第一个出现在 0%（此例中使用了别名 `from`）处，此处元素的左边距为 100%（即位于容器的右边界），宽为 300%（即容器宽度的 3 倍），使得在动画的第一帧中标题位于浏览器窗口右边界之外。

第二帧出现在 100%（此例中使用了别名 `to`）。元素的左边距设为 0%，宽设为 100%，使得动画结束时元素与窗口左边界对齐。

```html
<p>
  The Caterpillar and Alice looked at each other for some time in silence: at
  last the Caterpillar took the hookah out of its mouth, and addressed her in a
  languid, sleepy voice.
</p>
```

### 增加关键帧

让我们给上面的示例中添加一个关键帧，比如标题的字号先变大然后恢复正常，添加这个关键帧十分简单：

```css
75% {
  font-size: 300%;
  margin-left: 25%;
  width: 150%;
}
```

```
p {
  animation-duration: 3s;
  animation-name: slidein;
}

@keyframes slidein {
  from {
    margin-left: 100%;
    width: 300%;
  }

  to {
    margin-left: 0%;
    width: 100%;
  }
}
```

```
<p>
  The Caterpillar and Alice looked at each other for some time in silence: at
  last the Caterpillar took the hookah out of its mouth, and addressed her in a
  languid, sleepy voice.
</p>
```

在动画序列执行到 75% 的时候，标题元素的左边距为 25%，宽度为 150%。

### 重复动画

`animation-iteration-count`用以指定动画重复的次数，仅仅使用该属性就能使动画重复播放。在该例中，设该属性为`infinite`以使动画无限重复

```css
p {
  animation-duration: 3s;
  animation-name: slidein;
  animation-iteration-count: infinite;
}
```

```
@keyframes slidein {
  from {
    margin-left: 100%;
    width: 300%;
  }

  to {
    margin-left: 0%;
    width: 100%;
  }
}
```

```
<p>
  The Caterpillar and Alice looked at each other for some time in silence: at
  last the Caterpillar took the hookah out of its mouth, and addressed her in a
  languid, sleepy voice.
</p>
```

### 来回运动

上面实现了动画的重复播放，但是每次动画开始时总跳回开始位置显得很怪异。我们真正想要的是标题来回滑动，这时只需要设置`animation-direction`属性为`alternate`。

```css
p {
  animation-duration: 3s;
  animation-name: slidein;
  animation-iteration-count: infinite;
  animation-direction: alternate;
}
```

```
@keyframes slidein {
  from {
    margin-left: 100%;
    width: 300%;
  }

  to {
    margin-left: 0%;
    width: 100%;
  }
}
```

```
<p>
  The Caterpillar and Alice looked at each other for some time in silence: at
  last the Caterpillar took the hookah out of its mouth, and addressed her in a
  languid, sleepy voice.
</p>
```

### 使用动画事件

利用动画事件可以更好的控制动画和信息。这些事件由 `AnimationEvent` (en-US)对象表示，可探测动画何时开始结束和开始新的循环。每个事件包括动画发生的时间和触发事件的动画名称。我们将修改滑动文本示例，输出每个动画事件出现时的信息。

```css
.slidein {
  -moz-animation-duration: 3s;
  -webkit-animation-duration: 3s;
  animation-duration: 3s;
  -moz-animation-name: slidein;
  -webkit-animation-name: slidein;
  animation-name: slidein;
  -moz-animation-iteration-count: 3;
  -webkit-animation-iteration-count: 3;
  animation-iteration-count: 3;
  -moz-animation-direction: alternate;
  -webkit-animation-direction: alternate;
  animation-direction: alternate;
}

@-moz-keyframes slidein {
  from {
    margin-left: 100%;
    width: 300%;
  }

  to {
    margin-left: 0%;
    width: 100%;
  }
}

@-webkit-keyframes slidein {
  from {
    margin-left: 100%;
    width: 300%;
  }

  to {
    margin-left: 0%;
    width: 100%;
  }
}

@keyframes slidein {
  from {
    margin-left: 100%;
    width: 300%;
  }

  to {
    margin-left: 0%;
    width: 100%;
  }
}
```

#### 添加动画事件监听器

我们使用 JavaScript 代码监听所有三种可能的动画事件，`setup()` 方法设置事件监听器，当文档第一次加载完成时执行该方法。

```js
var e = document.getElementById("watchme");
e.addEventListener("animationstart", listener, false);
e.addEventListener("animationend", listener, false);
e.addEventListener("animationiteration", listener, false);

e.className = "slidein";
```

以上是非常标准的代码写法，setup() 最后设置动画元素的 `class` 为 slidein，启动动画。为什么这样做？因为`animationstart`事件在动画一开始时就被触发，在我们的示例中，该事件在我们的代码执行前就被触发，所以我们自己通过设置元素的的`class`来启动动画。

#### 接收事件

事件传递给`listener()`函数，代码如下所示

```js
function listener(e) {
  var l = document.createElement("li");
  switch (e.type) {
    case "animationstart":
      l.innerHTML = "Started: elapsed time is " + e.elapsedTime;
      break;
    case "animationend":
      l.innerHTML = "Ended: elapsed time is " + e.elapsedTime;
      break;
    case "animationiteration":
      l.innerHTML = "New loop started at time " + e.elapsedTime;
      break;
  }
  document.getElementById("output").appendChild(l);
}
```

这段代码同样非常简单，简单地通过`event.type`来判断发生的是何种事件，然后添加对应的注解到`<ul>`中。

输出结果如下所示：

* Started: elapsed time is 0
* New loop started at time 3.01200008392334
* New loop started at time 6.00600004196167
* Ended: elapsed time is 9.234000205993652

注意以上时间非常接近预期时间，但不是完全相等。也要注意在最后一个周期完成后，不会触发`animationiteration`事件，而触发`animationend`事件。

#### HTML 代码

下面是示例中的用到的 HTML 代码：

```html
<body>
  <h1 id="watchme">Watch me move</h1>
  <p>
    This example shows how to use CSS animations to make
    <code>h1</code> elements move across the page.
  </p>
  <p>
    In addition, we output some text each time an animation event fires, so you
    can see them in action.
  </p>
  <ul id="output"></ul>
</body>
```

See also
--------

* `AnimationEvent` (en-US)
* Detecting CSS animation support
* Using CSS transitions


CSS Animations tips and tricks - CSS：层叠样式表

CSS Animations tips and tricks
==============================

CSS 动画使得你能够实现一些难以置信的效果点缀你的页面或者应用程序。然而，有些你想实现的东西表现的并不浅显易懂，或者没法使你立马想到一种聪明的解决办法。这篇文章集合一个一些温馨贴士和技巧，从而帮助你更轻松地工作，这其中包括了如何使一个已经停止的动画重新开始播放。

重新播放动画
------

CSS 动画的规范并没有提供使得动画重新激活的方法。在元素上调用`resetAnimation()` 并不生效，你也不能直接通过设置元素的 `animation-play-state`使得动画重新“跑起来”。事实上，你必须使用一些技巧使得已经停止的动画重新播放。

这有一种我们认为足够稳定和可靠的方法推荐给你。

### HTML

首先，让我们定义一个我们想要添加动画的元素`<div>` 以及一个“播放”或“重播”动画的按钮。

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

<div class="runButton">Click me to run the animation</div>
```

### CSS

现在我们将使用 CSS 定义动画本身。为了简洁，有些并不重要的 CSS（如“播放”按钮的样式）并没有显示在这里。
```

.runButton {
  cursor: pointer;
  width: 300px;
  border: 1px solid black;
  font-size: 16px;
  text-align: center;
  margin-top: 12px;
  padding-top: 2px;
  padding-bottom: 4px;
  color: white;
  background-color: darkgreen;
  font:
    14px "Open Sans",
    "Arial",
    sans-serif;
}
```

```css
@keyframes colorchange {
  0% {
    background: yellow;
  }
  100% {
    background: blue;
  }
}

.box {
  width: 100px;
  height: 100px;
  border: 1px solid black;
}

.changing {
  animation: colorchange 2s;
}
```

这里有两个类。`"box"` 类基本表述了 box 的外观，它不包含任何动画信息。动画的细节包含在`"changing"` 类，它描述了名为 `"colorchange"` 的 `@keyframes` 应该这持续两秒的时间段播放动画。

注意，正因为如此，这个 box 在这里不触发任何动画效果，因此他不会动起来。

### JavaScript

接下来我们将看看 JavaScript 的部分如何工作。这里关键的部分在 `play()` 方法中，他在用户点击“播放”按钮时被触发。

```js
function play() {
  document.querySelector(".box").className = "box";
  window.requestAnimationFrame(function (time) {
    window.requestAnimationFrame(function (time) {
      document.querySelector(".box").className = "box changing";
    });
  });
}
```

这看起来有点奇怪，不是么？这是因为重新播放动画的唯一方法是删除动画效果，让文档重新计算样式以使得它知道你已经设置了它，然后再将动画效果加回该元素。要实现这个，我们必须更具创造性。

这里是`play()` 方法被调用时发生的事情：

1. box 的 CSS 类列表被重置为 `"box"`。这么做的效果是移除了在这个 box 上的其他类属性，包括处理动画的 `"changing"` 类。换句话说，我们从 box 元素上删除了动画效果。然而，改变类属性列表在样式被重新计算完成或者发生刷新事件之前并不会生效。
2. 为了确保样式被重新计算我们使用 `window.requestAnimationFrame()`，同时设置了一个回调。我们的回调在下一次重绘页面之前被调用。问题是由于它在重绘之前被调用，而此时样式还没有被真正重新计算。
3. 我们的回调聪明地调用了 `requestAnimationFrame()` 方法！这一次，回调在下一次重绘之前被调用，这发生在样式被重新计算之后。回调在 box 元素上添加 `"changing"` 类，使得重绘后重新触发动画。

当然，我们同样需要在“播放”按钮上添加事件处理方法使其生效：

```js
document.querySelector(".runButton").addEventListener("click", play, false);
```

### 结果

参见
--

* Using CSS transitions
* `Window.requestAnimationFrame()`


使用 CSS 过渡 - CSS：层叠样式表

使用 CSS 过渡
=========

**CSS 过渡**提供了一种在更改 CSS 属性时控制动画速度的方法。其可以让属性变化成为一个持续一段时间的，而不是立即生效的过程。比如，将一个元素的颜色从白色改为黑色，通常这个改变是立即生效的，使用 CSS 过渡后该元素的颜色将按照一定的曲线速率从白色变化为黑色。这个过程可以自定义。

通常将两个状态之间的过渡称为**隐式过渡**，因为开始与结束之间的状态由浏览器决定。

![CSS 过渡告诉浏览器绘制初始和最终状态之间的中间状态，向用户展示一个平滑的过渡](/zh-CN/docs/Web/CSS/CSS_transitions/Using_CSS_transitions/transitionsprinciple.png)

CSS 过渡可以决定哪些属性发生动画效果（通过*明确地列出这些属性*），何时开始（通过设置*延时*），持续多久（通过设置*时长*）以及如何动画（通过定义*缓动函数*，比如线性或先快后慢）。

哪些 CSS 属性可用于过渡？
---------------

Web 作者可以定义哪一属性需以何种方式用于动画，由此允许创造复杂的过渡。然而因为为某些属性赋予动画无意义，所以这些属性无动画性。

**备注：** `auto` 值常常较复杂，规范指出不要在它上动画。一些用户代理，比如基于 Gecko 的，实现了这个需求；然而另外一些用户代理，比如基于 WebKit 的，没有这么严格限制。在 `auto` 上使用动画，取决于浏览器及其版本，可能会导致非预期结果，应当避免使用。

定义过渡
----

CSS 过渡通常使用简写属性 `transition` 控制。这是最好的方式，可以避免属性值列表长度不一，节省在 CSS 代码上调试的时间。

也可以用下面子属性来控制过渡的各部分：

`transition-property`

指定哪个或哪些 CSS 属性用于过渡。只有指定的属性才会在过渡中发生动画，其他属性仍如通常那样瞬间变化。

`transition-duration`

指定过渡的时长。你可以为所有属性指定一个值，或者指定多个值，或者为每个属性指定不同的时长。

`transition-timing-function`

指定一个函数，定义属性值怎么变化。*缓动函数*定义属性如何计算。大多数缓动函数由四点定义一个立方贝塞尔曲线。也可以从 Easing Functions Cheat Sheet 选择缓动效果。

`transition-delay`

指定延迟，即属性开始变化时与过渡开始发生时之间的时长。

`transition` 简写属性 CSS 语法如下：

```css
div {
  transition: <property> <duration> <timing-function> <delay>;
}
```

示例
--

### 简单示例

本示例实现了一个在用户鼠标移动到元素之上停留两秒后长度为四秒的字体大小过渡效果：

```css
#delay {
  font-size: 14px;
  transition-property: font-size;
  transition-duration: 4s;
  transition-delay: 2s;
}

#delay:hover {
  font-size: 36px;
}
```

### 多个动画属性示例
```

<body>
  <p>
    下面的盒子包含 width、height、background-color 和 rotate
    的过渡效果。鼠标停留在盒子上以观察这些属性是如何变化的。
  </p>
  <div class="box">示例</div>
</body>
```

#### CSS

```css
.box {
  border-style: solid;
  border-width: 1px;
  display: block;
  width: 100px;
  height: 100px;
  background-color: #0000ff;
  transition:
    width 2s,
    height 2s,
    background-color 2s,
    rotate 2s;
}

.box:hover {
  background-color: #ffcccc;
  width: 200px;
  height: 200px;
  rotate: 180deg;
}
```

### 当属性值列表长度不一致时

如果任意属性值列表的长度比其他属性值列表要短，则其中的值会重复使用以便匹配。例如：

```css
div {
  transition-property: opacity, left, top, height;
  transition-duration: 3s, 5s;
}
```

将视为：

```css
div {
  transition-property: opacity, left, top, height;
  transition-duration: 3s, 5s, 3s, 5s;
}
```

类似地，如果某个属性的值列表长于 `transition-property` 的，将被截短。例如：

```css
div {
  transition-property: opacity, left;
  transition-duration: 3s, 5s, 2s, 1s;
}
```

将按下面这样处理：

```css
div {
  transition-property: opacity, left;
  transition-duration: 3s, 5s;
}
```

### 高亮菜单过渡效果

CSS 的一个常见用途是当鼠标悬停在菜单上时高亮此菜单。很容易使用过渡效果来让它们更具有吸引力。

首先，我们使用 HTML 建立菜单：

### HTML

```html
<nav>
  <a href="#">主页</a>
  <a href="#">关于</a>
  <a href="#">联系我们</a>
  <a href="#">链接</a>
</nav>
```

然后，我们使用 CSS 实现菜单的视觉效果：

```css
nav {
  display: flex;
  gap: 0.5rem;
}

a {
  flex: 1;
  background-color: #333;
  color: #fff;
  border: 1px solid;
  padding: 0.5rem;
  text-align: center;
  text-decoration: none;
  transition: all 0.5s ease-out;
}

a:hover,
a:focus {
  background-color: #fff;
  color: #333;
}
```

这段 CSS 代码建立了菜单的外观，当元素处于 `:hover` 和 `:focus` 状态时，背景和文本颜色都会改变：

这个 CSS 设置了菜单的外观，在`:hover`时，菜单里的元素的文字、颜色及背景色都发生了变化。

JavaScript 示例
-------------

>
> \*\* 备注：\*\* 在以下场景之后，应注意过渡的使用：
>
>
> * 使用 `.appendChild()` 向 DOM 中添加元素
> * 移除元素的 `display: none;` 属性
>
>
> 这就好像初始状态从未发生过，元素一直处于最终状态一样。克服这个限制的简单方法是在改变你打算过渡到的 CSS 属性之前应用若干毫秒的 `setTimeout()` 函数。
>
>
>

### 过渡让 JavaScript 效果更平滑

过渡可以使事情看起来更顺畅，而不需要对你的 JavaScript 功能做任何处理。示例如下：

```html
<p>随便点击某处来移动球</p>
<div id="foo" class="ball"></div>
```

使用 JavaScript 将球移动到一个位置：

```js
const f = document.getElementById("foo");
document.addEventListener(
  "click",
  (ev) => {
    f.style.transform = `translateY(${ev.clientY - 25}px)`;
    f.style.transform += `translateX(${ev.clientX - 25}px)`;
  },
  false,
);
```

使用 CSS 来平滑移动，只需简单地添加一个过渡效果：

```css
.ball {
  border-radius: 25px;
  width: 50px;
  height: 50px;
  background: #c00;
  position: absolute;
  top: 0;
  left: 0;
  transition: transform 1s;
}
```

### 检测渐变的开始和完成

你可以使用 `transitionend` 事件来检测某动画是否结束运行，它是一个 `TransitionEvent` 对象，除了一般的 `Event` 对象外，还有两个额外属性：

`propertyName`

一个字符串，表示过渡完成的 CSS 属性的名称。

`elapsedTime`

一个浮点数，表示在事件发生时，过渡已经运行了多少秒。这个值不受 `transition-delay` 值的影响。

像往常一样，你可以使用 `addEventListener()` 方法来监控这个事件：

```js
el.addEventListener("transitionend", updateTransition, true);
```

使用 `transitionrun` (en-US)（在任何延迟之前触发）和 `transitionstart`（在任何延迟之后触发）检测一个过渡的开始，方式相同：

```js
el.addEventListener("transitionrun", signalStart, true);
el.addEventListener("transitionstart", signalStart, true);
```

**备注：** 如果在过渡完成之前，因为元素变为 `display``: none`，或者动画属性的值被改变，而中止了过渡，则 `transitionend` 事件不会触发。

规范
--

| Specification |
| --- |
| CSS Transitions  |

参见
--

* `TransitionEvent` 接口和 `transitionend` 事件
* 使用 CSS 动画


坐标系 - CSS：层叠样式表

坐标系
===

在图形上下文中指定像素的位置时（就像代数中指定坐标系一样），像素的位置是相对于上下文中的一个固定点定义的，这个固定点称为原点。位置指定为沿上下文每个维度从原点偏移的像素数。

本指南介绍了 CSS 对象模型使用的标准坐标系。这些坐标系通常只是在原点位置上有所不同。

维度
--

在 Web 技术使用的坐标系中，按照惯例，水平偏移量称为 *x 坐标*，负值表示在原点左侧，正值表示在原点右侧。*y 坐标*指定垂直偏移，负值表示在原点之上，正值表示在原点之下。

在 web 中，默认的原点是给定上下文的左*上*角（Y 坐标正值位于原点下方）。请注意，这与大多数数学模型不同，在大多数数学模型中，原点位于左*下*角，Y 坐标的正值位于原点之上。

在使用第三维度将物体从前向后分层时，我们使用 z 轴。z 轴从查看器一直延伸到屏幕表面。CSS z-index 属性会影响定位元素在此轴线上的位置，从而产生远离或朝向观众的效果。

**备注：** 实际上，使用 CSS 属性（如 `transform`）可以改变这些坐标系的定义和方向。不过，我们现在只讨论标准坐标系。

标准 CSS 对象模型坐标系
--------------

CSS 对象模型使用四种标准坐标系。为了帮助直观地理解这些主要坐标系，下图显示了一台显示器，显示器上有一个浏览器窗口，窗口中的内容滚动到了视口之外。在视口外滚动的页面内容在浏览器窗口上方显示为半透明，以指示“页面”坐标的原点在哪里。“客户端”、“页面”和“视口”坐标系的原点已突出显示。

![电脑显示器与浏览器窗口的示意图，浏览器窗口包含视口以外的内容。标签显示了页面、屏幕和视口坐标的原点。](/zh-CN/docs/Web/CSS/CSSOM_view/Coordinate_systems/css-coords.svg)

### 偏移

使用“偏移”模型指定的坐标使用的是被检查元素或发生事件的元素的左上角。

例如，当发生鼠标事件时，事件的 `offsetX` 和 `offsetY` 属性中指定的鼠标位置相对于事件发生节点的左上角。原点的嵌入距离由 `padding-left` 和 `padding-top` 指定。

### 视口

“视口”（或“客户端”）坐标系以发生事件的视口或浏览上下文的左上角为原点。这就是呈现文档的整个视图区域。

例如，在台式电脑上，`MouseEvent.clientX` 和 `MouseEvent.clientY` 属性表示事件发生时鼠标光标相对于 `window` 左上角的位置。使用触控笔或指针时，触摸事件中的 `Touch.clientX` 和 `Touch.clientY` 坐标相对于同一原点。

窗口的左上角始终是 `(0，0)`，与文档内容或任何滚动无关。换句话说，滚动文档会改变文档中给定位置的视口坐标。

### 页面

“页面”坐标系给出了一个像素相对于整个渲染文档左上角的位置。这意味着用户在文档中横向或纵向滚动元素后，除非元素通过布局变化移动，否则文档中元素的某一点将保持相同的坐标。

鼠标事件的 `pageX` 和 `pageY` 属性提供了事件发生时鼠标相对于文档左上角的位置。触摸事件中的 `Touch.pageX` 和 `Touch.pageY` 坐标相对于同一原点。

### 屏幕

最后，来介绍“屏幕”模型，原点是用户屏幕空间的左上角。该坐标系中的每个点都代表一个逻辑像素，因此每个坐标轴上的值都以整数递增或递减。如果文档中包含的窗口被移动，或者用户的屏幕几何形状发生变化（通过改变显示分辨率或在系统中添加或删除显示器），文档中给定点的位置就会发生变化。

`MouseEvent.screenX` 和 `MouseEvent.screenY` 属性给出了鼠标事件相对于屏幕原点的位置坐标。触摸事件中的 `Touch.screenX` 和 `Touch.screenY` 坐标相对于同一原点。

示例
--

让我们来看一个在元素中记录鼠标坐标的示例。每当鼠标进入内部盒子、在内部盒子中移动或退出内部盒子时，都会在四个可用系统中的每个系统中记录当前鼠标坐标来处理事件。

### JavaScript

在 JavaScript 中，代码通过调用 `addEventListener()`、`mouseenter`、`mousemove` 和 `mouseleave` 设置事件处理器。对于每个事件，我们都会调用 `setCoords()` 函数，该函数会将每个系统的坐标设置到 `<p>` 元素的内部文本中。

```js
const log = document.querySelector(".log");
const inner = document.querySelector(".inner");

function setCoords(e) {
  log.innerText = `
 偏移 X/Y：${e.offsetX}, ${e.offsetY}
 视口 X/Y：${e.clientX}, ${e.clientY}
 页面 X/Y：${e.pageX}, ${e.pageY}
 屏幕 X/Y：${e.screenX}, ${e.screenY}`;
}

inner.addEventListener("mousemove", setCoords);
inner.addEventListener("mouseenter", setCoords);
inner.addEventListener("mouseleave", setCoords);
```

### HTML

HTML 中包含一个 `"log"` 类的 `<p>` 元素，用于显示鼠标事件的数据。

```html
<div class="outer">
  <div class="inner">
    <p class="log">在这里移动鼠标以查看坐标</p>
  </div>
</div>
```

### CSS

用于包含盒子的 `"outer"` 类特意设置得很宽，以便在滚动内容时查看鼠标坐标的效果。`"inner"` 段落用于跟踪和记录鼠标事件。

```css
.outer {
  width: 1000px;
}

.inner {
  font-family: monospace;
  position: relative;
  width: 500px;
  height: 150px;
  top: 25px;
  left: 100px;
  background-color: darkblue;
  color: white;
  cursor: crosshair;
  user-select: none;
}

.log {
  position: relative;
  width: 100%;
  text-align: center;
}
```

### 结果

在这里，你可以看到实际效果。当鼠标在蓝色盒子内移动时，观察鼠标的 X 和 Y 坐标值在不同坐标系中的变化。

参见
--

* 使用 CSS 变换：如何改变坐标系
* 鼠标事件的坐标：
    + `MouseEvent.offsetX` 和 `MouseEvent.offsetY`
    + `MouseEvent.clientX` 和 `MouseEvent.clientY`
    + `MouseEvent.pageX` 和 `MouseEvent.pageY`
    + `MouseEvent.screenX` 和 `MouseEvent.screenY`
* 触摸事件的坐标：
    + `Touch.clientX` 和 `Touch.clientY`
    + `Touch.pageX` 和 `Touch.pageY`
    + `Touch.screenX` 和 `Touch.screenY`


使用 CSS 计数器 - CSS：层叠样式表

使用 CSS 计数器
==========

**CSS 计数器**可让你根据内容在文档中的位置调整其显示的外观。例如，你可以使用计数器自动为网页中的标题编号，或者更改有序列表的编号。

本质上 CSS 计数器是由 CSS 维护的变量，这些变量可能根据 CSS 规则跟踪使用次数以递增或递减。你可以自定义一个计数器，也可以修改 `list-item` 这一默认生成的应用于所有有序列表的计数器。

使用计数器
-----

在使用计数器之前，必须使用 `counter-reset` 属性初始化计数器的值。计数器可通过 `counter-increment` 属性指定其值为递增或递减。当前计数器的值可通过 `counter()` 或 `counters()` 函数显示出来，这通常会在伪元素的 `content` 属性中使用。

请注意，计数器只能在可以生成盒子的元素中使用（设置或重设值、递增）。例如，如果一个元素被设置为了 `display: none`，那么在这个元素上的任何计数器操作都会被忽略。

### 操作计数器的值

在使用计数器之前，需要使用 `counter-reset` 属性来初始化它的值。这个属性也可用于指定计数器的初始值。

下面，我们将名为 `section` 的计数器初始化为默认值（0）。

```css
counter-reset: section;
```

你也可以同时初始化多个计数器，并可以指定其初始值。下面，我们将名为 `section` 和 `topic` 的计数器初始化为默认值，并将 `page` 计数器的初始值指定为 3。

```css
counter-reset: section page 3 topic;
```

在初始化之后，计数器的值就可以使用 `counter-increment` 来指定其为递增或递减。例如，下面声明了一个随着 `h3` 标签递增的 `section` 计数器。

```css
h3::before {
  counter-increment: section; /\* Increment the value of section counter by 1 \*/
}
```

你可以在计数器的名称后指定单次递增或递减的值（正数或负数）。

计数器的名称不可以为 `none`、`inherit` 或 `initial`，否则，相应的声明会被忽略。

### 显示计数器

计数器的值可以使用 `counter()` 或 `counters()` 函数以在 `content` 属性中显示。

例如，以下使用 `counter()` 声明的计数器会在每一个 `h3` 标题前面添加文本 `Section <number>:`，其中的 `<number>` 是十进制计数的值（默认显示样式）：

```css
h3::before {
  counter-increment: section; /\* Increment the value of section counter by 1 \*/
  content: "Section " counter(section) ": "; /\* Display counter value in default style (decimal) \*/
}
```

当不需要包含父级上下文的编号，而仅需要嵌套内容的编号时，应使用 `counter()` 函数。例如，以下示例的每一个嵌套内容的计数都从 1 开始：
```

1 One
  1 Nested one
  2 Nested two
2 Two
  1 Nested one
  2 Nested two
  3 Nested three
3 Three
```

当需要同时包含父级上下文和嵌套内容的编号时，应使用 `counters()` 函数。例如，以下示例的每一个嵌套内容会包含父级编号：
```

1 One
  1.1 Nested one
  1.2 Nested two
2 Two
  2.1 Nested one
  2.2 Nested two
  2.3 Nested three
3 Three
```

`counter()` 函数有两种形式： `counter(<counter-name>)` 和 `counter(<counter-name>, <counter-style>)`。生成的文本是伪元素范围内指定名称的最内层计数器的值。

`counters()` 函数也同样有两种形式：`counters(<counter-name>, <separator>)` 和 `counters(<counter-name>, <separator>, <counter-style>)`。生成的文本由在伪元素范围内所有指定名称的计数器的值组成。这些值从最外层到最内层，使用指定的字符串（`<separator>`）分隔。

 以上两个函数均可以使用指定的 `<counter-style>` 来渲染其值（默认值为 `decimal`）。你也可以使用
 `list-style-type` 属性其他可选的值，或自定义样式。

基础示例和计数器嵌套示例这两个示例分别展示了 `counter()` 和 `counters()` 的使用方法。

### 反向计数器

反向计数器是一种用于递减（而非递增）的计数器。反向计数器可以通过在 `counter-reset` 属性中将计数器的名称使用 `reversed()` 函数包裹来创建。

反向计数器的默认初始值与元素的数量相同（不同于常规的默认初始值为 0 的计数器）。这使得实现从元素数量为初始值倒数到 1 的计数器变得更加容易。

例如，要创建一个名为 `section` 反向计数器（使用默认初始值），你只需要这样写：

```css
counter-reset: reversed(section);
```

你也可以指定它的初始值。

计数器的值会随着通过 `counter-increment` 属性指定的负数递减。

**备注：** 对于非反向计数器，你也仍然可以使用 `counter-increment` 属性实现递减。使用反向计数器的优点在于：其默认初始值可以自动根据元素数量生成，自动应用于有序列表的 `list-item` 计数器也可以借此反转编号。

### 有序列表（list item）计数器

使用 `<ol>` 元素创建的有序列表，会自动应用名为 `list-item` 的计数器。

和其他的计数器一样，其也是一个默认自增（+1）且初始值为 0 的计数器，对于反向计数器，则以元素数量为初始值，且默认自减（-1）。与自定义的计数器不同，`list-item` 是根据其是否为反向计数器而*自动*自增或自减的。

可以通过 CSS 修改 `list-item` 计数器应用在有序列表上的默认行为。例如，你可以改变默认初始值，或使用 `counter-increment` 改变递增或递减的方式。

示例
--

### 基础示例

以下示例会在每一个标题前添加一个“Section [the value of the counter]:”字符串。

#### CSS

```css
body {
  counter-reset: section; /\* Set a counter named 'section', and its initial value is 0. \*/
}

h3::before {
  counter-increment: section; /\* Increment the value of section counter by 1 \*/
  content: "Section " counter(section) ": "; /\* Display the word 'Section ', the value of
 section counter, and a colon before the content
 of each h3 \*/
}
```

#### HTML

```html
<h3>Introduction</h3>
<h3>Body</h3>
<h3>Conclusion</h3>
```

#### 结果

### 基础示例：反向计数器

以下示例与上一个类似，区别在于其使用了反向计数器。如果你的浏览器支持 `reversed()` 函数，其结果就会类似于这样：

![reversed counter](/zh-CN/docs/Web/CSS/CSS_counter_styles/Using_CSS_counters/reversed_headings_basic.png)

#### CSS

```css
body {
  counter-reset: reversed(
    section
  ); /\* Set a counter named 'section', and its initial value is 0. \*/
}

h3::before {
  counter-increment: section -1; /\* Decrement the value of section counter by 1 \*/
  content: "Section " counter(section) ": "; /\* Display the word 'Section ', the value of
 section counter, and a colon before the content
 of each h3 \*/
}
```

#### HTML

```html
<h3>Introduction</h3>
<h3>Body</h3>
<h3>Conclusion</h3>
```

#### 结果

### 一个更加复杂的示例

有时我们不需要让计数器在每一次递增时都显示其值，以下示例仅在链接的内容为空时将其替换为由计数器生成的值。

```css
:root {
  counter-reset: link;
}

a[href] {
  counter-increment: link;
}

a[href]:empty::after {
  content: "[" counter(link) "]";
}
```

#### HTML

```html
<p>See <a href="https://www.mozilla.org/"></a></p>
<p>Do not forget to <a href="contact-me.html">leave a message</a>!</p>
<p>See also <a href="https://developer.mozilla.org/"></a></p>
```

#### 结果

### 计数器嵌套示例

CSS 计数器对创建目录（多级有序列表）特别有用，因为其会在子元素中自动创建一个 CSS 计数器的实例。使用 `counters()` 函数，可以在不同级别的嵌套计数器之间可以插入分隔字符串。

#### CSS

```css
ol {
  counter-reset: section; /\* Creates a new instance of the
 section counter with each ol
 element \*/
  list-style-type: none;
}

li::before {
  counter-increment: section; /\* Increments only this instance
 of the section counter \*/
  content: counters(section, ".") " "; /\* Combines the values of all instances
 of the section counter, separated
 by a period \*/
}
```

#### HTML

```html
<ol>
  <li>item</li>          <!-- 1 -->
  <li>item               <!-- 2 -->
    <ol>
      <li>item</li>      <!-- 2.1 -->
      <li>item</li>      <!-- 2.2 -->
      <li>item           <!-- 2.3 -->
        <ol>
          <li>item</li>  <!-- 2.3.1 -->
          <li>item</li>  <!-- 2.3.2 -->
        </ol>
        <ol>
          <li>item</li>  <!-- 2.3.1 -->
          <li>item</li>  <!-- 2.3.2 -->
          <li>item</li>  <!-- 2.3.3 -->
        </ol>
      </li>
      <li>item</li>      <!-- 2.4 -->
    </ol>
  </li>
  <li>item</li>          <!-- 3 -->
  <li>item</li>          <!-- 4 -->
</ol>
<ol>
  <li>item</li>          <!-- 1 -->
  <li>item</li>          <!-- 2 -->
</ol>
```

#### 结果

规范
--

| Specification |
| --- |
| CSS Lists and Counters Module Level 3 # auto-numbering |

参见
--

* `counter-reset`
* `counter-set`
* `counter-increment`
* `@counter-style`


使用 box 值指定形状 - CSS：层叠样式表

使用 box 值指定形状
============

创建形状的一个简单方法是使用 CSS 盒模型中的值。本文将解释如何执行此操作

允许作为形状值的 box 值为：

* `content-box`
* `padding-box`
* `border-box`
* `margin-box`

box 值还支持 `border-radius` 值，这意味着你的页面中可以有带曲线边框的内容，并且你的形状可以跟随创建的形状。

CSS 盒模型
-------

上面列出的值对应于 CSS 盒模型的各个部分。CSS 中的盒子具有内容、外边距、边框和内边距。

![包含外边距、边框、内边距和内容盒子的盒模型](/zh-CN/docs/Web/CSS/CSS_shapes/From_box_values/box-model.png)

通过对形状使用 box 值，我们可以将内容环绕在这些值定义的边上。在下面的所有示例中，我都使用了一个元素，该元素具有外边距、边框和内边距，以便你可以看到内容的不同流动方式。

### margin-box

`margin-box` 是由外部边界边定义的形状，包括形状的角半径（如果 `border-radius` 已用于定义元素）。

在下面的示例中，我们有一个圆形的紫色项，它是一个带有高度、宽度和背景色的 `<div>` 项。通过设置 `border-radius` 属性为 `border-radius: 50%` 属性，创建了一个圆形。由于元素具有外边距，你可以看到内容围绕圆形流动，并且应用了圆形的外边距。

### border-box

`border-box` 值是由外部边框边缘定义的形状。此形状遵循边框外部的所有常规边框半径形状规则。即使没有使用 CSS `border` 属性，仍然有边框。在这种情况下，它将与由外部填充边定义的形状 `padding-box` 相同。

在下面的示例中，你可以看到文本现在是如何遵循由边框创建的行的。改变边框大小，内容也会随之改变。

### padding-box

`padding-box` 值定义由外边距边缘包围的形状。此形状遵循边框内部的所有常规边框半径形状规则。如果没有外边距，则 `padding-box` 与 `content-box` 相同。

### content-box

`content-box` 值定义由外部内容边缘包围的形状。此框的每个角半径都是 0 或 border-radius、border-width、padding 中的较大值。这意味着这里不可能有负值。

什么时候使用 box 值
------------

使用 box 值是创建形状的一种简单方法，但这本质上只适用于可以使用受良好支持的 `border-radius` 属性定义的非常简单的形状。上面显示的示例显示了一个这样的用法。可以使用边框半径创建圆形，然后在其周围绘制文本。

不过，只需使用这种简单的技术，你就能创造出一些有趣的效果。在本节的最后一个示例中，我左右浮动了两个元素，在最靠近文字的方向上，每个元素的边框半径都是 100%。

对于更复杂的形状，你需要使用基本形状 (en-US)中的一种作为值，或者根据本节其他指南中涉及的图像定义你的形状。