当我使用 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-color
、rotate
和 z-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 的演示。
哇!太棒了。
这实际上是我一段时间以来看到的最聪明的 CSS 技巧之一。
感谢您,并继续努力!
我的思想被炸飞了!非常聪明的东西。
一个不错的替代方法是用内阴影使外边缘变暗,即放大“轮子”裁剪元素内部的“雨伞”。我认为这看起来更自然。这里有一个 最终笔的 fork 展示了这一点。
一个非常棒的改进!谢谢;)
这简直太史诗了。
您也可以使用它在 css 中检测接近角度。
非常酷!
该来的总算来了!
太棒了 热狗!
非常棒的教程,感谢分享!
好吧!太棒了!+1000
CSS 能力的绝佳示例!非常酷!
相当不错。我不得不将此作为雷达图的背景,并最终使用了 SVG,因为我想不出任何其他方法来做到这一点,而无需使用图像。
我不知道是我的眼睛,我的显示器还是 Chrome,但我可以在主圆圈内看到一个淡淡的白色圆圈的伪像,它略大于一半的直径。
我可以在我的 iPad 上看到该伪像。我认为这是由用于使外边缘变暗的内阴影造成的。请查看我的评论(从顶部数第二个)以获取替代方案。
绝对令人惊叹。感谢您的技巧,伙计们。
Arun
哇,非常好!:)
非常巧妙的技巧,我喜欢它。
您可能希望稍微更改您的 Sass 循环,使其更易于阅读。
不过,出色地完成工作!
是的……所以会更好。谢谢,Hugo!
看起来很棒。
干得好,Shankar!
如果您触摸它,它可能会爆炸,但 这里 是一个使用纯 CSS 模拟圆锥渐变的小实验。它不像真正的圆锥渐变那样好,所以中心看起来不太好。不过,您可以在中间放置一些东西来遮盖它。
(免责声明:它可能不是准确的渐变。)
如果不太明显,我可以解释您在看什么。
您可以像上面的示例一样清理它,只需添加
-webkit-filter: blur(1.7em);
到您的雨伞类。
仍然做得很好,你和
Shankar。我喜欢这样的示例。
终于,一个优雅的解决方案,无需图像的“小丑乳头”。
嘟嘟!DB
该演示在 Safari 上无法正常工作。
圆锥形渐变也可以用线性渐变来模拟(这也意味着只使用一个元素)。背后的理念是我在这篇文章中解释过的。
很高兴看到圆锥形渐变越来越受欢迎,尽管这种方法产生的代码量可能使其不适合生产使用。但我们仍然需要这样的实验来推动圆锥形渐变的发展。
顺便说一下,这里有一个更简单的方法,但限制更多(你只能有4个段,而不是8个):http://dabblet.com/gist/6915653
@Lea Verou…
太棒了……真不错
非常棒的东西 - 谢谢发布!我希望在不久的将来能够在不使用多个元素的情况下实现圆锥形渐变,就像使用线性或径向渐变一样。这也是 SVG 应该作为标准具有的东西。
再次感谢您发布这篇博文!
做得好!但要等几年才能在 IE 中支持它 :)
对 Mac OS Finder 实现的致敬 :-)
CSS 旋转轮
有办法在瓷砖中添加文字吗?
这是我第一次使用圆锥形渐变;)
http://codepen.io/shankarcabus/details/hBbDi