We are trying to display SVG backgrounds in internet explorer. Our images are always getting cut off when a zoom other than 100% is used. This can be reproduced using the following code:
with this svg
<svg xmlns="http://www.w3.org/2000/svg" height="100" width="100" viewBox="0 0 100 100">
<circle cx="50" cy="50" r="48" stroke="black" stroke-width="3" fill="red" />
</svg>
div {
width: 14px;
height: 14px;
background-size: 14px 14px;
background-repeat: no-repeat;
background-image: url("data:image/svg+xml;charset=utf-8,%3C%3Fxml version='1.0' encoding='UTF-8'%3F%3E%3Csvg xmlns='http://www.w3.org/2000/svg' height='100' width='100' viewBox='0 0 100 100'%3E%3Ccircle cx='50' cy='50' r='48' stroke='black' stroke-width='3' fill='red'%3E%3C/circle%3E%3C/svg%3E");
}
<div></div>
The result looks like this:
In all other browsers it renders fine. Has anyone else ever experienced this bug? Is there a workaround?
I have found one workaround which requires very little work:
Make the SVG image 2X size of the actual content (this would make the circle look like this:
<svg xmlns="http://www.w3.org/2000/svg" height="200" width="200" viewBox="0 0 200 200">
<circle cx="50" cy="50" r="48" stroke="black" stroke-width="3" fill="red" />
</svg>
Then use the :after pseudo element to create an inside element with 2x the desired size. So the html would be
<div class="circle"></div>
And the css would be
.circle {
width: 14px;
height: 14px;
position:relative;
}
.circle:after {
position: absolute;
top: 0;
left: 0;
content: ' ';
width: 28px;
height: 28px;
background-size: 28px 28px;
background-repeat: no-repeat;
background-image: url('circle.svg');
}
The extra space in the :after pseoudoelement gives IE spare canvas to draw on, but both the visible icon and the space occupied by the original container remain the same.
Related
I'm displaying SVGs in <img> tags. With viewBox these images could be scaled without losing clarity. However, when I copy these images (and paste them into PowerPoint, etc.), they won't be as clear as they are displayed.
How could I make copied images clear? And could this be done without using a canvas?
Example SVG markup:
<svg id="mol-638318-0540814976"
xmlns="http://www.w3.org/2000/svg" width="84" height="40" viewBox="0 0 84 40">
<style>
#mol-638318-0540814976 text {
dominant-baseline: central;
text-anchor: middle;
font-size: 16px;
font-family: serif;
fill: black;
}
#mol-638318-0540814976 line {
stroke: black;
}
</style>
<text x="26" y="20">C</text>
<text x="58" y="20">C</text>
<line x1="32" y1="20" x2="52" y2="20"></line>
</svg>
Thanks!
Is there a way to stop this outline in firefox?
#blob { background: red; width: 500px; height: 500px; clip-path: url(#myClip); transform: rotate(20deg);}
<div id="blob"></div>
<svg>
<defs>
<path d="M320.403196,424.677624 C426.787532,365.585154 447.310044,306.188587 433.45394,197.28033 C419.597836,88.3720737 316.997962,53.8862578 227.347416,40.9086547 C144.650118,28.9375873 104.472702,88.6407456 69.862267,131.812053 C15.52584,199.588564 48.3439099,300.905451 80.8563197,361.757908 C110.80391,417.809872 214.018859,483.770094 320.403196,424.677624 Z" id="path-1"></path>
<clipPath id="myClip"><use href="#path-1"></use></clipPath>
</defs>
</svg>
This renders correctly in other browsers, just need some work around for this firefox bug
same outline appears using either clip-path or mask
As a workaround you could rotate the clipPath instead:
#blob {
background: red;
width: 500px;
height: 500px;
clip-path: url(#myClip);
}
<div id="blob"></div>
<svg viewBox="0 0 397 409">
<defs>
<path d="M320.403196,424.677624 C426.787532,365.585154 447.310044,306.188587 433.45394,197.28033 C419.597836,88.3720737 316.997962,53.8862578 227.347416,40.9086547 C144.650118,28.9375873 104.472702,88.6407456 69.862267,131.812053 C15.52584,199.588564 48.3439099,300.905451 80.8563197,361.757908 C110.80391,417.809872 214.018859,483.770094 320.403196,424.677624 Z" id="path-1" />
<clipPath id="myClip" transform="rotate(20)" transform-origin="center">
<use href="#path-1"></use>
</clipPath>
</defs>
</svg>
I am not aware of alternatives to adding width: 1em to the SVG in order to fix the IE11 issue (please see comment in the code). Play with the code in the codepen. Appreciate any help! Thanks :)
https://codepen.io/ambrwlsn90/pen/zjZYpb
<div class="box">
<span class="handle--draggable">
<svg class="handle--icon" xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 10 32">
<circle cx="2" cy="2" r="2" />
<circle cx="8" cy="2" r="2" />
<circle cx="2" cy="9" r="2" />
<circle cx="8" cy="9" r="2" />
<circle cx="2" cy="16" r="2" />
<circle cx="8" cy="16" r="2" />
<circle cx="2" cy="23" r="2" />
<circle cx="8" cy="23" r="2" />
<circle cx="2" cy="30" r="2" />
<circle cx="8" cy="30" r="2" />
</svg>
</span>
</div>
.box {
position: relative;
width: 400px;
height: 100px;
border: 3px solid black;
background-color: white;
top: 50px;
left: 100px;
padding: 15px;
line-height: 1.5em;
}
.handle--draggable {
position: absolute;
cursor: move;
left: -26px;
top: -3.5px;
}
/**
* 1. Magic number added to fix visual bug in IE: 11
*/
.handle--icon {
fill: black;
background-color: grey;
padding: 3.5px;
height: 37px;
width: 1em; /* 1. */
position: relative;
&:hover {
left: -5px;
border-right: 5px solid grey;
}
}
The SVG tag needs some basic attributes in order to be rendered as expected. If you read the W3C documentation according the outermost svg tag you will find the answer:
For embedded ‘svg’ elements, the width of the rectangular region into which the ‘svg’ element is placed.
A negative value is an error (see Error processing). A value of zero disables rendering of the element.
If the attribute is not specified, the effect is as if a value of '100%' were specified.
So you will need to specify the width and height attributes of the SVG tag, or it will be rendered at 100% width.
The opening svg tag should look like this:
<svg class="handle--icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 10 32" width=“10” height=“32”>
Then the SVG will look the same crossbrowser.
Having the width and height attributes defined on your svg element you can discard the ugly Internet Explorer 11 hack.
I'm attempting to create a donut chart using SVG, and am running into a problem when viewing it in Safari. Here's a fiddle that shows the issue; I'll describe it in detail below:
https://jsfiddle.net/nijhazer/phy2ossh/
This fiddle shows a graphic comprised of two circles overlaid atop one another. The problem becomes apparent when a Safari user increases zoom size in her browser:
Relevant HTML from the example:
<div class="donut-chart">
<svg width="200" height="200">
<circle class="backdrop" cx="100" cy="100" r="65" fill="#d5d8d5" stroke="none" stroke-width="0"></circle>
<circle class="progress" cx="100" cy="100" r="75" fill="none" stroke="lightgreen" stroke-width="20" style="stroke-dashoffset: 353.428875px;"></circle>
<circle class="outer-ring" cx="100" cy="100" r="85" fill="none" stroke="#d5d8d5" stroke-width="1"></circle>
</svg>
</div>
Relevant CSS from the example:
body {
background-color: white;
}
.donut-chart {
width: 200px;
height: 200px;
position: relative;
}
svg {
width: 200px;
height: 200px;
}
.progress {
stroke-dasharray: 471.24;
transform: rotate(-90deg);
transform-origin: 50% 50%;
background-color: transparent;
}
I don't know if this helps, but at I can read from the comments that people are blaming the CSS property transform-origin. In this example I moved the styling to attributes on the circle element. I also added pathLength to make it easier to control the progress bar.
body {
background-color: white;
}
.donut-chart {
width: 200px;
height: 200px;
position: relative;
}
svg {
width: 200px;
height: 200px;
}
<div class="donut-chart">
<svg viewBox="0 0 200 200" xmlns="http//www.w3.org/2000/svg">
<circle class="backdrop" cx="100" cy="100" r="65" fill="#d5d8d5"
stroke="none" stroke-width="0" />
<circle class="progress" cx="100" cy="100" r="75" fill="none"
stroke="lightgreen" stroke-width="20" stroke-dasharray="25 100"
transform="rotate(-90 100 100)" pathLength="100" />
<circle class="outer-ring" cx="100" cy="100" r="85" fill="none"
stroke="#d5d8d5" stroke-width="1" />
</svg>
</div>
I can confirm chrwahl's approach is working (at least in MacOS/IOS safari versions (15.4) I've tested - Unfortunately, the support of functions may vary from version to version)
Another workaround could be to add a translateX offset before rotating like so:
.donut-chart {
width: 200px;
height: 200px;
position: relative;
display: block;
}
svg {
width: 200px;
height: 200px;
}
.progress {
stroke-dasharray: 471.24;
background-color: transparent;
transform: translate(0px, 200px) rotate(-90deg);
}
<div class="donut-chart">
<svg width="200" height="200" viewBox="0 0 200 200">
<circle class="backdrop" cx="50%" cy="50%" r="65" fill="#d5d8d5" stroke="none" stroke-width="0"></circle>
<circle class="progress" cx="50%" cy="50%" r="75" fill="none" stroke="lightgreen" stroke-width="20" style="stroke-dashoffset: 353.428875px;"></circle>
<circle class="outer-ring" cx="100" cy="100" r="85" fill="none" stroke="#d5d8d5" stroke-width="1"></circle>
</svg>
</div>
This "hack" won't work combined with transform-origin: 50% 50%
I want to use a spotlight effect but it only seems to work in Chrome, looks "just ok" in Firefox, but will not position (x,y,z) in Safari. (Other browsers not tested)
I've tried different filter and primitive units, and while this makes a difference, Safari still cannot seem to position the lighting effect in any case.
In pursuit of understanding what is going on, I've tried lots of workarounds including different userSpaceOnUse/objectBoundingBox combos, and different svg structure but have never been able to find one that works on Safari.
Examples
Default filter/primitive units:
https://jsfiddle.net/localnerve/y470d52v/
objectBoundingBox units:
https://jsfiddle.net/localnerve/uyc7o52k/
A picture is also worth a 1000 words (Safari, Chrome, FF). The spotlight on Safari is rendered off-canvas to the right and bleeds in from the right.
To show the spotlight positions on Safari are "out of whack", here's me nudging them in web inspector so I can see the spotlight render at all:
Here is the code using objectBoundingBox filter and primitive units:
<style>
body {
margin: 0;
padding: 0;
font-family: sans-serif;
font-size: 16px;
color: #fff;
}
* {
transform-origin: 50% 50% 0;
}
.scene-container {
display: flex;
flex-flow: column nowrap;
justify-content: center;
align-items: center;
}
.scene-container.content {
position: relative;
width: 100%;
height: 150vh;
background-image: linear-gradient(hsla(240, 90%, 8%, 1) 0%, 99%, hsla(217,24%,71%,0) 100%);
box-shadow: 0px -10px 20px hsl(240, 90%, 8%);
}
.spot {
height: 100%;
width: 100%;
}
</style>
<body>
<div class="scene-container content">
<h2>Here's a spotlight.</h2>
<svg class="spot" viewBox="0 0 2000 3000" preserveAspectRatio="xMidYMid">
<defs>
<filter x="-0.2" y="-0.2" width="1.4" height="1.4" filterUnits="objectBoundingBox" primitiveUnits="objectBoundingBox" id="spotlight">
<feGaussianBlur in="SourceAlpha" stdDeviation="8" result="blur1"></feGaussianBlur>
<feSpecularLighting result="specOut" in="blur1" specularConstant="1.8" specularExponent="5" lighting-color="#ffffff">
<feSpotLight x="0.5" y="-0.4" z="0.03" pointsAtX="0.5" pointsAtY="0.8" pointsAtZ="0" limitingConeAngle="13.7"></feSpotLight>
</feSpecularLighting>
<feComposite in="SourceGraphic" in2="specOut" operator="arithmetic" k1="0" k2="1" k3="1" k4="0"></feComposite>
</filter>
<clipPath id="spot-clip">
<rect x="-50" y="2840" width="2200" height="200"></rect>
</clipPath>
<filter id="spot-blur">
<feGaussianBlur in="SourceGraphic" stdDeviation="15">
</feGaussianBlur>
</filter>
</defs>
<g transform="translate(0, -175)" filter="url(#spotlight)">
<ellipse cx="50%" cy="95.333%" rx="27%" ry="130" fill="#fff" clip-path="url(#spot-clip)" filter="url(#spot-blur)"></ellipse>
<rect x="25%" y="43.667%" width="50%" height="50%" stroke="peru" stroke-width="3%" stroke-linejoin="round" fill="#000"></rect>
</g>
</svg>
</div>
</body>
Any insight you can give is greatly appreciated.
There are known bugs in webkit/Safari for light source positioning wrt transforms and oBB units. After the webkit/blink engine schism, no-one at Apple picked these bugs up from the Chrome team.
https://bugs.webkit.org/show_bug.cgi?id=88877
https://bugs.webkit.org/show_bug.cgi?id=113059
The workaround is not to use transforms and oBB units (do any dynamic positioning or sizing via JavaScript)