是否可以在大元素上制作硬边渐变?

Is it possible to make a hard-edged gradient on a large element?

我 运行 在一个特别大的元素上使用 linear-gradient 遇到了问题。

在较小的元素上,可以通过以下方式实现硬边:

background-image: linear-gradient(180deg, #000, #000 33%, #0f0 0);

但是当元素的高度很大时,边缘会变软。您可以在下图和下面的示例中看到,当元素非常大且应用相同的渐变时,第二个版本具有柔和的边缘。

我在线性渐变上尝试了很多变化,但无法在大版本上实现硬边。有没有办法在大元素上应用带有硬边的渐变?

HTML 示例:

div {
  height: 5000px;
  background-repeat: no-repeat;
  margin-bottom: 1em;
  background-image: linear-gradient(180deg, #000, #000 20px, #0f0 0);
}
div:first-child {
  height: 100px;
}
<div></div>
<div></div>

编辑

这个渐变的目标是与另一个背景图像一起使用,所以我更喜欢与以下兼容的技术(不要覆盖图像):

div {
  height: 5000px;
  background-repeat: no-repeat;
  margin-bottom: 1em;
  background-image: url(http://placehold.it/600x20), linear-gradient(180deg, #000, #000 20px, #0f0 0);
}
<div></div>

编辑 2

感谢@Tarun,这似乎与浏览器有关。上图是 Chromium 45 的屏幕截图。Safari 和 Firefox 似乎可以正确呈现。

编辑 3

有关此问题的 Chromium 有一个开放 bug report

我找到了一种使用渐变来实现相同效果的替代方法,但我认为应该可以使用 1 个渐变来实现此效果,因此我认为这是一种变通方法。

诀窍是使用具有 2 个不改变颜色的渐变的多个背景。那么只要定义background-size就可以实现硬边效果了。查看工作片段:

div {
  height: 5000px;
  background-repeat: no-repeat;
  margin-bottom: 1em;
  background-image: linear-gradient(#000, #000), linear-gradient(#0f0, #0f0);
  background-size: 100% 20px, 100%;
}
div:first-child {
  height: 100px;
}
<div></div>
<div></div>

这对我有用。

background: linear-gradient(to bottom, black 0% ,black 20% ,green 20% ,green 100%);

编辑: 我已经尝试完全按照您在问题中所做的去做,但我在这两个方面都处于优势地位。你的问题肯定是和你的浏览器有关。

编辑 2: 确认

您可以使用更多代码空间并像下面这样设置您的 gardient:

background: #4c4c4c;
background: linear-gradient(to bottom,  #4c4c4c 0%,#2c2c2c 50%,#000000 51%,#131313 100%);
filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#4c4c4c', endColorstr='#131313',GradientType=0 );

如果浏览器因某种原因不支持此类 gardient 或其过滤器,纯色背景设置可确保您的页面显示某种颜色。

最好还包括 -moz、-o 和其他基于浏览器的修正以确保。

您可以使用方框阴影来达到同样的效果。

div {
  height: 5000px;
}
div {
  background: #0f0;
  box-shadow: inset 0 100px 0 0 #000;
}
<div></div>

您需要以一种巧妙但富有表现力的方式重复每种颜色和 linear-gradient 的每个百分比。让我们在六种颜色的样本中看到它来理解原理。 这种方法适用于任何大小的块。

div {
  height: 100px;
  background-repeat: no-repeat;
  margin-bottom: 1em;
  background-image:
      linear-gradient(90deg,
                       red,
                       red     17%,
                       orange  17%, 
                       orange  34%, 
                       yellow  34%,
                       yellow  51%,
                       black   51%,
                       black   68%,
                       green   68%,
                       green   85%,
                       blue    85%);
}
  
<div></div>