CSS 渐变

Avatar of Chris Coyier
Chris Coyier

DigitalOcean 为您旅程的每个阶段提供云产品。 立即开始使用 价值 200 美元的免费积分!

就像您可以在 CSS 中将元素的 背景 声明为纯色一样,您也可以将该背景声明为渐变。 使用在 CSS 中声明的渐变,而不是使用实际的图像文件,对于控制和性能来说更好。

渐变通常是一种颜色逐渐过渡到另一种颜色,但在 CSS 中您可以控制渐变过渡的所有方面,从方向到颜色(您可以使用任意数量的颜色),再到颜色变化的位置。 让我们逐一讲解。

渐变是背景图像

虽然在 CSS 中使用 background-color 属性声明纯色,但渐变使用 background-image。 这在很多方面都很有用,我们稍后会讲到。 如果你声明其中之一,速记 background 属性会知道你的意思。

.gradient {

  /* can be treated like a fallback */
  background-color: red;

  /* will be "on top", if browser supports it */
  background-image: linear-gradient(red, orange);

  /* these will reset other properties, like background-position, but it does know what you mean */
  background: red;
  background: linear-gradient(red, orange);

}

线性渐变

也许最常见和最有用的渐变类型是 linear-gradient()。 渐变的“轴”可以从左到右、从上到下或您选择的任何角度。

不声明角度将默认为从上到下

这些用逗号分隔的颜色可以使用您通常使用的任何颜色类型:十六进制、命名颜色rgbahsla 等。

要使渐变从左到右,您需要在 linear-gradient() 函数的开头传递一个额外的参数,以“to”开头,指示方向,例如“to right”。

这种“to”语法也适用于角。 例如,如果您希望渐变的轴线从左下角开始到右上角,您可以说“to top right”。

如果该框是正方形,那么该渐变的角度将是 45°,但由于它不是正方形,因此角度也不相同。 如果您希望确保它是 45°,您可以声明它。

.gradient {
  background-image:
    linear-gradient(
      45deg, 
      red, #f06d06
    );
}

您也不限于仅使用两种颜色。 实际上,您可以使用任意数量的用逗号分隔的颜色。 这里有四种颜色

.gradient {
  background-image:
    linear-gradient(
      to right, 
      red, 
      #f06d06, 
      rgb(255, 255, 0), 
      green
    );
}

您还可以声明希望任何特定颜色“开始”的位置。 这些被称为“颜色停止点”。 假设您希望黄色占据大部分空间,而红色仅在开头占据一小部分空间,您可以使黄色的 color-stop 非常早。

我们倾向于将渐变视为逐渐过渡的颜色,但是如果您有两个相同的颜色停止点,则可以使一种纯色立即过渡到另一种纯色。 这对于声明一个模拟列的全高背景很有用。

浏览器支持/前缀

到目前为止,我们只介绍了语法,但是 CSS 渐变已经存在相当长的时间了。 浏览器支持良好。 棘手的部分是语法和前缀。 浏览器已经支持了三种不同的语法。 这不是它们正式的名称,但您可以将其想象成:

  1. 旧版:最初的 WebKit 专用方式,使用类似 from() 和 color-stop() 的内容
  2. 中间版:旧的角度系统,例如“left”
  3. 新版:新的角度系统,例如“to right”

然后还有前缀。

让我们尝试一个图表

Chrome1-9:旧版,带前缀
10-25:中间版,带前缀
26:新版,无前缀
Safari3-:不支持
4-5.0:旧版,带前缀
5.1-6.0:中间版,带前缀
6.1:新版,无前缀
Firefox3.5-:不支持
3.6-15:中间版,带前缀
16:新版,无前缀
Opera11.0-:不支持
11.1-11.5:中间版,带前缀,仅线性
11.6-12:中间版,带前缀,添加径向
12.1:中间版,无前缀
15:新版,无前缀
IE8-:不支持
9:仅支持滤镜
10+:新版,无前缀(也支持带前缀的中间版)
Android2.0-:不支持
2.1-3.0:中间版,带前缀
4.0-4.3:新版,带前缀
4.4+:新版,无前缀
iOS3-:不支持
3.2-4.3:中间版,带前缀
5.0-6.1:新版,带前缀
7.0:新版,无前缀

其中有一些重叠。 例如,当浏览器支持新语法时,它们可能也支持旧语法,包括前缀。 最佳做法是:如果支持新语法,就使用新语法。

因此,如果您希望获得最深层次的浏览器支持,线性渐变可能看起来像这样

.gradient {
  
  /* Fallback (could use .jpg/.png alternatively) */
  background-color: red;

  /* SVG fallback for IE 9 (could be data URI, or could use filter) */
  background-image: url(fallback-gradient.svg); 

  /* Safari 4, Chrome 1-9, iOS 3.2-4.3, Android 2.1-3.0 */
  background-image:
    -webkit-gradient(linear, left top, right top, from(red), to(#f06d06));
  
  /* Safari 5.1, iOS 5.0-6.1, Chrome 10-25, Android 4.0-4.3 */
  background-image:
    -webkit-linear-gradient(left, red, #f06d06);

  /* Firefox 3.6 - 15 */
  background-image:
    -moz-linear-gradient(left, red, #f06d06);

  /* Opera 11.1 - 12 */
  background-image:
    -o-linear-gradient(left, red, #f06d06);

  /* Opera 15+, Chrome 25+, IE 10+, Firefox 16+, Safari 6.1+, iOS 7+, Android 4.4+ */
  background-image:
    linear-gradient(to right, red, #f06d06);

}

那里的代码太多了。 手动编写代码会容易出错,而且工作量很大。 Autoprefixer 可以很好地处理它,允许您根据要支持的浏览器数量来减少代码量。

如果对您很重要,Compass 混合器可以为 IE 9 创建 SVG 数据 URI。

为了使事情变得稍微 更复杂,OLD 与 NEW 语法中的度数工作方式略有不同。 OLD(和 TWEENER - 通常带前缀)方式将 0deg 定义为从左到右,并逆时针进行,而 NEW(通常无前缀)方式将 0deg 定义为从下到上,并顺时针进行。

OLD(或 TWEENER)= (450 – new) % 360

或者更简单地说

NEW = 90 – OLD
OLD = 90 – NEW

例如

OLD linear-gradient(135deg, red, blue)
NEW linear-gradient(315deg, red, blue)

IE 滤镜

Internet Explorer (IE) 6-9 虽然不支持 CSS 渐变语法,但它们确实提供了一种通过编程方式实现背景渐变的方法

/* "Invalid", but works in 6-8 */
filter: progid:DXImageTransform.Microsoft.gradient(GradientType=0, startColorstr=#1471da, endColorstr=#1C85FB);

/* Valid, works in 8-9 */
-ms-filter: "progid:DXImageTransform.Microsoft.gradient (GradientType=0, startColorstr=#1471da, endColorstr=#1C85FB)";

在决定是否使用它方面有一些注意事项

  1. filter 通常被认为是一种会影响性能的坏做法,
  2. background-image 会覆盖滤镜,因此如果您需要将其用作回退,则滤镜将失效。 如果纯色是可接受的回退(background-color),则滤镜是一种可能性

即使滤镜只适用于十六进制值,您仍然可以通过在十六进制值前添加透明度值(从 00(0%)到 FF(100%))来获得 Alpha 透明度。 例如

rgba(92,47,90,1) == #FF5C2F5A
rgba(92,47,90,0) == #005C2F5A

径向渐变

径向渐变与线性渐变不同,它们从一个点开始,向外扩散。 渐变通常用于模拟光线,我们知道光线并不总是直线,因此它们对于使渐变看起来更自然很有用。

默认情况下,第一种颜色从元素的(center center)开始,并逐渐过渡到元素边缘的结束颜色。 渐变过渡速度相同,无论哪个方向。

您可以看到该渐变如何形成椭圆形,因为元素不是正方形。 这是默认值(ellipse,作为第一个参数),但是如果我们说我们希望得到一个圆形,我们可以强制它成为圆形

.gradient {
  background-image:
    radial-gradient(
      circle,
      yellow,
      #f06d06
    );
}

请注意,渐变是圆形的,但仅沿着最远边缘逐渐过渡到结束颜色。 如果我们需要该圆形完全位于元素内,我们可以通过指定我们希望渐变过渡到“最近的一侧”来确保这一点,它与形状之间用空格隔开,例如

这里可能的取值有:closest-cornerclosest-sidefarthest-cornerfarthest-side。 您不妨将其想象成:“我希望该径向渐变从中心点逐渐过渡到________,其他所有区域则进行填充以适应这种情况。”

径向渐变也不必从默认的中心开始,您可以通过使用“at ______”作为第一个参数的一部分来指定特定点,例如

为了更清楚地说明这一点,我将示例设置为正方形,并调整了颜色停止点

径向渐变的浏览器支持与 linear-gradient() 几乎相同,但 Opera 在刚开始支持渐变的时候,只支持线性渐变,不支持径向渐变。

但是与线性渐变类似,radial-gradient() 也经历了一些语法更改。 同样,有“旧版”、“中间版”和“新版”。

/* Example of Old */
background-image: 
  -webkit-gradient(radial, center center, 0, center center, 141, from(black), to(white), color-stop(25%, blue), color-stop(40%, green), color-stop(60%, red), color-stop(80%, purple));

/* Example of Tweener */
background-image: 
  -webkit-radial-gradient(45px 45px, farthest-corner, #F00 0%, #00F 100%) repeat scroll 0% 0% rgba(0, 0, 0, 0);

/* Example of New */
background-image: 
  radial-gradient(circle farthest-side at right, #00F, #FFF);

其标志是

  • 旧版:使用 -webkit- 前缀,使用类似 from()color-stop() 的内容
  • 中间版:第一个参数是中心的定位。 在支持无前缀的新语法的浏览器中,这将完全失效,因此确保任何中间版语法都带前缀。
  • 新版:详细的第一个参数,例如“circle closest-corner at top right”

同样,我建议使用 Autoprefixer 来处理这个问题。 您使用最新语法编写代码,它会创建回退。 径向渐变比线性渐变更令人费解,因此我建议尝试只习惯最新语法并使用它(如果有必要,忘记您对旧语法的了解)。

圆锥渐变

圆锥渐变类似于径向渐变。 两者都是圆形的,都使用元素的中心作为颜色停止点的源点。 但是,径向渐变的颜色停止点从圆形中心出现,而圆锥渐变的颜色停止点位于圆形周围。

说明圆锥形(左)和径向(右)渐变之间的区别。

它们被称为“圆锥形”,因为它们看起来像从上面看到的圆锥形。 好吧,至少当有一个明显的角度提供并且颜色值之间的对比度足够大以区分差异时。

圆锥形渐变语法用简单的英语更容易理解。

创建一个位于 **[某个点]** 的 **圆锥形渐变**,从 **[一种颜色]** 开始,角度为 **某个角度**,并以 **[另一种颜色]** 结束,角度为 **[某个角度]**。

在最基本的层面上,它看起来像这样。

.conic-gradient {
  background: conic-gradient(#fff, #000);
}

... 其中假设渐变的位置从元素的正中心(`50% 50%`)开始,并且在白色和黑色颜色值之间均匀分布。

我们可以用几种其他方法来写它,所有这些都是有效的。

.conic-gradient {
  /* Original example */
  background-image: conic-gradient(#fff, #000);
  /* Explicitly state the location center point */
  background: conic-gradient(at 50% 50%, #fff, #000);
  /* Explicitly state the angle of the start color */
  background: conic-gradient(from 0deg, #fff, #000);
  /* Explicitly state the angle of the start color and center point location */
  background: conic-gradient(from 0deg at center, #fff, #000);
  /* Explicitly state the angles of both colors as percentages instead of degrees */
  background: conic-gradient(#fff 0%, #000 100%);
  /* Explicitly state the angle of the starting color in degrees and the ending color by a full turn of the circle */
  background: conic-gradient(#fff 0deg, #000 1turn);
}

如果我们没有为颜色指定角度,则假设渐变在颜色之间均匀分配,从 `0deg` 开始,到 `360deg` 结束。 这会在 `0deg` 和 `360deg` 处创建硬性停止,颜色会在那里彼此紧挨着。 如果我们的起始颜色从圆圈上的其他位置开始,比如在 `90deg` 的四分之一处,那么这会创建一个更平滑的渐变,并且我们开始获得那种酷炫的锥形透视感。

.conic-gradient {
  background: conic-gradient(from 90deg, #fff, #000);
}

我们可以用圆锥形渐变做很多有趣的事情。 例如,我们可以用它来创建与颜色选择器或臭名昭著的 Mac 旋转海滩球指示器中看到的图案类似的图案。

.conic-gradient {
  background: conic-gradient(red, yellow, lime, aqua, blue, magenta, red);
}
模拟颜色轮图案的圆锥形渐变的模型。

或者,让我们通过在三个颜色值之间添加硬性停止来尝试一个简单的饼图。

.conic-gradient {
  background: conic-gradient(lime 40%, yellow 0 70%, red 0);
}
模拟简单的三色饼图的圆锥形渐变的模型。

不幸的是,`conic-gradient` 在撰写本文时没有浏览器支持。 它目前是 CSS 图片和 替换内容模块级别 4 规范的一部分,该规范处于工作草案阶段。 同时,Lea Verou(他为规范做出了贡献) 提供了一个 polyfill,它使它们成为可能。

这些浏览器支持数据来自 Caniuse,它有更多细节。 数字表示浏览器从该版本开始支持该功能。

台式机

ChromeFirefoxIE边缘Safari
69837912.1

移动设备 / 平板电脑

Android ChromeAndroid FirefoxAndroidiOS Safari
12712712712.2-12.5

重复渐变

使用 浏览器支持略少 的是重复渐变。 它们有线性变体和径向变体。

对于非重复渐变,有一个技巧可以创建渐变,这样如果它是一个很小的矩形,它会与自身的其他很小的矩形版本对齐以创建一个重复模式。 因此,本质上创建该渐变并设置 `background-size` 以使该矩形变小。 这使得创建条纹变得很容易,然后可以旋转或进行其他操作。

使用 `repeating-linear-gradient()`,您不必诉诸于这种技巧。 渐变的大小 **由最后一个颜色停止决定**。 如果它位于 20px 处,则渐变的大小(然后重复)为 20px x 20px 的正方形。

径向渐变也是一样。

不正确的回退加载

正如我们所述,一些非常旧的浏览器根本不支持任何 CSS 渐变语法。 如果您需要仍然是渐变的回退,则图像(.jpg / .png)可以解决问题。 令人担忧的是,一些稍微旧一点的浏览器(它们刚刚开始支持 CSS 渐变)会加载回退图像。 也就是说,即使它会渲染 CSS 渐变,也会为图像发出 HTTP 请求。

Firefox 3.5.8 这样做过(见截图),以及 Chrome 5 和 Safari 5.0.1。 见

Safari 5.0.1 不正确地加载回退

好消息是这不再是什么问题。 唯一有问题的浏览器是 Chrome 和 Safari,Chrome 从 6 开始就没有这样做,Safari 从 5.1 开始就没有这样做,已经过去三年了。

其他资源