简体   繁体   English

CSS3 以循环方式线性渐变

[英]CSS3 Linear Gradient in a circular way

I am wondering if it is possible to do something like this with css gradients:我想知道是否可以用 css 渐变做这样的事情:

色轮

I have searched a lot and all the gradients are either "Linear" or "Radial".我搜索了很多,所有的渐变都是“线性”或“径向”。 My desired gradient is linear in a circular way!我想要的渐变是以圆形的方式线性的!

It's doable now - at least in Chrome.现在是可行的——至少在 Chrome 中是这样。 The CSS propertyconic-gradient can easily achieve this: 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>

This CSS function is specified in a working draft of CSS Images Module Level 4 and is currently only implement by recent version of Chrome, Android browser and Safari (macOS and iOS) but neither by Firefox or Edge.此 CSS 功能在CSS 图像模块级别 4工作草案中指定,目前仅由最新版本的 Chrome、Android 浏览器和 Safari(macOS 和 iOS)实现,但 Firefox 或 Edge 均未实现。 Check Can I use for current support.检查我可以使用当前支持。

This is called Conical Gradient and is not currently possible in pure CSS, but it has been proposed for the CSS Image Values 4 draft.这被称为锥形渐变,目前在纯 CSS 中是不可能的,但它已被提议用于 CSS Image Values 4 草案。 Recently Lea Verou created a polyfill for them, there is also a PostCSS plugin that does the same.最近Lea Verou为他们创建了一个 polyfill ,还有一个 PostCSS 插件可以做同样的事情

CSS CSS

This can be completed using multiple sections which are then rotated to create a circle.这可以使用多个部分来完成,然后旋转这些部分以创建一个圆。

 .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>

To then get the blur, just use the transform function to add an appropriate blur.要获得模糊效果,只需使用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>

Please note, in older versions of IE or old browsers, snippets won't work as they use HTML5 technology to run.请注意,在旧版本的 IE 或旧浏览器中,代码段将无法运行,因为它们使用 HTML5 技术运行。 I recommend testing in a local environment.我建议在本地环境中测试。

I'm afraid CSS doesn't allow for a linear-radial gradient.恐怕 CSS 不允许线性径向渐变。 However, svg provides a solution, albeit crude.然而,svg 提供了一个解决方案,尽管很粗糙。 See the below topics for a solution.请参阅以下主题以获取解决方案。

How to draw a linear gradient circle by svg? 如何通过 svg 绘制线性渐变圆?

svg multiple color on circle stroke 圆形笔划上的 svg 多种颜色

You can use 3 triangles cuted with common circle.您可以使用用普通圆切割的 3 个三角形。 Each triangle is transformed by central projection from long rectangle with linear gradient.每个三角形都由具有线性渐变的长矩形的中心投影转换而来。 I try it with SVG in Firefox, but Chromium does not support central projection in SVG but supports conical gradients, so see combined version for both browsers.我在 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>

Offset values is calculated using the formula (for rectangular triangle 350x200):偏移值使用以下公式计算(对于矩形三角形 350x200):

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

Where v is the value of the changing color channel.其中v是改变颜色通道的值。

HTML version (view the snippet in full window on Chrome) HTML 版本(在 Chrome 上以全窗口查看代码段)

 *{ 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>

SVG made my work very hard. SVG 使我的工作变得非常困难。 The best solution I found is to use multiple circle slices and color them.我发现的最佳解决方案是使用多个圆形切片并为它们着色。 And it is pure css3.它是纯 css3。

The question is: How to make the color changes smooth?问题是:如何让颜色变化平滑? I found the answer: By using blur filters.我找到了答案:通过使用模糊滤镜。

Here is the complete solution: Conical Gradients in CSS这是完整的解决方案: CSS 中的锥形渐变

I was just playing with an idea for this for my own project.我只是在为我自己的项目考虑这个想法。 I didn't wanna use 'conic-gradient' as the support is very low for it at this time (mid 2019).我不想使用“conic-gradient”,因为此时(2019 年年中)对它的支持非常低。 so I came up with the following:所以我想出了以下内容:

  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/ https://jsfiddle.net/p5vxek3u/

Its not exact, but its close enough for my needs.它不准确,但足以满足我的需求。 I'm using it behind something with alpha transparency so you only get to see a small part at a time.我在具有 alpha 透明度的东西后面使用它,所以你一次只能看到一小部分。

I thought I'd leave it here in case anyone needed it.我想我会把它留在这里以防万一有人需要它。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM