CSS 中的圆锥形渐变

Avatar of Shankar Cabus
Shankar Cabus

DigitalOcean 为您旅程的每个阶段提供云产品。立即开始使用 $200 免费赠送额度!

当我使用 CSS 创建过滤器、阴影、变换或渐变背景时,感觉很棒。谁会想到 CSS 会发展到这种程度。所有这些都不需要使用图像。我几乎可以听到浏览器告诉我:“别担心,我来处理”。

尽管经历了所有这些演变,CSS 仍然存在局限性。例如,背景渐变只能以 线性径向 样式创建,而不能创建圆锥形形状。

2011 年,Lea Verou 启动了一个关于实现原生 CSS 圆锥形渐变的 主题,创建了一个 草案规范,该规范已被引入 W3C 的官方草案。但是,我们仍然需要等待 W3C 正式化该功能以及浏览器实现它,这可能还需要一段时间。在此期间,我将向您展示如何仅使用 CSS3 模拟圆锥形渐变。

圆锥形渐变的示例。

很漂亮,对吧?让我们看一下代码吧!

开始

为了减少代码重复,我使用的是 Sass。CSS 预处理器的最有趣功能之一是 @mixin。@mixin 是函数和包含的混合体,当调用时,它会返回其内容。

@mixin circle($size) {
  content: "";
  position: absolute;
  border-radius: 50%;
  width: $size;
  height: $size;
  left: calc(50% - #{$size/2});
  top: calc(50% - #{$size/2});
}

此 @mixin 仅用于设置形状和位置属性,创建相对于其父元素水平和垂直居中的绝对位置圆圈。

魔法!

通过将 @mixin circle 与 clip 属性结合使用,我们可以获得半圆形。让我们从通过将两个半圆(颜色不同)组合在一起创建一个完整的圆圈开始。你能想象如果我们旋转其中一个半圆会发生什么吗?魔法!

$wheel: 15em;
.color {
  @include circle($wheel);
  background: red;
  clip: rect(0, $wheel, $wheel, #{$wheel/2});
  &:after {
    @include circle($wheel);
    background: blue;
    clip: rect(0, #{$wheel/2}, $wheel, 0);
    transform: rotate(45deg);
  }
}

clip: rect (top, right, bottom, left) 属性将可见区域限制为矩形元素,这会导致上面的示例中只有红色圆圈的一半可见。相同的原理应用于蓝色圆圈,即 .color:after 元素。此时我们将有一个完整的圆圈,一半是红色,一半是蓝色。但是,**transform 属性导致蓝色圆圈的可见区域侵入红色圆圈**。参见示例

带剪裁属性的半圆形

五彩缤纷的雨伞

五彩缤纷的雨伞

我们已经知道如何执行这个魔术技巧。让我们创建一个 12 色雨伞

<div class="wheel">
  <ul class="umbrella">
    <li class="color"></li>
    <li class="color"></li>
    <li class="color"></li>
    <li class="color"></li>
    <li class="color"></li>
    <li class="color"></li>
    <li class="color"></li>
    <li class="color"></li>
    <li class="color"></li>
    <li class="color"></li>
    <li class="color"></li>
    <li class="color"></li>
  </ul>
</div>

由于我们要通过组合半圆形来创建一个完整的圆形,从第七个项目(第二半中的第一个项目)开始,我们必须反转剪裁

.color, .color:nth-child(n+7):after {
  clip: rect(0, $wheel, $wheel, #{$wheel/2});
}
.color:after, .color:nth-child(n+7) {
  @include circle($wheel);
  clip: rect(0, #{$wheel/2}, $wheel, 0);
}

从第七个项目开始,.color 变成一个圆圈的左半部分的半圆形,而 .color:after 元素传递到圆圈的右半部分。

我们快完成了!我们需要改变每个元素的颜色和角度。同样,让我们利用 Sass 的强大功能,在短短 10 秒钟内生成 26193^42 行代码;)

$colors: (#9ED110, #50B517, #179067, #476EAF, #9f49ac, #CC42A2, #FF3BA7, #FF5800, #FF8100, #FEAC00, #FFCC00, #EDE604);
@for $i from 0 to length($colors) {
  .color:nth-child(#{1+$i}):after {
    background-color: nth($colors, $i+1);
    @if $i < 6 {
      transform: rotate(#{30*(1+$i)}deg);
      z-index: #{length($colors)-$i};
    } @else {
      transform: rotate(#{-30+(30*(1+$i))}deg);
    }
  }
}

首先,我们使用“12 色彩虹”定义 $colors 数组,然后遍历该列表,创建具有 background-colorrotatez-index 属性的 .color:nth-child(n):after 选择器。

rotate 属性有一些重要的点。它的角度是根据圆圈中的颜色数量来定义的。在我们的例子中,有 12 种颜色,所以 360/12 = 30 是每种颜色的旋转。但从第七个项目开始,圆圈的另一半就开始了,记得吗?因此,我们刚刚描述的过程在第七个项目处停止。然后我们将从头开始相同的过程,但这次旋转将朝另一个方向进行。这就是为什么在 @else 中有 rotate(#{-30+(30*($i+1))}deg),它从圆圈后半部分的元素中减去 30 度。

如果您是一位敏锐的观察者(并且理解了到目前为止的所有内容),您应该已经注意到,我们的雨伞实际上是一把扇子!太棒了!因此,为了让圆圈前半部分的最后一种颜色不会出现在其他颜色之上,我们需要反转这些元素的索引。例如,z-index (6) = 1,z-index (1) = 6。

再来点魔法

最后,我们需要平滑颜色之间的过渡,毕竟,我们不想要一把彩虹雨伞,我们想要一个圆锥形渐变!

.umbrella {
  -webkit-filter: blur(1.7em);
}

.wheel {
  overflow: hidden;
  box-shadow: inset 0 0 0 3em rgba(0, 0, 0, 0.3);
}

模糊过滤器负责混合颜色。但是,通过应用模糊,颜色会超出圆圈的范围。这就是为什么 overflow: hidden 属性也被添加到 .wheel 元素中的原因。内部 box-shadow 用于使被“冲洗”的边缘变暗。这是 最终结果

查看 CodePen 上 Shankar Cabus (@shankarcabus) 的 纯 CSS 圆锥渐变

演示

圆锥渐变可以以不同的方式使用来创建不同的效果。但最有趣的应用之一是 颜色选择器,如以下示例所示。

查看 CodePen 上 Shankar Cabus (@shankarcabus) 的 纯 CSS 颜色选择器

其他演示

编辑说明:我过去看到了许多其他方法。我将开始在这里将它们作为参考。

查看 CodePen 上 Kai Waddington (@waddington) 的 css 圆锥渐变

另一个 Michael Wehner 的演示