1. 引言
在 CSS 1 和 2 级中,诸如 background-image 属性中使用的图像值,只能通过单个 URL 值提供。本模块引入了表示 2D 图像的其他方式,例如作为 渐变。
本模块还定义了若干用于 操作位图图像,以及用于在 CSS 布局算法确定的盒模型内 调整尺寸 或 定位 替换元素的属性。它还以通用方式定义了针对图像及其他类似替换元素的 CSS 尺寸调整算法。
本小节(上方)是非规范性的。
1.1. 模块交互
本模块定义并扩展了在 [CSS-VALUES-3] 中定义的 <image> 值类型。它还在 CSS1 和 CSS2 的 background-image、cursor 和 list-style-image 定义中将 <url> 类型替换为 <image>,并为 content 属性值增加 <image> 作为 <url> 的替代选项。预计 CSS2.1 之后的 CSS 规范将在预期 2D 图像的地方使用 <image> 标记来代替 <url>。(参见例如 [CSS3BG]。)
本模块定义的属性中,仅有 image-rendering 适用于 ::first-line 和 ::first-letter。
1.2. 值的定义
本规范遵循来自 [CSS2] 的 CSS 属性定义约定,并使用来自 [CSS-VALUES-3] 的 值定义语法。本规范中未定义的值类型,在 CSS 2 级修订版 1 [CSS2] 中定义。其他 CSS 模块可能会扩展这些值类型的定义:例如 [CSS-VALUES-3] 在与本模块结合使用时,添加了 initial 关键字作为可能的属性值。
除了定义中列出的属性特定值外,本规范中定义的所有属性也都接受 CSS 全局关键字 作为其属性值。为了可读性,未明确重复列出。
2. 图像值:<image> 类型
<image> 值类型表示一个 2D 图像。它可以是一个 URL 引用 或一个 颜色渐变。其语法为
<image> = <url> | <gradient>
<image> 可用于许多 CSS 属性,包括 background-image、list-style-image 和 cursor 属性 [CSS2](其中它替换了属性值中的 <url> 组件)。
在某些情况下,图像是无效的,例如指向非有效图像格式的 <url>,或者加载失败的情况。无效图像 渲染为一个纯色的 透明 图像,且不具有 自然尺寸。然而,无效图像 在某些上下文中可能会触发错误处理子句。例如,list-style-image 中的 无效图像 会被视为 none,从而允许 list-style-type 取代其渲染。[CSS2]
当图像正在加载时,称为 加载中的图像。加载中的图像 不是 无效图像,但行为相似:它们被渲染为一个纯色的 透明 图像,且不具有 自然尺寸,并可能在提供此类机制的上下文中触发后备渲染,但不得触发后备资源的加载。或者,如果 加载中的图像 正好替换了已经加载完成的图像(例如由于文档或样式表的更改),且 UA 正在追踪此信息,它可能会继续渲染已加载完成的图像,以替代 加载中的图像。
部分加载的图像(已知其 自然尺寸,但图像数据未完全加载)可以被视为 加载中的图像,或者视为已加载并以部分数据渲染的图像。例如,UA 可能会在 GIF 的第一遍像素数据加载后立即原地渲染交错式 GIF,甚至在解析出图像头(包含尺寸数据)后立即进行,并随着更多数据的加载刷新渲染;或者它可能会等待整个图像加载完成后再使用它。
一个 计算后的 <image> 值,即为 指定值,其中所有的 <url>、<color> 和 <length> 均已计算得出。
2.1. 图像引用:url() 符号
指明图像的最简单方式是通过 URL 引用图像文件。这可以通过 [CSS-VALUES-3] 中定义的 url() 符号来实现。
如果 UA 无法下载、解析或以其他方式成功将 URL 处的内容显示为图像(即如果图像不是 完全可解码的),则必须将其视为 无效图像。
2.1.1. 歧义引用或图像 URL
URL 在许多上下文中用于多种类型的资源,因此可以有多种解读方式。通常,URL 出现的上下文使得如何解读资源变得明确,但在某些实例中可能会有歧义。例如,一个指向 SVG 文件的 mask-image <url> 值,既可被解读为对该文件中某元素的引用,也可被解读为 <image>。
一个 歧义图像 URL 是一个既可被解读为 <image> 又可被解读为元素引用的 <url> 值。如果 歧义图像 URL 是一个 仅包含片段的 URL,则它必须被视为元素引用。否则,如果 歧义图像 URL 包含的片段引用了该资源内的一个元素,且该元素类型适用于 <url> 出现的上下文(例如 mask-image 属性对应的 mask 元素),则将其解读为元素引用。否则,将其视为 <image>。
使用 歧义图像 URL 概念的规范必须定义哪些元素是有效的 URL 引用,以及可能适用的任何附加条件。
<mask id="foo"> 元素,或者指向 <g id="foo"> 元素,并依赖 :target 伪类来改变其作为图像的渲染方式。当这种情况发生时,将加载并检查 "icon.svg" 文件;如果 #foo 元素确实是一个 mask,则 url() 被视为对该元素的引用;否则,它被解读为图像。
2.1.2. 图像元数据
图像可以包含诸如分辨率和方向等元数据,这些元数据指定了如何渲染图像。某些图像格式在元数据可置于文件的位置上具有灵活性;然而,如果元数据出现在实际图像数据 之后,则会损害 UA 对图像进行“渐进式解码”并在图像数据流式传输时进行显示的能力。
为了减少此问题的影响
-
作者 必须 生成图像文件,使得此类元数据出现在图像文件中的图像数据之前。(注:这已是大多数图像的默认设置。)
-
用户代理 应该 忽略文件中图像数据开始之后出现的任何影响布局的元数据(例如方向或分辨率)。(注:此规则不影响不影响布局的元数据,例如色彩空间信息。)
如果用户代理无法根据元数据在文件中的位置来忽略它(例如,如果所使用的解码器不报告元数据在文件中的位置),则在所有情况下都 必须 使用该元数据。(特别是,不能仅在图像“较小”且整个文件下载较快时使用元数据,而在图像较大且元数据在图像开始显示后很久才下载时忽略它。)
3. 渐变
渐变是一种从一种颜色平滑过渡到另一种颜色的图像。它们通常用于背景图像、按钮及许多其他事物中的细微阴影。本节中描述的 渐变函数 允许作者以简洁的语法指定此类图像,以便 UA 在渲染页面时自动生成该图像。<gradient> 的语法为
<gradient> = <linear-gradient()> | <repeating-linear-gradient()> | <radial-gradient()> | <repeating-radial-gradient()>
与本规范中定义的其他 <image> 类型一样,渐变可用于任何接受图像的属性中。例如
-
background: linear-gradient(white, gray); -
list-style-image: radial-gradient(circle, #006, #00a 90%, #0000af 100%, white 100%)
渐变绘制在具有 具体对象尺寸 的盒中,称为 渐变盒。然而,渐变本身不具有 自然尺寸。
渐变是通过定义 起始点 和 结束点 来指定的,它们构成了 渐变线(根据渐变类型,几何上可能是一条线、一条射线或一条螺旋线),然后沿着该线在各点指定颜色。这些颜色平滑混合以填充该线的其余部分,然后每种类型的渐变定义如何使用 渐变线 的颜色来生成实际的渐变。
3.1. 线性渐变:linear-gradient() 符号
线性渐变是通过指定一条直线 渐变线,并沿着该线放置几种颜色来创建的。图像的构建方式是创建一个无限画布,并用垂直于渐变线的线条进行绘制,绘制线条的颜色即为两条线相交处渐变线的颜色。这产生了一种从一种颜色平滑过渡到下一种颜色,并沿指定方向前进的效果。
3.1.1. linear-gradient() 语法
CSS 中的 linear-gradient() 符号指定了一个线性渐变。其语法如下
<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]
函数的第一个参数指定 渐变线,它赋予渐变一个方向并决定颜色停止点如何定位。它可以被省略;如果省略,则默认为 to bottom。
渐变线 的方向可以通过两种方式指定
- 使用 <angle>
-
对于此参数,0deg 指向上方,正角度表示顺时针旋转,因此 90deg 指向右侧。
如果 <angle> 为零,单位标识符可以省略。
- 使用关键字
-
如果参数为 to top、to right、to bottom 或 to left,则 渐变线 的角度分别为 0deg、90deg、180deg 或 270deg。
如果参数改为指定盒的一个角(例如 to top left),则 渐变线 必须倾斜,使其指向与所指定角相同的象限,且垂直于连接 渐变盒 两个相邻角的线。这会导致 50% 处的颜色停止点与两个相邻角相交(参见 示例)。
从 渐变盒 的中心开始,沿指定角度向两个方向延伸一条线。结束点是 渐变线 上的某点,在此点处,一条垂直于 渐变线 的线将以指定方向与 渐变盒 的角相交。起始点的确定方式相同,但在相反的方向上。
注: 预计本模块的下一级将提供相对于当前文本方向和书写模式定义渐变方向的能力。
-
A 是定义渐变线方向的角度(在任何象限中),使得 0 度指向上方,正角度表示顺时针旋转,
-
W 是渐变盒的宽度,
-
H 是渐变盒的高度,
abs(W * sin(A)) + abs(H * cos(A))
渐变的颜色停止点通常位于 起始点 和 结束点 之间的 渐变线 上,但这并非必须:渐变线 向两个方向无限延伸。起始点和结束点仅是任意的位置标记,起始点定义了在指定颜色停止点时 0%、0px 等所处的位置,而结束点定义了 100% 所处的位置。颜色停止点允许位于 0% 之前或 100% 之后。
线性渐变在任何一点的颜色,通过找到穿过该点且垂直于 渐变线 的唯一线来确定。该点的颜色即为该线与 渐变线 相交处的颜色。
3.1.2. 线性渐变示例
以下所有 linear-gradient() 示例均假定为应用于一个 200px 宽、100px 高的盒的背景。
linear-gradient(yellow, blue); linear-gradient(to bottom, yellow, blue); linear-gradient(180deg, yellow, blue); linear-gradient(to top, blue, yellow); linear-gradient(to bottom, yellow 0%, blue 100%);

linear-gradient(135deg, yellow, blue); linear-gradient(-45deg, blue, yellow);

linear-gradient(to top right, red, white, blue)
3.2. 径向渐变:radial-gradient() 符号
在径向渐变中,颜色不是像线性渐变那样从 渐变盒 的一侧平滑过渡到另一侧,而是从单一点发出,并以圆形或椭圆形平滑地向外扩散。
radial-gradient() 符号通过指明渐变中心(0% 椭圆所在处)以及 结束形状(100% 椭圆)的大小和形状来指定径向渐变。颜色停止点以列表形式给出,就像 linear-gradient() 一样。从 渐变中心 开始并向 结束形状 前进(并可能超出),绘制均匀缩放的同心椭圆,并根据指定的颜色停止点进行着色。
3.2.1. radial-gradient() 语法
径向渐变语法为
<radial-gradient()> = radial-gradient( [ <radial-gradient-syntax> ] )
<radial-gradient-syntax> =
[ <radial-shape> || <radial-size> ]? [ at <position> ]? ,
<color-stop-list>
<radial-size> = <radial-extent> | <length [0,∞]> | <length-percentage [0,∞]>{2}
<radial-extent> = closest-corner | closest-side | farthest-corner | farthest-side
<radial-shape> = circle | ellipse
注: 未来级别可能会增加移动渐变焦点的能力,类似于原始的 -webkit-gradient() 函数。请参阅在 Issue 1575 中跟踪的关于 "from <position>" 和 "from offset <offset>" 的 提案。
参数定义如下
- <position>
- 确定渐变的 中心。<position> 值类型(也用于 background-position)在 [CSS-VALUES-3] 中定义,并使用中心点作为对象区域、渐变盒 作为定位区域进行解析。如果此参数被省略,则默认为 center。
- <radial-shape>
- 可以是 circle 或 ellipse;分别确定渐变的 结束形状 是圆形还是椭圆形。如果 <radial-shape> 被省略,如果 <radial-size> 是单个 <length>,则 结束形状 默认为圆形,否则默认为椭圆形。
- <radial-size>
- 确定渐变 结束形状 的大小。如果省略,则默认为 farthest-corner。它可以显式给出或通过关键字给出。为了定义关键字,应考虑 渐变盒 的边缘向两个方向无限延伸,而不是有限的线段。
如果结束形状是椭圆形,其轴与水平和垂直轴对齐。
circle 和 ellipse 渐变均接受以下 <radial-extent> 值
- closest-side
- 结束形状 的大小调整为正好接触距离渐变中心最近的 渐变盒 的边。如果形状是椭圆形,则正好接触每个维度中最接近的边。
- farthest-side
- 与 closest-side 相同,不同之处在于 结束形状 的大小是基于最远的边来设定的。
- closest-corner
- 结束形状 的大小调整为穿过距离渐变中心最近的 渐变盒 的角。如果形状是椭圆形,则 结束形状 的长宽比与指定 closest-side 时相同。
- farthest-corner
- 与 closest-corner 相同,不同之处在于 结束形状 的大小是基于最远的角来设定的。如果形状是椭圆形,则 结束形状 的长宽比与指定 farthest-side 时相同。
如果 <radial-shape> 被指定为 circle 或被省略,则 <radial-size> 可以显式地作为
- <length [0,∞]>
- 显式给出圆的半径。负值无效。
注: 这里不允许使用百分比;它们只能用于指定椭圆渐变的大小,不能用于圆形渐变。存在此限制是因为对于百分比应相对于哪个维度,有多个合理的答案。本模块的未来级别可能会提供用百分比调整圆大小的能力,可能对使用哪个维度有更明确的控制。
如果 <radial-shape> 被指定为 ellipse 或被省略,<radial-size> 可以改为显式地作为
- <length-percentage [0,∞]>{2}
- 显式给出椭圆的大小。第一个值表示水平半径,第二个值表示垂直半径。百分比值相对于 渐变盒 的相应维度。负值无效。
radial-gradient() = radial-gradient( [ [ circle || <length [0,∞]> ] [ at <position> ]? , | [ ellipse || <length-percentage [0,∞]>{2} ] [ at <position> ]? , | [ [ circle | ellipse ] || <radial-extent> ] [ at <position> ]? , | at <position> , ]? <color-stop-list> )
3.2.2. 放置颜色停止点
颜色停止点被放置在一条形状如射线的 渐变线 上(从一点开始并向一个方向无限延伸),类似于线性渐变的 渐变线。渐变线 的 起始点 位于渐变中心,并向右延伸,结束点 位于 渐变线 与 结束形状 相交的点。颜色停止点可以放置在 0% 之前的位置;尽管 渐变线 的负区域从未直接用于渲染,但放置在那里的颜色停止点可以通过插值或重复(参见 重复渐变)影响 渐变线 上非负位置的颜色。例如,radial-gradient(red -50px, yellow 100px) 产生的椭圆渐变在中心以淡红色-橙色(具体为 #f50)开始,并过渡到黄色。大于 100% 的位置仅仅指定了一个距离渐变中心相应更远的位置。
渐变在任何一点的颜色,通过首先找到穿过该点且具有与结束形状相同的中心、方向以及长短轴比例的唯一椭圆来确定。该点的颜色即为 渐变线 正向部分在该椭圆与之相交位置处的颜色。
3.2.3. 退化径向渐变
位置、大小和形状的某些组合将产生半径为 0 的圆或椭圆。如果中心位于 渐变盒 边缘且指定了 closest-side 或 closest-corner,或者如果大小和形状是显式给出的且任一半径为零,就会发生这种情况。在这些退化情况下,渐变必须渲染如下
- 如果 结束形状 是一个半径为零的圆
-
渲染为如同 结束形状 是一个半径为大于零的任意极小数的圆。这将使渐变看起来仍像一个圆。
- 如果 结束形状 的宽度为零(无论高度如何)
-
渲染为如同 结束形状 是一个高度为任意极大数且宽度为大于零的任意极小数的椭圆。这将使渐变看起来类似于一个水平线性渐变,并在椭圆中心镜像。这也意味着以百分比指定的所有颜色停止点位置都解析为 0px。
- 否则,如果 结束形状 的高度为零
-
渲染为如同 结束形状 是一个宽度为任意极大数且高度为大于零的任意极小数的椭圆。这将使渐变看起来像一个纯色图像,等于最后一个颜色停止点的颜色,如果它是重复渐变,则等于渐变的平均颜色。
3.2.4. 径向渐变示例
以下所有示例均应用于一个 200px 宽、100px 高的盒。
radial-gradient(yellow, green); radial-gradient(ellipse at center, yellow 0%, green 100%); radial-gradient(farthest-corner at 50% 50%, yellow, green);

radial-gradient(circle, yellow, green);

radial-gradient(red, yellow, green);

radial-gradient(closest-side at 20px 30px, red, yellow, green); radial-gradient(20px 30px at 20px 30px, red, yellow, green);

radial-gradient(closest-side circle at 20px 30px, red, yellow, green); radial-gradient(20px 20px at 20px 30px, red, yellow, green);

3.3. 重复渐变:repeating-linear-gradient() 和 repeating-radial-gradient() 符号
除了 linear-gradient() 和 radial-gradient(),本规范还定义了 repeating-linear-gradient() 和 repeating-radial-gradient() 值。这些符号采用相同的值,并与之前定义的非重复同类渐变解析方式相同。
<repeating-linear-gradient()> = repeating-linear-gradient( [ <linear-gradient-syntax> ] ) <repeating-radial-gradient()> = repeating-radial-gradient( [ <radial-gradient-syntax> ] )
然而在渲染时,颜色停止点会向两个方向无限重复,它们的位置会根据最后一个指定颜色停止点的位置与第一个指定颜色停止点的位置之差的倍数进行平移。例如,repeating-linear-gradient(red 10px, blue 50px) 等同于 linear-gradient(..., red -30px, blue 10px, red 10px, blue 50px, red 50px, blue 90px, ...)。请注意,最后一个颜色停止点和第一个颜色停止点总会在每组的边界处重合,如果渐变不是以相同的颜色开始和结束,这将产生尖锐的过渡。
repeating-linear-gradient(red, blue 20px, red 40px)

repeating-radial-gradient(red, blue 20px, red 40px)

repeating-radial-gradient(circle closest-side at 20px 30px, red, yellow, green 100%, yellow 150%, red 200%)

如果第一个和最后一个颜色停止点之间的距离不为零,但小到实现知道输出设备的物理分辨率不足以准确渲染该渐变,则实现必须 找到渐变的平均颜色,并将渐变渲染为等于该平均颜色的纯色图像。
如果第一个和最后一个颜色停止点之间的距离为零(或因实现限制而四舍五入为零),实现必须 找到一个渐变的平均颜色,该渐变具有相同数量和颜色的颜色停止点,但第一个和最后一个颜色停止点之间相隔任意非零距离,且剩余的颜色停止点在它们之间等距分布。然后,它必须将该渐变渲染为等于该平均颜色的纯色图像。
如果重复径向渐变的结束形状的宽度不为零而高度为零,或者小到足以让实现知道输出设备的物理分辨率不足以准确渲染该渐变,则实现必须 找到该渐变的平均颜色,并将渐变渲染为等于该平均颜色的纯色图像。
注: 退化径向渐变 一节描述了当结束形状的宽度为零时如何进行调整。
若要 找到渐变的平均颜色,请执行以下步骤
-
定义 list 为一个初始为空的预乘 RGBA 颜色列表,并定义 total-length 为第一个和最后一个颜色停止点之间的距离。
-
对于每一对相邻的颜色停止点,定义 weight 为这两个颜色停止点之间距离的一半除以 total-length。将两个条目添加到 list,第一个条目通过表示预乘 sRGBA 格式中第一个颜色停止点的颜色并将所有分量缩放 weight 得到,第二个条目通过相同方式处理第二个颜色停止点得到。
-
按分量对 list 的条目求和以产生平均颜色,并返回它。
注: 与往常一样,实现可以使用它们希望的任何算法,只要它产生与上述相同的结果即可。
rgb(75%,50%,75%))repeating-linear-gradient(red 0px, white 0px, blue 0px);
以下渐变在正常情况下渲染效果与前一个相同(因为桌面显示器无法准确渲染相隔 1/10 像素的颜色停止点),但如果作者对出现渐变的元素应用了 "zoom:100;",则会渲染为正常的重复渐变
repeating-linear-gradient(red 0px, white .1px, blue .2px);
3.4. 定义渐变颜色
渐变中的颜色使用 颜色停止点(一个 <color> 和 渐变线 上的对应位置)以及 颜色过渡提示(颜色停止点 之间表示颜色过渡中点的位置)来指定,它们被放置在 渐变线 上,定义了线上每一点的颜色。(每个 渐变函数 定义了 渐变线 的形状和长度,以及其 起始点 和 结束点;见上文。)
整个渐变域中的颜色随后通过将它们绑定到渐变函数所指定的 渐变线 上的特定点来确定。UA 可能会对渐变颜色进行微小的“抖动”(在渐变线上随机交替单个像素及其附近的颜色),以实现更平滑的渐变。
3.4.1. 颜色停止点列表
颜色停止点 和 过渡提示 在 颜色停止点列表 中指定,该列表是两个或多个交替包含可选 过渡提示 的 颜色停止点
<color-stop-list> = <linear-color-stop> , [ <linear-color-hint>? , <linear-color-stop> ]# <linear-color-stop> = <color> <length-percentage>? <linear-color-hint> = <length-percentage>
百分比相对于 起始点 和 结束点 之间的 渐变线 长度进行解析,0% 位于起始点,100% 位于结束点。长度沿 渐变线 从 起始点 向 结束点 的方向测量。
颜色停止点 和 过渡提示 的位置通常放置在 起始点 和 结束点 之间,但这并非必须:渐变线向两个方向无限延伸,位置可以指定在 渐变线 上的任何地方。
当 颜色停止点 的位置被省略时,它会被自动分配一个位置。颜色停止点列表 中的第一个或最后一个 颜色停止点 分别被分配 渐变线 的 起始点 或 结束点。否则,它被分配在两个相邻停止点中间的位置。如果连续有多个停止点缺少位置,它们会在相邻的已定位停止点之间等距排列。详情参见 § 3.4.3 颜色停止点“修正”。
3.4.2. 为渐变线着色
在每个 颜色停止点 位置,渐变线 为该 颜色停止点 的颜色。在第一个 颜色停止点 之前,渐变线 为第一个 颜色停止点 的颜色,在最后一个 颜色停止点 之后,渐变线 为最后一个 颜色停止点 的颜色。在两个 颜色停止点 之间,渐变线 的颜色在两个 颜色停止点 的颜色之间进行插值,插值在 预乘 RGBA 空间 中进行。
默认情况下,这种插值是线性的——在两个 颜色停止点 之间距离的 25%、50% 或 75% 处,颜色是这两个停止点颜色的 25%、50% 或 75% 混合。
然而,如果在两个 颜色停止点 之间提供了 过渡提示,则插值是非线性的,并由该提示控制
注: 过渡提示 指定了“中间颜色”(两个周围颜色停止点颜色的 50% 混合)应放置的位置。当提示正好位于两个周围颜色停止点的中间时,上述插值算法恰好产生普通的线性插值。如果提示放置在其他任何地方,它会在周围颜色停止点之间产生平滑的指数曲线,而“中间颜色”准确出现在提示指定的位置。
如果多个 颜色停止点 位于相同位置,它们会产生从列表中第一个指定的停止点到最后一个指定的停止点极微小的过渡。实际上,颜色在该位置突然变化,而不是平滑过渡。
什么是“预乘”?
“预乘”颜色以 Alpha 通道被乘以颜色通道的形式编写,而不是独立处理。例如,一种半透明蓝色可以写为 ,其预乘表示为 [0, 0, 127.5, .5]。
使用预乘表示法而不是普通 rgba 表示法对颜色进行插值往往能产生更具吸引力的过渡,尤其是在从完全不透明的颜色过渡到完全透明的颜色时。
注意,透明度或颜色保持恒定的过渡(例如在 (不透明红色)和 (不透明蓝色),或者 (不透明红色)和 (透明红色)之间过渡)无论颜色插值是在预乘还是非预乘颜色空间中完成,结果都是完全相同的。只有当两个端点在颜色和透明度上都不同时,差异才会产生。
3.4.3. 颜色停止点“修正”
当解析每个 颜色停止点 的 使用值 位置时,必须按顺序应用以下步骤
- 如果第一个 颜色停止点 没有位置,将其位置设为 0%。如果最后一个 颜色停止点 没有位置,将其位置设为 100%。
- 如果 颜色停止点 或 过渡提示 的位置小于列表中排在其前的任何 颜色停止点 或 过渡提示 的指定位置,将其位置设为等于排在其前的所有 颜色停止点 或 过渡提示 的最大指定位置。
- 如果任何 颜色停止点 仍没有位置,则对于每一组没有位置的相邻 颜色停止点,设置它们的位置,使其在前后有位置的 颜色停止点 之间等距分布。
应用这些规则后,所有 颜色停止点 和 过渡提示 都将具有明确的位置和颜色,并且它们将按升序排列。
注: 建议作者在混合使用不同类型的单位(如 px、em 或 %)时要谨慎,因为这可能导致 颜色停止点 无意中试图移动到较早的停止点之前。例如,规则 background-image: linear-gradient(yellow 100px, blue 50%) 在背景区域高度至少为 200px 时不会触发修正。然而,如果高度为 150px,则蓝色 颜色停止点 的位置将等同于 75px,它位于黄色 颜色停止点 之前,并将被修正为 100px。此外,由于此类颜色停止点的相对顺序在执行布局前无法确定,因此它们在 动画 或 过渡 中将无法平滑插值。
1. linear-gradient(red, white 20%, blue) =1=> linear-gradient(red 0%, white 20%, blue 100%) 2. linear-gradient(red 40%, white, black, blue) =1,3=> linear-gradient(red 40%, white 60%, black 80%, blue 100%) 3. linear-gradient(red -50%, white, blue) =1,3=> linear-gradient(red -50%, white 25%, blue 100%) 4. linear-gradient(red -50px, white, blue) =1,3=> linear-gradient(red -50px, white calc(-25px + 50%), blue 100%) 5. linear-gradient(red 20px, white 0px, blue 40px) =2=> linear-gradient(red 20px, white 20px, blue 40px) 6. linear-gradient(red, white -50%, black 150%, blue) =1,2=> linear-gradient(red 0%, white 0%, black 150%, blue 150%) 7. linear-gradient(red 80px, white 0px, black, blue 100px) =2,3=> linear-gradient(red 80px, white 80px, black 90px, blue 100px)
4. CSS 中的图像与对象尺寸调整
CSS 中使用的图像可能来自多种来源:二进制图像格式(如 gif、jpeg 等)、专用标记格式(如 SVG)以及 CSS 特定格式(如本规范中定义的 linear-gradient() 值类型)。此外,文档可能包含许多其他类型的对象,例如视频、插件或嵌套文档。这些图像和对象(此后统称为 对象)可能向 CSS 提供多种类型的尺寸信息,也可能完全不提供。本节通用地定义了对象与 CSS 布局算法之间的尺寸协商模型。
4.1. 对象尺寸术语
为了定义此处理过程,我们定义了几个术语,以便于指代各种概念
- 自然尺寸
- 术语 自然尺寸 指的是 自然高度、自然宽度 和 自然长宽比(宽度与高度之比)的集合,每一个对于给定的 对象 可能存在也可能不存在。这些自然尺寸代表对象本身固有的首选尺寸;也就是说,它们不是使用该对象的上下文的函数。CSS 通常不定义如何找到自然尺寸。
位图图像是具有所有三种自然尺寸的 对象 的示例。为缩放而设计的 SVG 图像可能仅具有 自然长宽比;SVG 图像也可以仅以 自然宽度 或 高度 创建。本规范中定义的 CSS 渐变是根本没有 自然尺寸 的对象示例。另一个例子是嵌入的文档,例如 HTML 中的
iframe元素。许多 对象(如大多数图像)不能仅具有两个 自然尺寸,因为任何两个都会自动定义第三个。然而,某些类型的替换元素(如表单控件)可以具有 自然宽度 和 自然高度,但没有 自然长宽比。如果一个 对象 具有 退化的 自然长宽比(至少有一个部分为零或无穷大),则将其视为没有 自然长宽比。
如果一个 对象(例如图标)具有多种尺寸,则最大尺寸(按面积)被视为其 自然尺寸。如果它在该尺寸下具有多种长宽比,或者具有多种长宽比且没有尺寸,则使用最接近 默认对象尺寸 长宽比的长宽比。通过观察在使用 包含约束 拟合将其置于 默认对象尺寸 内时哪种长宽比产生最大面积来确定;如果多种尺寸对于最大面积平局,则选择最宽的尺寸作为其 自然尺寸。
- 指定大小
- 对象 的指定尺寸由 CSS 提供,例如通过 width 和 height 或 background-size 属性。指定尺寸可以是明确的宽度和高度、一组约束,或者是它们的组合。
- concrete object size (具体对象尺寸)
- 具体对象尺寸 是结合 对象 的 自然尺寸 和 指定尺寸 与使用它的上下文的 默认对象尺寸 的结果,产生一个具有绝对宽度和高度的矩形。
- 默认对象大小
- 默认对象尺寸 是一个具有绝对高度和宽度的矩形,当 自然尺寸 和 指定尺寸 都缺少维度时,用于确定 具体对象尺寸。
4.2. CSS⇋对象协商
CSS 中的 对象 通过以下 对象尺寸协商 算法进行尺寸调整和渲染
-
当文档中指定了对象(object)时,例如通过 background-image 属性中的 url() 值,或者
img元素上的src属性,CSS 会向该对象查询其自然尺寸(natural dimensions)。 -
利用自然尺寸、指定尺寸(specified size)以及该对象所处上下文的默认对象尺寸,CSS 会计算出一个具体对象尺寸(concrete object size)。(参见下一节。)这定义了对象将要渲染区域的大小和位置。
-
CSS 要求对象以具体对象尺寸进行自身渲染。当具体对象尺寸与对象的自然尺寸不同时,CSS 不定义对象如何渲染。对象可能会以某种方式调整自身以匹配具体对象尺寸,甚至为了满足其自身的尺寸约束而渲染得比具体对象尺寸更大或更小。
4.3. 具体对象尺寸解析
目前,缩放对象的规则在这些对象被使用的每个上下文中都有描述。本节定义了一些通用的缩放约束以及解析它们的方法,以便未来的规范可以引用它们,而不是在每个实例中重新定义尺寸解析。
4.3.1. 默认缩放算法
此默认缩放算法(default sizing algorithm)是一组通常用于查找对象的具体对象尺寸的规则。它解析了由对象的自然尺寸,以及未受约束的指定尺寸(或仅包含确定的宽度和/或高度的尺寸)所带来的同时约束。
一些对象缩放规则(例如 list-style-image 的规则)与默认缩放算法完全对应。其他规则(例如 border-image)会调用默认缩放算法,但在得出最终的具体对象尺寸之前还会应用额外的缩放规则。
默认缩放算法定义如下:
-
如果指定尺寸没有任何约束:
4.3.2. Cover 和 Contain 约束缩放
另外两种常见的指定尺寸是包含约束(contain constraint)和覆盖约束(cover constraint),两者均使用对象的首选纵横比针对指定的约束矩形(constraint rectangle)进行解析。
-
包含约束(contain constraint)的解析方法是:将具体对象尺寸设置为具有对象的自然纵横比的最大矩形,且其宽度和高度均不大于约束矩形的宽度和高度。
-
覆盖约束(cover constraint)的解析方法是:将具体对象尺寸设置为具有对象的自然纵横比的最小矩形,且其宽度和高度均不小于约束矩形的宽度和高度。
在这两种情况下,如果对象没有自然纵横比,则具体对象尺寸即为指定的约束矩形。
4.4. CSS 对象缩放示例
- background-image
- 计算背景具体对象尺寸的规则定义在 CSS2.1§14.2.1 和 CSS3BG§3.9 中。CSS2.1 使用没有指定尺寸的默认缩放算法,并以背景定位区域作为默认对象尺寸。[CSS2] 在 CSS3 中,background-size 属性可以给出缩放约束,从而调用默认缩放算法,或者包含或覆盖约束之一。如果 background-repeat 具有 round 值,具体对象尺寸会在后续步骤中进一步调整。[CSS3BG]
- list-style-image
- 计算列表样式图像具体对象尺寸的规则定义在 CSS2.1§12.5.1 中。它们使用没有指定尺寸的默认缩放算法,默认对象尺寸为 1em 的正方形。
- border-image
- 边框图像需进行两次缩放:首先,对整个图像进行缩放以确定切片点;然后,对切片进行缩放以装饰边框。第一次缩放操作定义在 CSS3BG§6.2 中,使用没有指定尺寸的默认缩放算法,并以边框图像区域作为默认对象尺寸。第二次操作定义在 CSS3BG§6.2 中:默认缩放算法用于确定每个切片的初始尺寸,并以相应的边框图像区域部分作为默认对象尺寸。默认情况下,指定尺寸与此默认对象尺寸匹配;但是 border-image-repeat 属性可以在一个或多个方向上放弃指定尺寸,并且还可以应用额外的舍入步骤。[CSS3BG]
- cursor
- 计算光标具体对象尺寸的规则定义在 CSS2.1 § 18.1: Cursors 中。默认对象尺寸是 UA 定义的尺寸,应基于 UA 操作系统上典型光标的大小。[CSS2]
- 内容
- 通过 CSS2.1 content 属性插入的对象是匿名替换元素,并以相同的方式进行缩放。[CSS2] 注意,此类匿名元素的所有非继承属性(包括 width、height 等)都设置为其初始值。
- 替换元素
- CSS 2.1 在章节 10.3.2、10.4、10.6.2 和 10.7 中定义了替换元素的缩放(包括通过 content 插入的生成内容)。[CSS2] 下面定义的 object-fit 属性定义了具体对象尺寸如何对应于元素的已用宽度和高度;默认情况下,它们是一致的。
4.5. 对象缩放:object-fit 属性
| 名称 | object-fit |
|---|---|
| 值 | fill | contain | cover | none | scale-down |
| 初始值 | 填充 (fill) |
| 应用于 | 替换元素 |
| 可继承 | 否 |
| 百分比 | 不可用 |
| 计算值 | 指定关键字 |
| 规范顺序 | 按语法 |
| 动画类型 | 离散 (discrete) |
object-fit 属性指定了如何将替换元素的内容拟合到其已用高度和宽度所建立的框中。
- fill
- 替换内容被缩放以填满元素的内容框:对象的具体对象尺寸即为元素的已用宽度和高度。
- contain
- 替换内容被缩放以在保持其自然纵横比的同时拟合在元素的内容框内:其具体对象尺寸被解析为针对元素已用宽度和高度的包含约束。
- cover
- 替换内容被缩放以在保持其自然纵横比的同时填满元素的整个内容框:其具体对象尺寸被解析为针对元素已用宽度和高度的覆盖约束。
- none(无)
- none:替换内容不会被缩放以适合元素的内容框:使用没有指定尺寸的默认缩放算法确定对象的具体对象尺寸,且默认对象尺寸等于替换元素的已用宽度和高度。
- scale-down
- scale-down:将内容缩放为如同指定了 none 或 contain 中的一种,取结果较小的具体对象尺寸。
如果内容未完全填满替换元素的内容框,则未填满的空间会显示替换元素的背景。由于替换元素总是将其内容裁剪至内容框,因此内容绝不会溢出。有关相对于内容框定位对象的信息,请参见 object-position 属性。
注意:object-fit 属性与 [SMIL10] 中的 fit 属性以及 [SVG11] 中 preserveAspectRatio 属性上的 <meetOrSlice> 参数具有相似的语义。
注意:根据对象尺寸协商(object size negotiation)算法,具体对象尺寸(或者在本例中为内容尺寸)并不直接缩放对象本身——它仅仅作为关于可见画布大小的信息传递给对象。如何在该尺寸内绘制取决于图像格式。特别是,光栅图像始终缩放到给定尺寸,而 SVG 则使用给定尺寸作为“SVG 视口”(SVG Viewport,由 SVG 定义的术语),然后使用根 <svg> 元素上多个属性的值来确定其自身如何绘制。
4.6. 对象定位:object-position 属性
| 名称 | object-position |
|---|---|
| 值 | <position> |
| 初始值 | 50% 50% |
| 应用于 | 替换元素 |
| 可继承 | 否 |
| 百分比 | 指代元素本身的宽度和高度 |
| 计算值 | 同 background-position |
| 规范顺序 | <position> 的水平分量,后跟垂直分量 |
| 动画类型 | 同 background-position |
object-position 属性决定了替换元素在其框内的对齐方式。<position> 值类型(也用于 background-position)定义在 [CSS-VALUES-3] 中,并使用具体对象尺寸作为对象区域,内容框作为定位区域进行解析。
注意:框中未被替换元素覆盖的区域将显示元素的背景。
5. 图像处理
5.1. 页面上的图像方向:image-orientation 属性
如果照片拍摄时相机侧放,或者文档在扫描仪中放置位置不正确,则生成的图像可能是“横向”的,甚至是上下颠倒的。image-orientation 属性提供了一种对图像源数据应用“带外”(out-of-band)旋转的方法,以正确调整图像方向。
| 名称 | image-orientation |
|---|---|
| 值 | from-image | none | [ <angle> || flip ] |
| 初始值 | from-image |
| 应用于 | 所有元素 |
| 可继承 | 是 |
| 百分比 | 不可用 |
| 计算值 | 指定的关键字或一个<angle>(经舍入和归一化,见文内说明),外加可选的 flip 关键字 |
| 规范顺序 | 按语法 |
| 动画类型 | 离散 (discrete) |
此属性对于实现者而言是可选的。
此属性指定在将元素图像用于文档之前需对其应用正交旋转。它适用于内容图像(例如替换元素和生成内容)、SVG 元素引用的图像源(例如 feImage),以及通过 CSS 规则应用的装饰性图像(例如 background-image 和其他 <image> 属性)。它不适用于文档之外的图像渲染,例如 UA 导航工具栏或菜单中的图标等。
注意:此属性不用于指定任意旋转或水平/垂直翻转图像等布局变换。(有关该功能的特性,请参见 [CSS-TRANSFORMS-1]。)在打印横向与纵向时也不需要用它来正确调整图像方向,因为该旋转是作为布局的一部分完成的。(参见 [CSS3PAGE]。)它仅应用于校正方向错误的图像。
值的含义如下:
- none(无)
- 不应用额外的旋转:图像按编码方式定向。
- from-image
- 如果图像在元数据(如 EXIF)中指定了方向,则该值计算为元数据指定的正确调整图像方向所需的角度。如有必要,该角度将按照上述 <angle> 值的描述进行舍入和归一化。如果元数据中未指定方向,则该值计算为 none。
注意:§ 2.1.2 图像元数据 对可以使用的元数据施加了一些限制。
- <angle> || flip
- 正的 <angle> 值会导致图像向右(顺时针)旋转,而负值会导致向左旋转。如果省略 <angle>,则默认为 0deg。
如果指定了 flip,图像将在旋转后进行水平翻转。
该值仅适用于内容图像;装饰性图像继续表现为 from-image。该值在 CSS 中已弃用,且除了符合 [CSS-PRINT] 的实现外,对其他实现均是可选的。
注意:该值允许手动再现 from-image 可以产生的所有 8 种可能的 EXIF 方向。
该属性的计算值是通过将 <angle> 舍入到最近的四分之一圈(ambiguous 时向正无穷舍入),然后对 1turn 取模来计算的(使其位于半开区间 [0turn, 1turn) 内)。
除了 none 和 from-image 之外的值在实现上是可选的,且在 CSS 中已弃用。
所有 CSS 布局和渲染过程都在旋转之后使用图像,就像图像最初是以旋转后的形式编码的一样。例如,这意味着:
-
自然高度和宽度是从旋转后的图像尺寸派生的,而不是原始图像尺寸。
-
高度(宽度)属性应用于旋转后图像的垂直(水平)维度。
-
图像cursor的热点坐标是相对于旋转后的图像的。
-
边框图像(参见 border-image)在旋转后进行切片。
-
其他变换(例如 [CSS-TRANSFORMS-1] 中的变换)在应用 image-orientation 之后应用于图像。
img.ninety { image-orientation: 90deg }
...
<img class="ninety" src=...>
同样的效果也可以通过例如 -270deg 或 450deg 的角度来实现。
注意:此属性以前使用 none 作为初始值。人们认为使用 from-image 作为初始值将产生更好的用户体验且破坏性最小,但 UA 在进行此项更改时获得的未来兼容性数据将予以确认。如果得到证实,那么除非除了“纠正错误方向”之外还提出了其他用例,否则该属性很可能会从 CSS 中移除。
5.2. 确定如何缩放图像:image-rendering 属性
| 名称 | image-rendering |
|---|---|
| 值 | auto | smooth | high-quality | pixelated | crisp-edges |
| 初始值 | auto |
| 应用于 | 所有元素 |
| 可继承 | 是 |
| 百分比 | 不可用 |
| 计算值 | 指定关键字 |
| 规范顺序 | 按语法 |
| 动画类型 | 离散 (discrete) |
image-rendering 属性向用户代理提供关于缩放图像时最需要保留哪些方面的提示,以辅助用户代理选择合适的缩放算法。当在元素上指定时,它适用于为元素提供的所有图像,例如背景图像、列表样式图像,或当替换元素代表必须缩放的图像时其内容。此 image-rendering 属性的值解释如下:
- auto
- 缩放算法取决于 UA。
- 平滑
- 图像应使用能最大化图像外观的算法进行缩放。特别是,可以接受“平滑”颜色的缩放算法,例如双线性插值。这适用于照片等图像。
- high-quality
-
与 smooth 相同,但优先考虑更高质量的缩放。如果系统资源受限,当考虑降低哪些图像的质量以及程度时,应用 high-quality 的图像应优先于任何其他值。
此值不会阻止图像在系统资源受限时质量受损。它仅仅表达了一个偏好,即这些图像应比应用 auto 的图像获得额外的缩放资源。如果页面上的所有图像都应用了 high-quality,则等同于它们都应用了 auto——它们将被同等对待。为了充分利用 high-quality,仅将其应用于页面上最重要的图像。
- pixelated
-
图像的缩放方式应尽可能保留原始图像的像素化效果,但在目标尺寸不是原始尺寸的整倍数时,允许进行必要的少量平滑处理,以避免图像失真。
对于每个轴,独立地首先确定其自然尺寸的整数倍,使之最接近目标尺寸且大于零。使用最近邻插值(nearest neighbor)将其缩放到此整数倍尺寸,然后将其缩放至目标尺寸,如同 smooth 一样。
注意:在自然尺寸的整数倍处,这产生的结果与 crisp-edges 相同。在非整数倍处,这通常会产生更好的视觉效果(即使对于像素艺术),但由于需要“两步”渲染,会产生性能损耗。
- crisp-edges
-
图像的缩放方式应保留对比度和边缘,并避免在此过程中平滑颜色或引入模糊。这适用于线条画等图像。
图像可能使用最近邻插值或任何其他 UA 选择的不会模糊边缘或混合源图像颜色的算法进行缩放。不过,它可以检测对角线或曲线并进行相应渲染(而不是渲染为锯齿状的“巨型像素”)。
注意:如果新尺寸不是原始尺寸的整数倍,最近邻插值算法可能会引入严重的“混叠”错误;在缩放后的图像中,原始图像中相同厚度的线条可能会根据它们出现的位置而变细或变粗等。对于大多数目的而言,pixelated 将产生比最近邻插值更合适的渲染。
除了 pixelated 的第一步之外,此属性不指定必须使用任何特定的缩放算法。例如,使用 image-rendering: auto 时,用户代理默认可以使用双线性插值缩放图像,在高负载情况下切换到最近邻插值,并为非移动或非变化的静态图像切换到更高质量的缩放算法(如 Lanczos 插值)。
根据 image-rendering 的值,将其放大 3 倍可能如下所示:
(在这种情况下,以最近邻插值解释会产生与 pixelated 相同的结果。)
例如,使用最近邻插值将图像放大 2.5 倍,会导致源图像的每个像素交替地用于目标图像的两个或三个像素,而将图像缩小至 0.5 倍则会跳过源图像中的每隔一个像素。
pixelated 版本保持了简单放大像素的整体视觉外观,付出了轻微模糊的代价,尽管其模糊程度远低于 smooth 缩放。同时,最近邻插值完全避免了引入任何模糊,但付出了由于混叠伪影导致“像素”看起来大小不规则的代价。
此属性以前接受 optimizeSpeed 和 optimizeQuality 值。这些值现已弃用;用户代理必须接受它们作为合法值,但必须将其处理为分别具有与 crisp-edges 和 smooth 相同的行为,且作者不应使用它们。
6. 插值
<image> 值的插值在此级别中未定义。除非未来规范另有定义,否则实现必须突然过渡它们(在 50% 过渡进度处,类似于其他不支持的插值)。
注意:预计 CSS Images Level 4 将定义渐变的专门插值,并定义所有其他图像通过交叉渐变(cross-fading)进行插值。
7. 序列化
本节描述了本规范中引入的所有新属性和值类型的序列化,以用于与 CSS 对象模型 [CSSOM] 进行交互。
要序列化本模块中定义的任何函数,请按其各自语法进行序列化,顺序应与其语法的书写顺序一致,尽可能在不改变含义的情况下省略组件,用单个空格连接空格分隔的标记,并在每个序列化逗号后跟一个空格。
Linear-Gradient( to bottom, red 0%,yellow,black 100px)
必须序列化为:
linear-gradient(red, yellow, black 100px)
隐私性考虑
本规范不引入任何新的隐私问题。
安全性考虑
本规范默认允许渲染跨域图像,这会在程序上暴露这些图像的一些信息——具体而言,是这些图像的自然尺寸和分辨率。
致谢
感谢 Webkit 团队、Brad Kemper、Brian Manthos 和 Alan Gresley 对渐变定义的贡献;感谢 Melinda Grant 对 object-fit、object-position 和 image-orientation 所做的工作;感谢 L. David Baron、Kang-Hao Lu、Leif Arne Storset、Erik Dahlstrom 和 Øyvind Stenhaug 的仔细审阅、评论和更正。
变更 (Changes)
自 2019 年 10 月 10 日候选推荐标准以来的变更
自 2020 年 12 月 17 日 CRD 以来的重大变更:
-
移除 &&,这允许了对 <linear-color-stop> 的重新排序。(Issue 8021)
-
指定 pixelated 使用从最近邻插值到最接近像素倍数的平滑缩放,以避免失真。(Issue 5837)
-
明确允许将最近邻插值作为 crisp-edges 的实现,因为这正是当前各实现的做法。(Issue 6038)
-
对语法产生式进行了各种编辑/拼写修正。
自 2019 年 10 月 10 日 CR 以来的重大变更:
-
定义退化纵横比的处理(Issue 4572)
-
定义应忽略出现在图像数据之后的影响布局的元数据(Issue 5165)
-
明确允许在渐变中进行抖动(dithering)(Issue 4793)
-
定义 image-orientation 同时适用于装饰性图像和内容图像(Issue 5245)
-
将“固有尺寸”(intrinsic dimensions)重命名为自然尺寸,以避免与固有尺寸(intrinsic sizes)混淆。(Issue 4961)
自 2012 年 4 月 17 日候选推荐标准以来的变更
主要变更包括:
-
image() 记法已推迟至 Level 4。
-
image-resolution 属性已推迟至 Level 4。
-
image-orientation 属性已被标记为已弃用、可选和处于风险中。此外:
-
添加了 from-image 和 none 关键字。
-
添加了 flip 值。
-
-
添加了 image-rendering 属性。
-
将 <resolution> 类型移动至 [CSS-VALUES-3]。
-
更好地定义了无效和部分加载图像的处理。
-
定义了 <image> 的通用计算形式。
-
定义了对于既是图像又是元素引用的 URL 的概念和处理方式。
-
定义了由于兼容性原因,在 linear-gradient() 中可以省略零角度的单位。
-
略微澄清了退化重复径向渐变的处理。
-
向 <color-stop-list> 添加了过渡提示(transition hints),并在编辑上重写了关于渐变颜色停止点的章节,以更好地适应新文本。
-
在所有属性定义表中添加了“标准顺序”和“动画类型”。
-
定义了 <image> 值的插值和序列化。
-
各种微小的澄清。

