SVG with radialGradient not work in browsers - css

Problem:
The following svg code not work in browsers:
<svg width="207" height="209" viewBox="0 0 207 209" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M96.2318 8.29356C149.379 4.30837 195.684 44.2918 199.657 97.599C203.631 150.906 163.767 197.351 110.62 201.336C57.473 205.321 11.1677 165.338 7.19452 112.031C3.2213 58.7234 43.0847 12.2787 96.2318 8.29356Z" stroke="url(#paint0_angular)" stroke-width="2"/>
<defs>
<radialGradient id="paint0_angular" cx="0" cy="0" r="1" gradientUnits="userSpaceOnUse" gradientTransform="translate(103.426 104.815) rotate(-94.2626) scale(96.7891 96.5016)">
<stop stop-color="#FF7870"/>
<stop offset="1" stop-color="#FF7870" stop-opacity="0"/>
</radialGradient>
</defs>
</svg>
If replace stroke atribute in path fragment of svg with simple color (for example #f00) - it works, but with radial gradient - not works.
Question:
Is there a way to make this svg valid for browsers?
OR
Is there a way to make this element with HTML & CSS?
All information, that I've found not solves the problems, because:
Background of circle must be transparent
Gradient has grades around the circle (not from top to bottom)
P. S. Expected view of svg:

You can do this using mask and conic-gradient
.box {
width: 200px;
height: 200px;
margin: 20px auto;
border-radius: 50%;
background: conic-gradient(#0000, red);
-webkit-mask: radial-gradient(farthest-side, #0000 calc(100% - 10px), #000 calc(100% - 9px));
mask: radial-gradient(farthest-side, #0000 calc(100% - 10px), #000 calc(100% - 9px));
}
body {
background: url(https://picsum.photos/id/100/1000/1000) center/cover;
}
<div class="box">
</div>

Related

Can I create a stright line having circle at both ends with Clip path CSS?

I will like to achieve something like this
I have tried using clip path, but I am struggling achieving the desired result. Any help will be appreciated
You need mask for this:
.box {
--h: 50px; /* height of the element */
--b: 60%; /* height of the bar */
width: 200px;
height: var(--h);
background: linear-gradient(90deg,red, blue);
-webkit-mask:
linear-gradient(#000 0 0)
50%/calc(100% - var(--h)) var(--b) no-repeat,
radial-gradient(calc(var(--h)/2) at calc(var(--h)/2) 50%, #000 96%, #0000)
0 50%/calc(100% - var(--h)) 100% repeat-x;
}
<div class="box"></div>
<div class="box" style="width:300px;--b:45%;"></div>
Honestly, you'd probably be better off using an SVG (https://developer.mozilla.org/en-US/docs/Web/SVG) instead of a clip-path if you need something like that. Here's one I did really quickly in Illustrator but you can make SVGs in several other apps as well. Not saying you necessarily couldn't use a clip-path to accomplish this but it seems like it would be more work than the 5 minutes it took to make the SVG and map the gradient.
svg {
fill: url(#gradient);
}
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" width="500px" height="250px" viewBox="0 0 500 250">
<defs>
<linearGradient id="gradient">
<stop offset="0%" stop-color="#00ff77" />
<stop offset="100%" stop-color="#ffef00" />
</linearGradient>
</defs>
<path d="M350.333,84.055c-15.52,0-28.956,8.881-35.531,21.833H105.531C98.957,92.937,85.52,84.055,70,84.055
c-22,0-39.833,17.834-39.833,39.833c0,22,17.834,39.834,39.833,39.834c15.52,0,28.956-8.881,35.531-21.833h209.271
c6.574,12.952,20.011,21.833,35.53,21.833c21.999,0,39.833-17.834,39.833-39.834C390.166,101.889,372.332,84.055,350.333,84.055z" />
</svg>

Linear Gradient with Round corners

I am creating a background image using linear gradients. How to to add round corners for each linear gradient.
Please provide solution without any changes in html (cant use more than one div)
.myStyle {
height:500px;
width: 900px;
background-image:
linear-gradient(lightgrey , blue),
linear-gradient(lightgrey , blue),
linear-gradient(lightgrey , blue),
linear-gradient(lightgrey , blue);
background-repeat: no-repeat;
background-size:
100px 40px,
500px 60px,
250px 50px,
250px 60px;
background-position:
0 0,
0 80px,
0 160px,
0 220px;
}
<div class="myStyle"></div>
Not really sure what is your goal but if you want gradient with solid color to have radius you can build it using multiple linear-gradient and radial gradient.
Here is an example where I am using CSS variable to easily define the position, size and radius. This is one of your gradient. You need to repeat the code for all the gradient and adjust the different values.
.box {
--w:200px; /*Gradient width*/
--h:100px; /*Gradient height*/
--r:10px; /*Gradient radius*/
--x:50px; /*Gradient position x*/
--y:40px; /*Gradient position y*/
--c:grey; /*Gradient color*/
margin:0;
height:100vh;
background:
radial-gradient(farthest-side,var(--c) 98%,transparent 100%) var(--x) var(--y) / calc(2*var(--r)) calc(2*var(--r)),
radial-gradient(farthest-side,var(--c) 98%,transparent 100%) calc(var(--x) + var(--w) - 2*var(--r)) var(--y) / calc(2*var(--r)) calc(2*var(--r)),
radial-gradient(farthest-side,var(--c) 98%,transparent 100%) var(--x) calc(var(--y) + var(--h) - 2*var(--r)) / calc(2*var(--r)) calc(2*var(--r)),
radial-gradient(farthest-side,var(--c) 98%,transparent 100%) calc(var(--x) + var(--w) - 2*var(--r)) calc(var(--y) + var(--h) - 2*var(--r)) / calc(2*var(--r)) calc(2*var(--r)),
linear-gradient(var(--c),var(--c)) calc(var(--x) + var(--r)) var(--y) / calc(var(--w) - 2*var(--r)) var(--h),
linear-gradient(var(--c),var(--c)) var(--x) calc(var(--y) + var(--r)) / var(--w) calc(var(--h) - 2*var(--r));
background-repeat:no-repeat;
width:300px;
height:200px;
display:inline-block;
border:1px solid;
}
<div class="box"></div>
<div class="box" style="--w:80px;--r:30px;--c:red;"></div>
<div class="box" style="--h:80px;--r:40px;--x:5px;--y:5px;--c:blue"></div>
The cleanest might actually be to use svg for this instead of css-gradients.
You'll load it as a data-uri in the background-image property.
To make the rounded corner, you can use the rx and ry attributes of the <rect> element.
To make the gradients, you can use svg's <linearGradient> elements.
.mystyle {
height: 900px;
width: 500px;
background-image: url("data:image/svg+xml,<svg xmlns='http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg' width='500' height='900' viewBox='0 0 500 900'><defs><linearGradient id='blue-grad' gradientTransform='rotate(90)'><stop stop-color='lightgrey' offset='0%'/><stop stop-color='blue' offset='100%'/></linearGradient></defs><rect x='0' y='0' width='100' height='40' rx='15' fill='url(%23blue-grad)'/><rect x='0' y='80' width='500' height='60' rx='15' fill='url(%23blue-grad)'/><rect x='0' y='160' width='250' height='50' rx='15' fill='url(%23blue-grad)'/><rect x='0' y='220' width='250' height='60' rx='15' fill='url(%23blue-grad)'/></svg>");
background-size: cover;
background-repeat: no-repeat;
}
/*
SVG Image unminified:
<svg xmlns="http://www.w3.org/2000/svg" width="500" height="900">
<defs>
<linearGradient id="blue-grad" gradientTransform="rotate(90)">
<stop stop-color="lightgrey" offset="0%"/>
<stop stop-color="blue" offset="100%"/>
</linearGradient>
</defs>
<rect x="0" y="0" width="100" height="40" rx="15" fill="url(#blue-grad)"/>
<rect x="0" y="80" width="500" height="60" rx="15" fill="url(#blue-grad)"/>
<rect x="0" y="160" width="250" height="50" rx="15" fill="url(#blue-grad)"/>
<rect x="0" y="220" width="250" height="60" rx="15" fill="url(#blue-grad)"/>
</svg>
*/
<div class="mystyle"></div>
Maybe try this approach instead of making one div output multiple gradient boxes?
.myStyle {
width:150px;
height:100px;
background:linear-gradient(black,purple);
border-radius:20px;
}
<div class="myStyle"></div>

SVG background only works in IE

I'm trying to put a radialGradient background in a SVG circle and nothing will work. It only works in Internet Explorer. Even just a solid color background won't work. I must have setup my document incorrectly. Maybe this is due to cloning from a hidden copy? The actual project can be seen here. I have it hosted here. To see the problem circle click "New Player". I'm trying now in HTML5, but I believe that I've also had this problem in xhtml.
index.html:
<!doctype html>
<html lang="en-US">
<head>
<link rel="stylesheet" href="styles.css" />
</head>
<body style="background-color:#EEEEEE;">
<div>
<svg xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 225 140" preserveAspectRatio="xMidYMid slice"
id="d00" class="svg">
<defs>
<radialGradient cx="20%" cy="20%" id="gearShift">
<stop offset="0%" style="stop-color:white;"/>
<stop offset="80%" style="stop-color:black;"/>
</radialGradient>
<style type="text/css"><![CDATA[
.gear {
background: radial-gradient(ellipse at 20% 20%, white 20%, black 80%);
}
]]></style>
</defs>
<circle id="gear00" class="gear" cx="70" cy="20" r="10" style="stroke:black;" fill="url(#gearShift)" />
</svg>
</div>
</body>
</html>
styles.css:
.gear{
stroke:black;
background: radial-gradient(ellipse at 20% 20%, white 20%, black 80%);
background-color:red;
background-image:-webkit-gradient(linear, left top, right top, from(red), to(#f06d06));
background-image:-webkit-linear-gradient(left, red, #f06d06);
background-image:linear-gradient(to right, red, orange);
}
I've commented out the following rule in styles.css which shows the Player 0 that all the other players are copied from. This allows the background of the circle to be shown. Once you've added Player 1 when switching between players, whenever Player 0 is hidden, the background on all copies of this circle are hidden.
#_00, #sort00, #playertab00, .hidden {
/*display:none !important;*/
}
Sorry, this might be a duplicate of this question. It seems like the issue stems from the fact that the background in the defs section is linked to the circle by an ID. I was cloning it and creating multiple radialGradients with the same ID.
I've fixed this by splitting the def into its own svg element.
<body>
<svg xmlns="http://www.w3.org/2000/svg" id="svgDefs" class="svgDefs">
<defs>
<radialGradient cx="35%" cy="35%" id="gearShift">
<stop offset="0%" style="stop-color:white;stop-opacity:1"/>
<stop offset="50%" style="stop-color:black;"/>
</radialGradient>
</defs>
</svg>
<svg xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 225 140" preserveAspectRatio="xMidYMid slice"
id="d00" class="svg">
<circle id="gear00" class="gear" fill="url(#gearShift)" cx="70" cy="20" r="10" style="stroke:black;"/>
</svg>
</body>

SVG working on html image tag -- not on HTML5 canvas

I have a problem here. I need something to be implemented onclick of a button. I searched on the net and found out that SVG was an easier way to do it rather than CSS stylesheets.
I have an HTML5 canvas (which is basically a snapshot from a video stream that I have taken and drawn on to the HTML 5 canvas using drawImage()). On click of a button, I want the image with the following effect to come on the canvas instead of the original image.
My problem is that I am able to replicate the effect if I apply the effect on just an image. However, on the canvas it gives me the mask separately and the image separately. This is the code that I am using for the SVG
<svg height="0">
<defs>
<mask id="mask-radial">
<rect width="500" height="500" fill="url(#g1)"></rect>
<radialGradient id="g1" cx="80%" cy="80%" r="100%">
<stop stop-color="black" offset="50%"/>
<stop stop-color="white" offset="110%"/>
</radialGradient>
</mask>
<!--<mask id="mask-linear">
<rect width="400" height="300" fill="url(#l1)"></rect>
<linearGradient id="l1" x1="0" y1="0" x2="0" y2="1">
<stop stop-color="white" offset="0%"/>
<stop stop-color="black" offset="30%"/>
<stop stop-color="white" offset="100%"/>
</linearGradient>
</mask> -->
<filter id="filtre1">
<feGaussianBlur in="SourceGraphic" stdDeviation="5"/>
</filter>
<!-- <filter id="filtre2">
<feGaussianBlur in="SourceGraphic" stdDeviation="10"/>
</filter> -->
</defs>
</svg>
This is how I am calling it in CSS
.effet{
width: 500px; height: 500px;
margin: 0 auto 50px auto;
box-shadow: 0 1px 5px rgba(0,0,0,.5);
}
.effet img{
position: absolute;
}
.filtre--r{
-webkit-mask: -webkit-radial-gradient( center, closest-side, transparent 50%, black 80%);
-webkit-mask: radial-gradient( closest-side at center, transparent 50%, black 80%);
-webkit-filter: blur(40px);
mask: url('#mask-radial');
filter: url('#filtre1');
}
and these are my HTML elements.
<div class="effet">
<img src="/static/images/noEffect.png" alt="" />
<img class="filtre filtre--r" src="/static/images/noEffect.png" alt="" />
</div>
Can somebody please tell me how I can recreate the effect for my canvas? Thanks in advance.
I researched and found that HTML5 Canvas radial gradient was an effective solution.
var lightSize = 100;
var x = 200;
var y = 200;
var radialGradient = context.createRadialGradient(x, y, 0,x, y, lightSize);
radialGradient.addColorStop(0, "#FFFF99"); // color at start circle
radialGradient.addColorStop(0.9, "#FFFF99"); //color at offset 0.9
radialGradient.addColorStop(1, '#7D7D5C');// color of finish circle
context.globalCompositeOperation = "multiply";
context.fillStyle = radialGradient;
Was able to recreate the effect totally.

Vertically-repeating horizontal gradient in CSS

I'm having trouble coming up with a pure CSS mechanism to get a particular background pattern happening.
What I'm looking for is a horizontal gradient that is also repeated vertically, with a gap between each instance. Example:
(source: howsfamily.net)
I can get the horizontal effect easily enough
background: linear-gradient(to left, white, red, white); background-size: 100% 50px; background-repeat: no-repeat; }
I can get the vertical effect (without the horizontal gradient)
background: linear-gradient(to bottom, red 0px, red 50px, transparent 50px, transparent 100%); background-size: 100% 150px; background-repeat: repeat-y;
Does anyone know how to combine the two?
Extending from comment:
Since you're already going for linear-gradient, I would suggest using an SVG for more freedom and better compatibility.
Example: http://dabblet.com/gist/6632969
The SVG that is used (beautified):
<?xml version="1.0"?>
<svg width="10" height="100" viewBox="0 0 10 100" preserveAspectRatio="none" version="1.1" xmlns="http://www.w3.org/2000/svg">
<defs>
<linearGradient id="l">
<stop offset="0%" stop-color="white" />
<stop offset="50%" stop-color="red" />
<stop offset="100%" stop-color="white" />
</linearGradient>
</defs>
<rect x="0" y="0" width="10" height="50" fill="url(#l)" />
</svg>
You can tweak the height and viewBox here and background-size in CSS to fit your need.
The preserveAspectRatio attribute here is crucial, otherwise the background image may not stretch.

Resources