在你没注意的时候,CSS 渐变变得更好了

Avatar of Ana Tudor
Ana Tudor

DigitalOcean 为你的旅程各个阶段提供云产品。立即开始使用 200 美元的免费信用额度!

Lea Verou 的 conic-gradient() polyfill 的 功能 列表中,有一点引起了我的注意,那就是最后一项

支持双位置语法(同一个颜色停点的两个位置,作为两个具有相同颜色的连续颜色停点的快捷方式)

令人惊讶的是,我最近发现大多数人甚至没有意识到渐变停点的双位置在规范中实际上是存在的,所以,我决定写一篇关于它的文章。

根据 规范

指定两个位置可以更轻松地在渐变中创建纯色“条纹”,而无需两次重复颜色。

我完全同意,这是我意识到此功能时想到的第一件事。

假设我们想要获得以下结果:一个具有许多等宽垂直条纹的渐变(我从 Chris 的一篇 早些时候的文章 中获得的灵感)。

Screenshot. Shows 8 vertical rainbow stripes, from left to right: violet, magenta, red, orange, yellow, yellowish green, teal, blue.
所需的渐变结果。

十六进制值是:#5461c8#c724b1#e4002b#ff6900#f6be00#97d700#00ab84#00a3e0

首先,让我们看看如何在不使用双停点位置的情况下实现这个 CSS!

我们有八个条纹,这使得每个条纹占渐变宽度的八分之一。八分之一的 100%12.5%,因此我们在该值的倍数处从一个条纹移到下一个条纹。

这意味着我们的 linear-gradient() 如下所示

linear-gradient(90deg, 
             #5461c8 12.5% /* 1*12.5% */, 
  #c724b1 0, #c724b1 25%   /* 2*12.5% */, 
  #e4002b 0, #e4002b 37.5% /* 3*12.5% */, 
  #ff6900 0, #ff6900 50%   /* 4*12.5% */, 
  #f6be00 0, #f6be00 62.5% /* 5*12.5% */, 
  #97d700 0, #97d700 75%   /* 6*12.5% */, 
  #00ab84 0, #00ab84 87.5% /* 7*12.5% */, 
  #00a3e0 0)

请注意,我们不需要重复停点位置 % 值,因为只要停点位置小于上一个位置,我们就会自动进行一个急剧的过渡。这就是为什么始终可以安全地使用 0(它总是小于任何正值)并使用 #c724b1 25%, #e4002b 0 而不是 #c724b1 25%, #e4002b 25%,例如。如果我们将来决定添加两个条纹并使停点位置成为 10% 的倍数,这将使我们的工作更容易。

还不错,尤其是与渐变生成器通常 吐出的 内容相比。但是,如果我们决定中间的其中一个条纹不太适合其他条纹,那么将其更改为其他内容意味着要更新两个地方。

再说一次,这也不错,我们也可以借助预处理器来解决这个问题。

$c: #5461c8 #c724b1 #e4002b #ff6900 #f6be00 #97d700 #00ab84 #00a3e0;

@function get-stops($c-list) {
  $s-list: ();
  $n: length($c-list);
  $u: 100%/$n;
	
  @for $i from 1 to $n {
    $s-list: $s-list, 
             nth($c-list, $i) $i*$u, 
             nth($c-list, $i + 1) 0
  }

  @return $s-list
}

.strip {
  background: linear-gradient(90deg, get-stops($c)))
}

这将生成我们之前看到的精确 CSS 渐变,现在我们不再需要在两个地方修改任何内容。

查看 thebabydino 在 CodePen 上的 Pen。(@thebabydino

但是,即使预处理器可以帮助我们避免两次输入相同的内容,它也无法消除生成的代码中的重复。

而且我们可能并不总是希望使用预处理器。撇开有些人固执或对预处理器有非理性的恐惧或仇恨的事实不谈,有时用一个循环来实现它感觉有点傻。

例如,当我们要循环的内容很少时!假设我们想要获得一个更简单的 background 模式,例如一个对角线斜线模式,我认为这是一个比过度彩虹模式更常见的用例,过度彩虹模式可能不适合大多数网站。

Screenshot. Shows a pattern of diagonal light grey hashes on a white background.
所需的斜线结果

这需要使用 repeating-linear-gradient(),即使我们没有像之前那样拥有长长的十六进制值列表,也意味着要进行一些重复。

repeating-linear-gradient(-45deg, 
    #ccc /* can't skip this, repeating gradient won't work */, 
    #ccc 2px, 
    transparent 0, 
    transparent 9px /* can't skip this either, tells where gradient repetition starts */)

在这里,我们不能放弃第一个和最后一个停点,因为它们恰好指示了渐变如何在 background-size 定义的矩形内重复。

如果你想了解为什么最好使用 repeating-linear-gradient() 而不是一个普通的 linear-gradient() 以及适当的 background-size 来创建这样的斜线,请查看我之前写的另一篇 文章

这正是此功能的用武之地——它允许我们在最终的 CSS 代码中避免重复。

对于彩虹条纹示例,我们的 CSS 变成

linear-gradient(90deg, 
    #5461c8 12.5%, 
    #c724b1 0 25%, 
    #e4002b 0 37.5%, 
    #ff6900 0 50%, 
    #f6be00 0 62.5%, 
    #97d700 0 75%, 
    #00ab84 0 87.5%, 
    #00a3e0 0)

要重新创建斜线,我们只需要

repeating-linear-gradient(-45deg, 
    #ccc 0 2px, 
    transparent 0 9px)

查看 thebabydino 在 CodePen 上的 Pen。(@thebabydino

支持情况如何?很好,你问对了!它实际上支持得很好!它在 SafariChromium 浏览器(现在也包括 Edge!)和 Firefox 中有效。预 Chromium Edge 和一些移动浏览器可能仍然不支持,但是,如果你不必担心为所有浏览器提供支持,或者可以提供一个回退,那么,就可以开始使用它了!