Problem
My <radialGradient> for the ellipses below won't show in Chrome based browsers, but will show the other content. Whereas firefox will show both.
I read this page, and this page, and they gave clues that it was a radialGradient issue, but I'm not dealing with any external files like the first page has, nor trying a conical gradient like the other one.
Goal
I want to have my first <svg> tag strictly for <defs> only, so I can reference parts later on to cut down the file size, and keep it clean. And to get rid of blank space, I added style="display: none;" to this first <svg> tag.
What I tried
Once I do the above, I add my other <svg>'s (email, SMS, etc) to reference them many times. Again, the first blank svg with the defs does not show (which is good), and the <path>, ellipses, etc. will show fine in Firefox, but not Chrome.
The ellipses will only show in Chrome when I take off style="display: none;" from the first svg, even though they're in the same element.
When I noticed it might be a <radialGradient> issue, I added fill:yellow;stroke:purple;stroke-width:2 to my ellipses style attribute, and that makes the ellipse show with that styling, so I know the ellipse is there, but the gradient won't show inside it.
Anyone know why the <radialGradient> will not show up in Chrome based browsers while style="display: none;" is on the first svg??? Or does anyone have any work arounds to fix this / do this more efficiently??? I know I can put everything in 1 svg, but I need them all separate so I can style them with css more easily, since they're all icons.
Thanks!
<!DOCTYPE html>
<html>
<body>
<svg
version="1.1"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
style="display:none;"
>
<defs>
<symbol id="ellipsesymbol" viewBox="0 0 126 76">
<radialGradient id="_Radial1" cx="0" cy="0" r="1" gradientUnits="userSpaceOnUse" gradientTransform="matrix(62.5,0,0,37.5,62.5069,37.5066)">
<stop offset="0" style="stop-color:#000;stop-opacity:0.5"/>
<stop offset="0.62" style="stop-color:#170725;stop-opacity:0.58"/>
<stop offset="0.82" style="stop-color:#4e187f;stop-opacity:0.78"/>
<stop offset="1" style="stop-color:#8a2be2;stop-opacity:1"/>
</radialGradient>
<ellipse cx="62.5" cy="37.839" rx="62.5" ry="37.5" style="fill:url(#_Radial1);" />
</symbol>
<symbol id="emailsymbol" viewBox="0 0 126 76">
<path
d="M31.15,17.125l0,40.763l62.713,0l0,-40.763l-62.713,-0Zm36.687,24.928c-1.411,1.411 -3.292,2.195 -5.33,2.195c-2.038,0 -3.92,-0.784 -5.331,-2.195l-21.792,-21.792l54.089,-0l-21.636,21.792Zm-17.402,-4.546l-16.149,16.148l0,-32.297l16.149,16.149Zm1.097,1.097l4.547,4.547c1.724,1.724 4.076,2.665 6.428,2.665c2.508,0 4.703,-0.941 6.428,-2.665l4.547,-4.547l16.148,16.149l-54.246,-0l16.148,-16.149Zm23.047,-1.097l16.149,-16.149l-0,32.454l-16.149,-16.305Z"
style="fill:#00bfff;fill-rule:nonzero;"/>
</symbol>
<symbol id="SMSsymbol" viewBox="0 0 126 76">
<path d="M98.587,27.064c0,-4.29 -3.483,-7.773 -7.773,-7.773l-56.464,0c-4.29,0 -7.773,3.483 -7.773,7.773l0,15.546c0,4.29 3.483,7.773 7.773,7.773l15.631,0l-9.002,13.326l19.803,-13.326l30.032,0c4.29,0 7.773,-3.483 7.773,-7.773l0,-15.546Z"
style="fill:#00bfff;"/>
<text x="36.276px" y="42.521px" style="font-family:'KnightsTemplar', 'Knights Templar';font-size:25.665px;">SMS</text>
</symbol>
<!-- .... -->
</defs>
</svg>
<svg id="emailgroup">
<use xlink:href="#ellipsesymbol" />
<use xlink:href="#emailsymbol" />
</svg>
<svg id="smsgroup">
<use xlink:href="#ellipsesymbol" />
<use xlink:href="#SMSsymbol" />
</svg>
<!-- more svg's.... -->
</body>
</html>
Instead of display:none, you can hide the first SVG with width="0" height="0". Then it works in Chrome:
<svg xmlns="http://www.w3.org/2000/svg" width="0" height="0">
<defs>
<symbol id="ellipsesymbol" viewBox="0 0 126 76">
<radialGradient id="_Radial1" cx="0" cy="0" r="1" gradientUnits="userSpaceOnUse" gradientTransform="matrix(62.5,0,0,37.5,62.5069,37.5066)">
<stop offset="0" style="stop-color:#000;stop-opacity:0.5"/>
<stop offset="0.62" style="stop-color:#170725;stop-opacity:0.58"/>
<stop offset="0.82" style="stop-color:#4e187f;stop-opacity:0.78"/>
<stop offset="1" style="stop-color:#8a2be2;stop-opacity:1"/>
</radialGradient>
<ellipse cx="62.5" cy="37.839" rx="62.5" ry="37.5" style="fill:url(#_Radial1);" />
</symbol>
<symbol id="emailsymbol" viewBox="0 0 126 76">
<path d="M31.15,17.125l0,40.763l62.713,0l0,-40.763l-62.713,-0Zm36.687,24.928c-1.411,1.411 -3.292,2.195 -5.33,2.195c-2.038,0 -3.92,-0.784 -5.331,-2.195l-21.792,-21.792l54.089,-0l-21.636,21.792Zm-17.402,-4.546l-16.149,16.148l0,-32.297l16.149,16.149Zm1.097,1.097l4.547,4.547c1.724,1.724 4.076,2.665 6.428,2.665c2.508,0 4.703,-0.941 6.428,-2.665l4.547,-4.547l16.148,16.149l-54.246,-0l16.148,-16.149Zm23.047,-1.097l16.149,-16.149l-0,32.454l-16.149,-16.305Z"
style="fill:#00bfff;fill-rule:nonzero;"/>
</symbol>
<symbol id="SMSsymbol" viewBox="0 0 126 76">
<path d="M98.587,27.064c0,-4.29 -3.483,-7.773 -7.773,-7.773l-56.464,0c-4.29,0 -7.773,3.483 -7.773,7.773l0,15.546c0,4.29 3.483,7.773 7.773,7.773l15.631,0l-9.002,13.326l19.803,-13.326l30.032,0c4.29,0 7.773,-3.483 7.773,-7.773l0,-15.546Z"
style="fill:#00bfff;"/>
<text x="36.276px" y="42.521px" style="font-family:'KnightsTemplar', 'Knights Templar';font-size:25.665px;">SMS</text>
</symbol>
</defs>
</svg>
<svg id="emailgroup">
<use href="#ellipsesymbol" />
<use href="#emailsymbol" />
</svg>
<svg id="smsgroup">
<use href="#ellipsesymbol" />
<use href="#SMSsymbol" />
</svg>
Also note that xlink:href is deprecated, and you can simply use href now:
https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/href
I've followed this tuto in order to implement a progress ring for my Vue application. I still have an extra requirement: fill the circle with an image. That's the point I've reached to, using a pattern (copy pasted from my browser in order to avoid adding the extra complexity of Vue property evaluations):
HTML
<div>
<svg
height="600"
width="600">
<defs>
<pattern id="service" x="0%" y="0%" height="100%" width="100%"
viewBox="0 0 100 100">
<image x="5" y="5" width="90" height="90" href="https://upload.wikimedia.org/wikipedia/commons/thumb/7/7a/Selfie_icon.svg/2000px-Selfie_icon.svg.png"></image>
</pattern>
<linearGradient id="gradient">
<stop offset="0%" stop-color="#f6921e"/>
<stop offset="100%" stop-color="#f6921e88"/>
</linearGradient>
</defs>
<circle
stroke="url(#gradient)"
stroke-dasharray="1709.0264035528476 1709.0264035528476"
style="stroke-dashoffset: 512.708;"
stroke-linecap="round"
stroke-width="14"
fill="url(#service)"
r="272"
cx="300"
cy="300"
/>
</svg>
</div>
CSS
circle {
transition: stroke-dashoffset 0.35s;
transform: rotate(-90deg);
transform-origin: 50% 50%;
}
However, I find that rotating the circle obviously rotates its filling too.
Is there any way to overcome this problem? Why does the example rotate the entire SVG to make the circle gap be in the upside?
Codepen
You can use another circle in your SVG, one for the border and one for the background, then rotate just the circle with the border:
.circle-border {
transition: stroke-dashoffset 0.35s;
transform: rotate(-90deg);
transform-origin: 50% 50%;
}
<!-- begin snippet: js hide: false console: true babel: false -->
<div>
<svg height="600" width="600">
<defs>
<pattern id="service" x="0%" y="0%" height="100%" width="100%" viewBox="0 0 100 100">
<image x="5" y="5" width="90" height="90" href="https://upload.wikimedia.org/wikipedia/commons/thumb/7/7a/Selfie_icon.svg/2000px-Selfie_icon.svg.png"></image>
</pattern>
<linearGradient id="gradient">
<stop offset="0%" stop-color="#f6921e"/>
<stop offset="100%" stop-color="#f6921e88"/>
</linearGradient>
</defs>
<circle
stroke="url(#gradient)"
stroke-dasharray="1709.0264035528476 1709.0264035528476"
style="stroke-dashoffset: 512.708;"
stroke-linecap="round"
stroke-width="14"
fill="transparent"
class="circle-border"
r="272"
cx="300"
cy="300"
/>
<circle
stroke-width="0"
fill="url(#service)"
class="circle-bg"
r="272"
cx="300"
cy="300"
/>
</svg>
</div>
I tried to make it with border but gradient makes it impossible. Maybe I can make four divs and make it like that?
CSS might not be the best way to create such shapes. You should use SVG instead.
We can use SVG's path element to create a pointing arrow like shape and fill it with gradient created with linearGradient.
Only one attribute d is used to define shapes in path element. This attribute itself contains a number of short commands and few parameters that are necessary for those commands to work.
Here is a detailed information about SVG paths:
body {
text-align: center;
background: #333;
margin: 20px;
}
<svg width="400" height="400" viewBox="0 0 400 400" xmlns="http://www.w3.org/2000/svg">
<defs>
<linearGradient id="gradient">
<stop offset="0" stop-color="#212121"></stop>
<stop offset="1" stop-color="#a7a7a7"></stop>
</linearGradient>
<path id="arrow" x="0" y="0" d="M0,200
A200,200 0, 0, 1, 200,0
L225,25
L200,50
A150,150, 0, 0, 0 50,200
L25,175" fill="url(#gradient)" />
</defs>
<use xlink:href="#arrow" transform="translate(0,400) rotate(270)"></use>
<use xlink:href="#arrow" transform="translate(400,400) rotate(180)"></use>
<use xlink:href="#arrow" transform="translate(400,0) rotate(90)"></use>
<use xlink:href="#arrow"></use>
</svg>
I'm trying to use part of an SVG as a tiling background. However I'm having great problems making it work properly.
I think a picture will illustrate the problem best:
demonstration picture
This is my CSS:
body {
background: url("tiletest.svg#svgView(viewBox(120 32 150 64))");
background-size: 30px 32px;
}
And here is the code of the SVG I'm using for the demonstration:
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 21.0.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg height="100" width="360" version="1.1" id="Lager_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 360 100" style="enable-background:new 0 0 360 100;" xml:space="preserve">
<style type="text/css">
.st0{fill:url(#SVGID_1_);}
.st1{fill:#13FF00;}
.st2{fill:#2732FF;}
</style>
<g>
<linearGradient id="SVGID_1_" gradientUnits="userSpaceOnUse" x1="9.094947e-13" y1="9.094947e-13" x2="100" y2="100">
<stop offset="0" style="stop-color:#E7FF00"/>
<stop offset="1" style="stop-color:#FF0000"/>
</linearGradient>
<rect class="st0" width="100" height="100"/>
</g>
<polygon class="st1" points="174.68,0 190.92,32.92 227.25,38.2 200.96,63.82 207.17,100 174.68,82.92 142.19,100 148.39,63.82
122.11,38.2 158.43,32.92 "/>
<circle class="st2" cx="310" cy="50" r="50"/>
</svg>
As you can see the full viewbox in the SVG is 0 0 360 100 and when I call the SVG in the CSS I'm giving it a new viewbox of 120 32 150 64, as well as changing the background size accordingly (though I'm pretty sure this shouldn't matter anyway as the svg defined by the viewbox is supposed to expand to fill the container no matter size,right?).
I've tried fiddling with the viewbox in the SVG, with the width and height, with the preserveAspectRatio attribute, and so far nothing has worked. What am I doing wrong?
<update>
While what I wrote below is useful it did not fully fix your problem. With the proviso that Safari and iOs support is flakey, I got your code working by removing the height and width on the SVG as below:
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 360 100">
<linearGradient id="grad" x2="100" y2="100" gradientUnits="userSpaceOnUse">
<stop offset="0" stop-color="#E7FF00"/>
<stop offset="1" stop-color="#F00"/>
</linearGradient>
<path d="M0 0h100v100H0z" fill="url(#grad)"/>
<path d="M174.68 0l16.24 32.92 36.33 5.28-26.29 25.62 6.21 36.18-32.49-17.08L142.19 100l6.2-36.18-26.28-25.62 36.32-5.28z" fill="#13FF00"/>
<circle cx="310" cy="50" r="50" fill="#2732FF"/>
</svg>
Using following html worked in Chrome, Firefox and IE11:
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>SVG Fragment</title>
<style type="text/css">
body {
background: url("tiletest.svg#svgView(viewBox(120,32,30,32))");
background-size: 30px 32px;
}
</style>
</head>
<body>
<h1>SVG Fragment</h1>
</body>
</html>
</update>
A couple of things, support for inline viewbox is not there in all browsers yet ... and often has quirks (see links at bottom) ... the other is that the viewbox is x-min y-min width height ... you appear to have thought it is x1 y1 x2 y2.
You should have used background: url("tiletest.svg#svgView(viewBox(120 32 30 32))"); for it to work in Chrome ... though you may need to use a view element to get it working in Firefox.
I've shown another way to implement what you want below which will work in all modern browsers (except Opera Mini and a few others). Hope it gives you some ideas.
.svg-background {
height: 200px;
background-image: url("data:image/svg+xml;charset=UTF-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='120 32 30 32'%3E%3ClinearGradient id='grad' x2='100' y2='100' gradientUnits='userSpaceOnUse'%3E%3Cstop offset='0' stop-color='%23E7FF00'/%3E%3Cstop offset='1' stop-color='%23F00'/%3E%3C/linearGradient%3E%3Cpath d='M0 0h100v100H0z' fill='url(%23grad)'/%3E%3Cpath d='M174.68 0l16.24 32.92 36.33 5.28-26.29 25.62 6.21 36.18-32.49-17.08L142.19 100l6.2-36.18-26.28-25.62 36.32-5.28z' fill='%2313FF00'/%3E%3Ccircle cx='310' cy='50' r='50' fill='%232732FF'/%3E%3C/svg%3E");
}
<svg xmlns="http://www.w3.org/2000/svg" width="100" viewBox="0 0 360 100">
<linearGradient id="grad" x2="100" y2="100" gradientUnits="userSpaceOnUse">
<stop offset="0" stop-color="#E7FF00"/>
<stop offset="1" stop-color="#F00"/>
</linearGradient>
<path d="M0 0h100v100H0z" fill="url(#grad)"/>
<path d="M174.68 0l16.24 32.92 36.33 5.28-26.29 25.62 6.21 36.18-32.49-17.08L142.19 100l6.2-36.18-26.28-25.62 36.32-5.28z" fill="#13FF00"/>
<circle cx="310" cy="50" r="50" fill="#2732FF"/>
</svg>
<div class="svg-background">
</div>
Further Reading:
Mozilla Developer Network (MDN) Viewbox page
CanIUse.com svg fragment identifiers
Also check out the SVG view element which I have not looked into yet.
Definitely check out the page on CSSTricks about fragment identifers
and the fragment identifier testbed codepen
I found this SVG code, and I was wondering how do I apply it to a background image?
<svg width="600px" height="600px" viewbox="0 0 600 600">
<defs>
<linearGradient id="alphaLinear">
<stop offset="0%" stop-color="#FFFFFF" stop-opacity="0%" />
<stop offset="100%" stop-color="#FFFFFF" stop-opacity="100%" />
</linearGradient>
<mask id="Mask">
<rect x="0" y="0" width="600" height="600" fill="url(#alphaLinear)" />
</mask>
</defs>
<image xlink:href="/media/images/body-bg.jpg" width="600" height="600" x="0" y="0" preserveAspectRatio="xMinYMin meet" mask="url(#Mask)"/>
</svg>
In the <image> tag I replaced the href url with the image I want to use. I then call the svg from the css like so:
body{
background: url('/media/images/gradient.svg') center top no-repeat;
}
Nothing seems to be happening, all I am getting is a white background.
There are a few things wrong:
For external files, you will need the xmlns and xmlns:xlink namespace declarations in the <svg> tag.
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"
width="600px" height="600px" viewbox="0 0 600 600">
viewbox should be viewBox
SVG files used as an external image in <img> or as a background-image need to be self contained. They cannot refer to other external files as you are doing here.
You can embed the external JPEG as a Data URI though if you want.
<image xlink:href="data:image/jpeg;base64,...Base64 encoded JPEG data here...">