【问题标题】:CSS3 Linear Gradient in a circular way圆形方式的CSS3线性渐变
【发布时间】:2015-10-04 02:01:04
【问题描述】:

我想知道是否可以用 css 渐变做这样的事情:

我搜索了很多,所有渐变都是“线性”或“径向”。我想要的渐变是圆形的线性渐变!

【问题讨论】:

  • 有趣的问题。但我认为仅使用 CSS 渐变是不可能的。
  • 我想出了一个使用 css 和 javascript 的混乱解决方案。我可以创建许多圆形切片并为它们着色。但我不认为这是要走的路。
  • 其实这是我能想到的使用纯 CSS 的最佳方式。
  • 这对于 CSS 来说是非常困难的。使用 Canvas 或 SVG 会很容易。查看my answer here 以了解 SVG/Canvas 实现。还有其他 SVG 和 CSS(锥形渐变)答案,您会发现它们很有帮助。

标签: html css css-shapes


【解决方案1】:

现在是可行的 - 至少在 Chrome 中是这样。 CSS 属性conic-gradient 可以轻松实现:

html, body { margin: 0; padding: 0; }
.box {
    position: absolute;
    width: 200px;
    height: 200px;
    left: 100px;
}
.colorwheel {
    background: conic-gradient(red, yellow, lime, aqua, blue, magenta, red);
    border-radius:50%;
}
.fallback {
    text-align: center;
    padding: 50px 0;
}
<div class="fallback box">
    If you can read<br>this, your browser<br>doesn't support<br>conic-gradient yet.
</div>
<div class="colorwheel box"></div>

此 CSS 功能在 CSS 图像模块级别 4 的工作草案 中指定,目前仅由最新版本的 Chrome、Android 浏览器和 Safari(macOS 和iOS),但既不是 Firefox 也不是 Edge。查看Can I use 以获得当前支持。

【讨论】:

    【解决方案2】:

    这被称为锥形渐变,目前在纯 CSS 中是不可能的,但它已被提议用于 CSS Image Values 4 草案。最近Lea Verou created a polyfill 为他们服务,也有a PostCSS plugin 做同样的事情。

    【讨论】:

      【解决方案3】:

      CSS

      这可以使用多个部分完成,然后旋转以创建一个圆圈。

      .wheel,
      .umbrella,
      .color {
        content: "";
        position: absolute;
        border-radius: 50%;
        width: 15em;
        height: 15em;
        margin: 0;
        padding: 0;
      }
      .wheel {
        overflow: hidden;
        width: 15em;
        height: 15em;
        position: relative;
      }
      .umbrella {
        position: relative;
        -webkit-transform: scale(1.35);
      }
      .color,
      .color:nth-child(n+7):after {
        clip: rect(0, 15em, 15em, 7.5em);
      }
      .color:after,
      .color:nth-child(n+7) {
        content: "";
        position: absolute;
        border-radius: 50%;
        left: calc(50% - 7.5em);
        top: calc(50% - 7.5em);
        width: 15em;
        height: 15em;
        clip: rect(0, 7.5em, 15em, 0);
      }
      .color:nth-child(1):after {
        background-color: #9ED110;
        transform: rotate(30deg);
        z-index: 12;
      }
      .color:nth-child(2):after {
        background-color: #50B517;
        transform: rotate(60deg);
        z-index: 11;
      }
      .color:nth-child(3):after {
        background-color: #179067;
        transform: rotate(90deg);
        z-index: 10;
      }
      .color:nth-child(4):after {
        background-color: #476EAF;
        transform: rotate(120deg);
        z-index: 9;
      }
      .color:nth-child(5):after {
        background-color: #9f49ac;
        transform: rotate(150deg);
        z-index: 8;
      }
      .color:nth-child(6):after {
        background-color: #CC42A2;
        transform: rotate(180deg);
        z-index: 7;
      }
      .color:nth-child(7):after {
        background-color: #FF3BA7;
        transform: rotate(180deg);
      }
      .color:nth-child(8):after {
        background-color: #FF5800;
        transform: rotate(210deg);
      }
      .color:nth-child(9):after {
        background-color: #FF8100;
        transform: rotate(240deg);
      }
      .color:nth-child(10):after {
        background-color: #FEAC00;
        transform: rotate(270deg);
      }
      .color:nth-child(11):after {
        background-color: #FFCC00;
        transform: rotate(300deg);
      }
      .color:nth-child(12):after {
        background-color: #EDE604;
        transform: rotate(330deg);
      }
      <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>

      要获得模糊效果,只需使用transform 函数添加适当的模糊效果。

      .wheel,
      .umbrella,
      .color {
        content: "";
        position: absolute;
        border-radius: 50%;
        width: 15em;
        height: 15em;
        margin: 0;
        padding: 0;
      }
      .wheel {
        overflow: hidden;
        width: 15em;
        height: 15em;
        position: relative;
      }
      .umbrella {
        position: relative;
        filter: blur(.75em);
        -webkit-filter: blur(.75em);
        -moz-filter: blur(.75em);
        -o-filter: blur(.75em);
        -ms-filter: blur(.75em);
        filter: url(#blur);
        filter: progid: DXImageTransform.Microsoft.Blur(PixelRadius='.75');
        -webkit-transform: scale(1.35);
      }
      .color,
      .color:nth-child(n+7):after {
        clip: rect(0, 15em, 15em, 7.5em);
      }
      .color:after,
      .color:nth-child(n+7) {
        content: "";
        position: absolute;
        border-radius: 50%;
        left: calc(50% - 7.5em);
        top: calc(50% - 7.5em);
        width: 15em;
        height: 15em;
        clip: rect(0, 7.5em, 15em, 0);
      }
      .color:nth-child(1):after {
        background-color: #9ED110;
        transform: rotate(30deg);
        z-index: 12;
      }
      .color:nth-child(2):after {
        background-color: #50B517;
        transform: rotate(60deg);
        z-index: 11;
      }
      .color:nth-child(3):after {
        background-color: #179067;
        transform: rotate(90deg);
        z-index: 10;
      }
      .color:nth-child(4):after {
        background-color: #476EAF;
        transform: rotate(120deg);
        z-index: 9;
      }
      .color:nth-child(5):after {
        background-color: #9f49ac;
        transform: rotate(150deg);
        z-index: 8;
      }
      .color:nth-child(6):after {
        background-color: #CC42A2;
        transform: rotate(180deg);
        z-index: 7;
      }
      .color:nth-child(7):after {
        background-color: #FF3BA7;
        transform: rotate(180deg);
      }
      .color:nth-child(8):after {
        background-color: #FF5800;
        transform: rotate(210deg);
      }
      .color:nth-child(9):after {
        background-color: #FF8100;
        transform: rotate(240deg);
      }
      .color:nth-child(10):after {
        background-color: #FEAC00;
        transform: rotate(270deg);
      }
      .color:nth-child(11):after {
        background-color: #FFCC00;
        transform: rotate(300deg);
      }
      .color:nth-child(12):after {
        background-color: #EDE604;
        transform: rotate(330deg);
      }
      <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>
      
      <svg version="1.1" xmlns="http://www.w3.org/2000/svg">
        <filter id="blur">
          <feGaussianBlur stdDeviation="3" />
        </filter>
      </svg>

      请注意,在旧版本的 IE 或旧浏览器中,sn-ps 将无法工作,因为它们使用 HTML5 技术运行。我建议在本地环境中进行测试。

      【讨论】:

        【解决方案4】:

        恐怕 CSS 不允许线性径向渐变。然而,svg 提供了一个解决方案,尽管很粗糙。请参阅以下主题以获取解决方案。

        How to draw a linear gradient circle by svg?

        svg multiple color on circle stroke

        【讨论】:

        • 不错,但解决方案仅适用于细圆形轮廓
        【解决方案5】:

        您可以使用 3 个用普通圆切割的三角形。每个三角形都通过具有线性渐变的长矩形的中心投影进行变换。 我在 Firefox 中尝试使用 SVG,但 Chromium 不支持 SVG 中的中心投影,但支持锥形渐变,因此请参阅两种浏览器的组合版本。

        <svg version="2" viewBox="-207 -207 414 414" xmlns="http://www.w3.org/2000/svg">
         <defs>
          <radialGradient id="gWt">
           <stop style="stop-color:#fff" offset="0"/>
           <stop style="stop-color:#fff0" offset="1"/>
          </radialGradient>
          <!-- part for firefox: using central projection of 3 rectangles -->
          <linearGradient id="gYM" x1="0" x2="0" y1="0" y2="100%">
           <stop style="stop-color:#ef08" offset="0"/>
           <stop style="stop-color:#ff0" offset=".005"/>
           <stop style="stop-color:#fc0" offset=".1827"/>
           <stop style="stop-color:#f90" offset=".2924"/>
           <stop style="stop-color:#f60" offset=".3728"/>
           <stop style="stop-color:#f00" offset=".5"/>
           <stop style="stop-color:#f06" offset=".6272"/>
           <stop style="stop-color:#f09" offset=".7076"/>
           <stop style="stop-color:#f0c" offset=".8173"/>
           <stop style="stop-color:#f0f" offset=".995"/>
           <stop style="stop-color:#e0f8" offset="1"/>
          </linearGradient>
          <linearGradient id="gCY" href="#gYM">
           <stop style="stop-color:#0ef8" offset="0"/>
           <stop style="stop-color:#0ff" offset=".005"/>
           <stop style="stop-color:#0fc" offset=".1827"/>
           <stop style="stop-color:#0f9" offset=".2924"/>
           <stop style="stop-color:#0f6" offset=".3728"/>
           <stop style="stop-color:#0f0" offset=".5"/>
           <stop style="stop-color:#6f0" offset=".6272"/>
           <stop style="stop-color:#9f0" offset=".7076"/>
           <stop style="stop-color:#cf0" offset=".8173"/>
           <stop style="stop-color:#ff0" offset=".995"/>
           <stop style="stop-color:#fe08" offset="1"/>
          </linearGradient>
          <linearGradient id="gMC" href="#gYM">
           <stop style="stop-color:#f0e8" offset="0"/>
           <stop style="stop-color:#f0f" offset=".005"/>
           <stop style="stop-color:#c0f" offset=".1827"/>
           <stop style="stop-color:#90f" offset=".2924"/>
           <stop style="stop-color:#60f" offset=".3728"/>
           <stop style="stop-color:#00f" offset=".5"/>
           <stop style="stop-color:#06f" offset=".6272"/>
           <stop style="stop-color:#09f" offset=".7076"/>
           <stop style="stop-color:#0cf" offset=".8173"/>
           <stop style="stop-color:#0ff" offset=".995"/>
           <stop style="stop-color:#0fe8" offset="1"/>
          </linearGradient>
          <rect id="r" width="2000" height="700" style="transform:matrix3d(
              -29,0,0,100,
              0,1,0,0,
              0,0,1,0,
              200,-350,1,1
            ); mix-blend-mode:lighten"/>
         </defs>
         <clipPath id="cc">
          <circle r="200" id="c"/>
         </clipPath>
         <circle r="199" fill="#000"/>
         <g clip-path="url(#cc)" id="m">
          <use href="#r" fill="url(#gCY)" transform="rotate(-120)"/>
          <use href="#r" fill="url(#gYM)"/>
          <use href="#r" fill="url(#gMC)" transform="rotate(120)"/>
          <!-- for Chrome use conic gradient (does not work with any svg object but with foreign)
           Firefox ignores this object due to unknown keyword in style -->
         <foreignObject width="400" height="400" x="-200" y="-200" style="background:conic-gradient(from 90deg,
           #f00,#f0f,#00f,#0ff,#0f0,#ff0,#f00);
          background-repeat: no-repeat;
          background-position: center center;
          background-size: auto;"/>
         </g>
         <g>
          <!-- Points for visual test -->
          <circle cx="-200" r="6" fill="#0ff"/>
          <circle cx="-195.6" cy="-41.6" r="6" fill="#0fc"/>
          <circle cx="-182.7" cy="-81.3" r="6" fill="#0f9"/>
          <circle cx="-161.8" cy="-117.6" r="6" fill="#0f6"/>
          <circle cx="-133.8" cy="-148.6" r="6" fill="#0f3"/>
          <circle cx="-100" cy="-173.2" r="6" fill="#0f0"/>
          <circle cx="-61.8" cy="-190.2" r="6" fill="#3f0"/>
          <circle cx="-20.9" cy="-198.9" r="6" fill="#6f0"/>
          <circle cx="20.9" cy="-198.9" r="6" fill="#9f0"/>
          <circle cx="61.8" cy="-190.2" r="6" fill="#cf0"/>
          <circle cx="100" cy="-173.2" r="6" fill="#ff0"/>
          <circle cx="133.8" cy="-148.6" r="6" fill="#fc0"/>
          <circle cx="161.8" cy="-117.6" r="6" fill="#f90"/>
          <circle cx="182.7" cy="-81.3" r="6" fill="#f60"/>
          <circle cx="195.6" cy="-41.6" r="6" fill="#f30"/>
          <circle cx="200" r="6" fill="#f00"/>
          <circle cx="-195.6" cy="41.6" r="6" fill="#0cf"/>
          <circle cx="-182.7" cy="81.3" r="6" fill="#09f"/>
          <circle cx="-161.8" cy="117.6" r="6" fill="#06f"/>
          <circle cx="-133.8" cy="148.6" r="6" fill="#03f"/>
          <circle cx="-100" cy="173.2" r="6" fill="#00f"/>
          <circle cx="-61.8" cy="190.2" r="6" fill="#30f"/>
          <circle cx="-20.9" cy="198.9" r="6" fill="#60f"/>
          <circle cx="20.9" cy="198.9" r="6" fill="#90f"/>
          <circle cx="61.8" cy="190.2" r="6" fill="#c0f"/>
          <circle cx="100" cy="173.2" r="6" fill="#f0f"/>
          <circle cx="133.8" cy="148.6" r="6" fill="#f0c"/>
          <circle cx="161.8" cy="117.6" r="6" fill="#f09"/>
          <circle cx="182.7" cy="81.3" r="6" fill="#f06"/>
          <circle cx="195.6" cy="41.6" r="6" fill="#f03"/>
         </g>
         <circle r="200" fill="url(#gWt)"/>
        </svg>

        使用公式计算偏移值(对于 350x200 的矩形三角形):

        0.5 ± tan(v/255.*pi/3)/350*100.
        

        其中v是变色通道的值。

        HTML 版本(在 Chrome 上全窗口查看 sn-p)

        *{
            margin:0;
            padding:0;
        }
        .c{
           height:90vmin;
           width:90vmin;
           margin:5vmin;
           overflow: hidden;
           border-radius:50%;
           position:absolute;
        }
        .c>div{
           position:relative;
           height:180vmin;
           width:100vmin;
           perspective: 0.40vmin;
           top:-45vmin;
           left:-4.8vmin;
        }
        .c>div>div{
           height: 100%;
           width: 100%;
           left:0;
           top:1%;
           height: 98%;
           transform-origin:99.98% 50%;
           position:relative;
           transform: rotate3d(0, 1, 0, -80deg);
           border:black;
        }
        #YM>div{
           background:linear-gradient(#ef08,#ff0 0.5%,#fc0 18.27%,#f90 29.24%,#f60 37.28%,#f00 50%,#f06 62.72%,#f09 70.76%,#f0c 81.73%,#f0f 99.5%,#e0f8);
        }
        #MC{
           transform: rotateZ(120deg);
        }
        #CY{
           transform: rotateZ(-120deg);
        }
        #MC>div{
           background:linear-gradient(#f0e8,#f0f 0.5%,#c0f 18.27%,#90f 29.24%,#60f 37.28%,#00f 50%,#06f 62.72%,#09f 70.76%,#0cf 81.73%,#0ff 99.5%,#0fe8);
        }
        #CY>div{
           background:linear-gradient(#0ef8,#0ff 0.5%,#0fc 18.27%,#0f9 29.24%,#0f6 37.28%,#0f0 50%,#6f0 62.72%,#9f0 70.76%,#cf0 81.73%,#ff0 99.5%,#fe08);
        }
        <div class="c"><div id="YM"><div></div></div></div>
        <div class="c"><div id="MC"><div></div></div></div>
        <div class="c"><div id="CY"><div></div></div></div>

        【讨论】:

          【解决方案6】:

          SVG 让我的工作非常努力。 我发现的最佳解决方案是使用多个圆形切片并为其着色。而且是纯css3。

          问题是:如何使颜色变化平滑? 我找到了答案: 通过使用模糊滤镜。

          这里是完整的解决方案: Conical Gradients in CSS

          【讨论】:

          • 我刚刚发现在 IE9+ 中模糊滤镜在画布和 svg 之外不存在。所以这个方法不能在IE9+中使用。真是个惊喜!!!
          • 这就是我推荐 SVG/Canvas 的原因,但在看到您的回答后,我认为您不需要支持 IE9。看看我在评论中链接的答案或 Ilya 的答案中提到的 polyfill。 polyfill 也仅使用 Canvas 和/或 SVG。
          • 仅链接的答案不是很有用——当链接失效或内容发生变化时,答案就失去了价值。请更新答案以包含链接中的有用内容,否则此答案有被删除的风险。
          【解决方案7】:

          我只是在为自己的项目提出一个想法。我不想使用“圆锥梯度”,因为此时(2019 年中)对它的支持非常低。所以我想出了以下内容:

            background: 
              radial-gradient(circle at 38% 7% ,rgba(255,255,000,1) 20%,rgba(255,255,000,.0) 38%),
              radial-gradient(circle at 50% 0%,rgba(128,255,000,1) 22%,rgba(128,255,000,.0) 48%),
              radial-gradient(circle at 75% 7% ,rgba(000,255,000,1) 22%,rgba(000,255,000,.0) 48%),
              radial-gradient(circle at 93% 24%  ,rgba(000,255,128,1) 22%,rgba(000,255,128,.0) 48%),
              radial-gradient(circle at 100% 50%,rgba(000,255,255,1) 22%,rgba(000,255,255,.0) 48%),
              radial-gradient(circle at 93% 75% ,rgba(000,128,255,1) 22%,rgba(000,128,255,.0) 48%),
              radial-gradient(circle at 75% 93%,rgba(000,000,255,1) 22%,rgba(000,000,255,.0) 48%),
              radial-gradient(circle at 50% 100% ,rgba(128,000,255,1) 22%,rgba(128,000,255,.0) 48%),
              radial-gradient(circle at 25% 93%,rgba(255,000,255,1) 22%,rgba(255,000,255,.0) 48%),
              radial-gradient(circle at 7% 75%,rgba(255,000,128,1) 22%,rgba(255,000,128,.0) 48%),
              radial-gradient(circle at 0% 50%,rgba(255,000,000,1) 22%,rgba(255,000,000,.0) 48%),
              radial-gradient(circle at 7% 25%,rgba(255,128,000,1) 22%,rgba(255,128,000,.0) 48%);
          

          https://jsfiddle.net/p5vxek3u/

          它不准确,但足够接近我的需要。我在具有 alpha 透明度的东西后面使用它,所以你一次只能看到一小部分。

          我想我会把它留在这里以防万一有人需要它。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2014-02-28
            • 1970-01-01
            • 2012-05-21
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多