How to make a diagonal border gradient?

I have a problem with CSS3. I do not know how to make a diagonal round gradient border: circle example

I found something like this :

.box { width: 250px; height: 250px; margin: auto; background: #eee; border: 20px solid transparent; -moz-border-image: -moz-linear-gradient(top left, #3acfd5 0%, #3a4ed5 100%); -webkit-border-image: -webkit-linear-gradient(top left, #3acfd5 0%, #3a4ed5 100%); border-image: linear-gradient(to bottom right, #3acfd5 0%, #3a4ed5 100%); border-image-slice: 1; } 
 <div class="box"></div> 

But unfortunately, this only works with squares.

Any help would be appreciated.

+7
css css3 css-shapes gradient linear-gradients
source share
2 answers

You can try something like this, I used a pseudo-element with -ve z-index

Note: the background is not transparent since I used background-color for the inner element

 .box { width: 250px; height: 250px; position: relative; margin: auto; margin: 30px; border-radius: 50%; background: #fff; } .box:after { content: ''; position: absolute; top: -15px; bottom: -15px; right: -15px; left: -15px; background-image: linear-gradient(to bottom left, #7B73A4 0%, #150E5E 100%); z-index: -1; border-radius: inherit; } 
 <div class="box"></div> 
+6
source share

A conical gradient is a gradient that runs along an arc of a circle around the center. This is what we see in the colored wheels. As Paulie_D noted, this is currently not possible for CSS, but Lea Verou developed a polyfill for it .

Having said that what you are looking for does not seem to be a conical gradient , it is a normal linear gradient, but applies only to borders. This is not possible with the CSS border-image property because of how it should work according to the specifications .

Field frames, but not its border image, are tied to the corresponding curve


If the center of the circle is a solid color, you can use the approach mentioned in Vitorino's answer. If this is not a solid color (that is, the background of the page is a gradient or image to be displayed), this will not help. In this case, the following approaches can be used.

Using a mask image:

This approach uses a circular mask image to mask the inside of the circle. This pretends that only the border has a gradient applicable to it. the disadvantage is that this feature is currently only supported in browsers running Webkit .

 .border-gradient-mask { height: 200px; width: 200px; border-radius: 50%; background-image: linear-gradient(to bottom left, #7B73A4 0%, #150E5E 100%); -webkit-mask-image: radial-gradient(circle at center, transparent 57%, white 58%); mask-image: radial-gradient(circle at center, transparent 57%, white 58%); } body { background: radial-gradient(circle at center, sandybrown, chocolate); } 
 <div class="border-gradient-mask"></div> 

Using SVG Shape or Mask:

Another approach is to use the SVG circle to create a circle and then assign the stroke property to the gradient. Gradient also uses gradientTransform , because this is the only way to create linear gradients with direct SVG.

 .border-gradient-svg { position: relative; height: 200px; width: 200px; border-radius: 50%; } .border-gradient-svg svg { position: absolute; top: 0px; left: 0px; height: 100%; width: 100%; } .border-gradient-svg circle { fill: transparent; stroke: url(#grad); stroke-width: 8; } body { background: radial-gradient(circle at center, sandybrown, chocolate); } 
 <div class="border-gradient-svg"> <svg viewBox="0 0 100 100"> <defs> <linearGradient id="grad" gradientUnits="objectBoundingBox" gradientTransform="rotate(135 0.5 0.5)"> <stop offset="0%" stop-color="#7B73A4" /> <stop offset="100%" stop-color="#150E5E" /> </linearGradient> </defs> <circle r="46" cx="50" cy="50" /> </svg> </div> 

You can do the same with the SVG mask . All you need to do is create a mask with two circle elements, fill the big circle with white, the smaller circle with black, and then apply the mask to our original circle element. The area occupied by the smaller circle (with black fill) will be transparent.

 .border-gradient-svg { position: relative; height: 200px; width: 200px; border-radius: 50%; } .border-gradient-svg svg { position: absolute; top: 0px; left: 0px; height: 100%; width: 100%; } .border-gradient-svg .grad-border { fill: url(#grad); mask: url(#masker); } body { background: radial-gradient(circle at center, sandybrown, chocolate); } 
 <div class="border-gradient-svg"> <svg viewBox="0 0 100 100"> <defs> <linearGradient id="grad" gradientUnits="objectBoundingBox" gradientTransform="rotate(135 0.5 0.5)"> <stop offset="0%" stop-color="#7B73A4" /> <stop offset="100%" stop-color="#150E5E" /> </linearGradient> <mask id="masker" x="0" y="0" width="100" height="100"> <circle r="50" cx="50" cy="50" fill="#fff" /> <circle r="42" cx="50" cy="50" fill="#000" /> </mask> </defs> <circle r="50" cx="50" cy="50" class="grad-border"/> </svg> </div> 

Using clip path:

Another approach to creating this would be to use clip-path (with built-in SVG) with clip-rule set to evenodd . The advantage of the clip solution compared to others is that it will trigger the effects of freezing only when it hangs on a filled area (and not in a transparent area). Disadvantage lies in the fact that IE does not support clicks (even with SVG).

 .border-gradient-clip { height: 200px; width: 200px; border-radius: 50%; background-image: linear-gradient(to bottom left, #7B73A4 0%, #150E5E 100%); -webkit-clip-path: url(#clipper); clip-path: url(#clipper); } body { background: radial-gradient(circle at center, sandybrown, chocolate); } 
 <svg width="0" height="0"> <defs> <clipPath id="clipper" clipPathUnits="objectBoundingBox"> <path d="M0,0.5 a0.5,0.5 0 1,0 1,0 a0.5,0.5 0 1,0 -1,0z M0.08,0.5 a0.42,0.42 0 1,0 0.84,0 a0.42,0.42 0 1,0 -0.84,0z" clip-rule="evenodd" /> </clipPath> </defs> </svg> <div class="border-gradient-clip"></div> 
+10
source share

All Articles