Images clipped using SVG paths are reversed in Chrome - html

I am having issues with an SVG clipping mask that's applied to an image. This works correctly in Firefox, but in Chrome and IE the clipping mask works in reverse (not had a chance to try other browsers yet).
Here's what I mean-
Firefox
Chrome/IE
<svg height="0" width="0" >
<defs>
<clipPath id="clipPath" stroke="white" stroke-width="10">
<path d="M252.294,0.26l-203.586,0c0,0-47.43,1.586-48.207,38.876c0.777,37.29,48.207,38.877,48.207,38.877h203.586
c0,0,47.43-1.587,48.207-38.877C299.724,1.847,252.294,0.26,252.294,0.26z"/>
</clipPath>
</defs>
<div id='board_img_1' class='board_imgs'>
<img src="./images/board1.png" style=" clip-path: url(#clipPath);
width: 100%;
height: 100%;"></div>
<div id='board_img_2' class='board_imgs'>
<img src="./images/board2.png" style=" clip-path: url(#clipPath);
width: 100%;
height: 100%;"></div>
</svg>
Here's my HTML. I'm not sure where to begin even trying to fix this and it seems like a fairly specific issue.

As Michael Mullany suggested, try changing img to image and changing your div tags.
http://www.w3schools.com/svg/svg_reference.asp
Here is a page that might help with regards to what you can/can not use.
There is also some examples of how to use SVG here:
http://www.w3schools.com/svg/svg_examples.asp
Lastly, check out this link for browser support for SVG and its various uses:
http://caniuse.com/#cats=SVG

Related

is there a way to reference svg from page in the css?

I see that you can reference the svg by id in some css/svg properties, as in:
<!-- the logo svg -->
<svg id="rect-container" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<!-- left squares -->
<rect fill="url(#rect-fill)"/>
</svg>
does anyone know if we can use a svg from the page, in a css bg for example? to avoid encoding it on the css.
Something like this, which I already tried but did not seem to work the same way.
.myel {
background-image: url(#rect-svg-image);
}
First, there is a misconception to clear up.
fill: url(#source);
does not reference arbitrary SVG content, but a paint server, namely a gradient or pattern. Other uses of the CSS url() notation in SVG include the clip-path, mask and marker-start|mid|end properties that all also can only reference specific elements.
Currently, background-image needs an actual self-contained image resource or a CSS gradient. Referencing a SVG paint server with url() does not work.
But the CSS Images Module Level 4 also defines a element() functional notation that can reference fragments inside the page.
If you look at the text of the specification, there are still a lot of open questions listed to solve before this can become mainstream. There currently is only a Firefox implementation with vendor prefix, -moz-element(). You can point it to paint servers; that means you can (mis)use a <pattern> element. Although experimenting, I found there are some tradeoffs to make:
patternContentUnits="objectBoundingBox" needs all content drawn into a 1px*1px square, but makes the content scalable. Preserving the aspect ratio is not supported.
patternContentUnits="userSpaceOnUse" gives you preservation of the aspect ratio, but scaling is not supported.
svg {
display: block;
width: 0;
height: 0;
}
div {
width: 200px;
height: 150px;
border: 1px solid black;
background-image: -moz-element(#image);
background-size: cover;
}
<svg>
<pattern patternContentUnits="objectBoundingBox"
preserveAspectRatio="xMidYMid meet"
width="100%" height="100%" id="image">
<rect width=".5" height=".5" fill="red"/>
<rect width=".5" height=".5" x=".5" fill="yellow"/>
<rect width=".5" height=".5" y=".5" fill="green"/>
<rect width=".5" height=".5" x=".5" y=".5" fill="blue"/>
<circle r=".5" cx=".5" cy=".5" fill="white" opacity=".5"/>
</pattern>
</svg>
<div>

Problem rendering SVGs on safari with html5

I'll admit right off the bat i'm very new to SVG graphics in html. That said i'm attempting to upgrade my site images to SVG's where appropriate.
I started with this code:
<svg class="logo">
<image
class="logo"
xlink:href="https://cdn.badmonsterarts.com/main_logo.svg"
src="https://cdn.badmonsterarts.com/main_logo.png"
/>
</svg>
Which works fine in chrome and firefox, however when tested on Safari(Both mobile and desktop) it rendered as a blank rectangle. That said I did some research and tried some stack overflow answers which brings us to my current code:
<svg
class="logo"
viewBox="0 0 256 75"
xmlns="http://www.w3.org/2000/svg"
role="img"
>
<image
class="logo"
xlink:href="https://cdn.badmonsterarts.com/main_logo.svg"
src="https://cdn.badmonsterarts.com/main_logo.png"
/>
</svg>
The problem however is this still works in chrome and firefox, but I still can't get it to render in Safari.
Here's the CSS i'm using to size it, logo wrapper is a div surrounding the SVG as a warpper:
.logo-wrapper {
width: 256px;
height: 75px;
overflow: hidden;
.logo {
width: auto;
height: 100%;
}
}
I've also tried using <use ... /> instead of <image ... /> with no luck either, when I used <use ... /> it didn't even render in chrome. I'm hoping one of your brilliant minds can lead me in the right direction and save my sanity.
If it helps anyone debug this, there's a link to the site that the SVG is being used on(The logo in the top left on the nav bar).
https://www.badmonsterarts.com/
Thanks!
If you set the image width and height to 100% of the viewBox it ought to work (I took the viewBox values from the external SVG).
By only setting the viewBox you make the SVG responsive – why you can leave out the logo class
.logo-wrapper {
width: 256px;
height: 75px;
overflow: hidden;
}
<div class="logo-wrapper">
<svg viewBox="0 0 679 200">
<image width="100%" height="100%" xlink:href="https://cdn.badmonsterarts.com/main_logo.svg" />
</svg>
</div>

Why is my SVG showing in Chrome, but not in other browsers?

I am trying to show an SVG with a bit of CSS in browsers like Edge and Firefox. In Chrome it is working as expected, but not in any other browsers. I have singled out the problem in the CodePen below. Don't mind the messy styling (in the original version there is a different font etc).
The problem is that the SVG is simply not shown at all in other browsers. When I inspect the element it does show the code needed, but nothing is there on the front-end. I am not very experienced with SVG.
I have tried: Adding a viewbox (though I am not sure if I did this correctly) and changing the size of the box around it. Neither did help.
CodePen
svg {
font-size: 260px;
}
.colortext .anim-shape:nth-child(1) {
fill: white;
}
.colortext .anim-shape:nth-child(2) {
fill: #19b5b3;
}
section.portfolio-page {
background-color: #252627;
min-height: calc(100vh - 120px)
}
<section class="portfolio-page">
<svg>
<!-- Clippath with text -->
<clipPath id="cp-text">
<text text-anchor="middle" x="50%" y="30%" dy=".38em" class="text--line">
RT
</text>
</clipPath>
<!-- Group with clippath for text-->
<g clip-path="url(#cp-text)" class="colortext">
<!-- Animated shapes inside text -->
<rect width="100%" class="anim-shape"></rect>
<rect width="23%" class="anim-shape blue-logo"></rect>
</g>
</svg>
</section>

Why doesn't my SVG data URL inside HTML inside an SVG data url show in Chrome?

Background
I have an SVG data URL as a background-image property of an HTML element inside a <foreignObject> inside an SVG data URL which serves as the source of an <img> element.
Problem
In Google Chrome, that inner SVG is not rendered at all; while if this whole business wasn't inside an image, it would have rendered. How can I solve this?
Wait, what? Why?
A why will be below, but first I want to complete the question by adding a tree structure and a code sample, to clarify the above convoluted paragraph.
Tree:
<img src="data:image/svg+xml;utf8, (exhibit A)
<svg> (exhibit B)
<foreignObject>
<html>
<div style="background: url('data:image/svg+xml;utf8,
<svg> (exhibit C)
Exhibit C is not rendered at all, as if it's not there. If I cut exhibit A out, though, so that exhibit B is the top-level element, then exhibit C is rendered fine.
Small code sample:
<div>Standalone:</div>
<svg xmlns="http://www.w3.org/2000/svg" width="75" height="50" style="position:relative"><circle cx="25" cy="25" r="25" fill="red" /><foreignObject style="width: 100%; height: 100%"><html xmlns="http://www.w3.org/1999/xhtml"><style>.x {position: absolute;background: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='100' height='50'><circle cx='50' cy='25' r='25' fill='blue'/></svg>"); width: 100%; height: 100%;}</style><div class="x"></div></html></foreignObject></svg>
<div>As image source:</div>
<img style="position:relative" src='data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="75" height="50" style="position:relative"><circle cx="25" cy="25" r="25" fill="red" /><foreignObject style="width: 100%; height: 100%"><html xmlns="http://www.w3.org/1999/xhtml"><style>.x {position: absolute;background: url("data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="100" height="50"><circle cx="50" cy="25" r="25" fill="blue"/></svg>"); width: 100%; height: 100%;}</style><div class="x"></div></html></foreignObject></svg>'>
One final note: using a PNG data URL instead of an SVG data URL works well; it's when using SVG when this becomes broken.
Why?
Placing HTML inside an <img> allows that HTML to be rendered on a canvas by context.drawImage - and I follow that up by canvas.toDataURL in order to generate an image from the HTML, which is my ultimate goal. This is a terrible though standard approach, also employed by widely-used libraries such as https://github.com/tsayen/dom-to-image.
My HTML comes with its own embedded SVG, though, which creates the problem mentioned in the question. Until now I bypassed this by first repeating this flow for the innermost SVG data URLs, replacing them with PNG data URLs, and only then rendering the top-level HTML element. But now I want to add scaling to the mix, which greatly complicates things, since those PNGs won't scale smoothly and I can't scale first because then the images will be too big for their elements.
(well it works okay with background-image which scales, but not with clip-path which doesn't scale and I'm also converting).
Other browsers
IE and Edge do not support HTML inside <foreignObject>, so this is irrelevant for them.
Firefox does support it but for some reason its "standalone" version doesn't work either - which I would also like to solve but it might belong in a separate question.
Related but not duplicates:
Append foreignObject containing some HTML inside an SVG element - is about a missing namespace declaration.
img Inside a foreignObject Inside an svg Inside an img - is about external images, not data URLs.
You need to encode special characters, I don't know exactly which one was the culprit, but when using encodeURIComponent on the whole <CSSImage url>, then encoding again the whole markup to pass it in the <img>, everything works fine in Chrome.
<div>Standalone:</div>
<svg xmlns="http://www.w3.org/2000/svg" width="75" height="50" style="position:relative"><circle cx="25" cy="25" r="25" fill="red" /><foreignObject style="width: 100%; height: 100%"><html xmlns="http://www.w3.org/1999/xhtml"><style>.x {position: absolute;background: url("data:image/svg+xml;utf8,%3Csvg%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20width%3D'100'%20height%3D'50'%3E%3Ccircle%20cx%3D'50'%20cy%3D'25'%20r%3D'25'%20fill%3D'blue'%2F%3E%3C%2Fsvg%3E"); width: 100%; height: 100%;}</style><div class="x"></div></html></foreignObject></svg>
<div>As image source:</div>
<img style="position:relative" src="data:image/svg+xml;utf8,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%2275%22%20height%3D%2250%22%20style%3D%22position%3Arelative%22%3E%3Ccircle%20cx%3D%2225%22%20cy%3D%2225%22%20r%3D%2225%22%20fill%3D%22red%22%20%2F%3E%3CforeignObject%20style%3D%22width%3A%20100%25%3B%20height%3A%20100%25%22%3E%3Chtml%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F1999%2Fxhtml%22%3E%3Cstyle%3E.x%20%7Bposition%3A%20absolute%3Bbackground%3A%20url(%22data%3Aimage%2Fsvg%2Bxml%3Butf8%2C%253Csvg%2520xmlns%253D'http%253A%252F%252Fwww.w3.org%252F2000%252Fsvg'%2520width%253D'100'%2520height%253D'50'%253E%253Ccircle%2520cx%253D'50'%2520cy%253D'25'%2520r%253D'25'%2520fill%253D'blue'%252F%253E%253C%252Fsvg%253E%22)%3B%20width%3A%20100%25%3B%20height%3A%20100%25%3B%7D%3C%2Fstyle%3E%3Cdiv%20class%3D%22x%22%3E%3C%2Fdiv%3E%3C%2Fhtml%3E%3C%2FforeignObject%3E%3C%2Fsvg%3E">
Also note that <foreingObject>'s width and height attributes are mandatory in SVG1.1, and thus, omitting them will work only in Chrome.
So for other browsers that still have to implement this new feature
<div>Standalone:</div>
<svg xmlns="http://www.w3.org/2000/svg" width="75" height="50" style="position:relative"><circle cx="25" cy="25" r="25" fill="red" /><foreignObject width="100%" height="100%"><html xmlns="http://www.w3.org/1999/xhtml"><style>.x {position: absolute;background: url("data:image/svg+xml;utf8,%3Csvg%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20width%3D'100'%20height%3D'50'%3E%3Ccircle%20cx%3D'50'%20cy%3D'25'%20r%3D'25'%20fill%3D'blue'%2F%3E%3C%2Fsvg%3E"); width: 100%; height: 100%;}</style><div class="x"></div></html></foreignObject></svg>
<div>As image source:</div>
<img style="position:relative" src="data:image/svg+xml;utf8,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%2275%22%20height%3D%2250%22%20style%3D%22position%3Arelative%22%3E%3Ccircle%20cx%3D%2225%22%20cy%3D%2225%22%20r%3D%2225%22%20fill%3D%22red%22%20%2F%3E%3CforeignObject%20width%3D%22100%%22%20height%3D%22100%%22%3E%3Chtml%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F1999%2Fxhtml%22%3E%3Cstyle%3E.x%20%7Bposition%3A%20absolute%3Bbackground%3A%20url(%22data%3Aimage%2Fsvg%2Bxml%3Butf8%2C%253Csvg%2520xmlns%253D'http%253A%252F%252Fwww.w3.org%252F2000%252Fsvg'%2520width%253D'100'%2520height%253D'50'%253E%253Ccircle%2520cx%253D'50'%2520cy%253D'25'%2520r%253D'25'%2520fill%253D'blue'%252F%253E%253C%252Fsvg%253E%22)%3B%20width%3A%20100%25%3B%20height%3A%20100%25%3B%7D%3C%2Fstyle%3E%3Cdiv%20class%3D%22x%22%3E%3C%2Fdiv%3E%3C%2Fhtml%3E%3C%2FforeignObject%3E%3C%2Fsvg%3E">

SVG scaled differently on different browsers

I need to have my svg within div's as follows:
<div style="height:100px; width: 300px; border:1px solid red;" >
<div style="width: 100%; height: 100%; display: table;">
<div style="display:table-row; height:100%">
<div style="position: relative; vertical-align: middle; height:100%;">
<div style="vertical-align: middle; position: relative; margin: 0px auto; height:100%;">
<svg viewBox="0 0 485 255" id="damageCanvas" style="vertical-align: middle;" xmlns="http://www.w3.org/2000/svg" xlink="http://www.w3.org/1999/xlink" version="1.1" fill="rgba(124,240,10,0.5)" height="100%" width="100%">
<g transform="translate(1,1)">
<rect stroke="black" stroke-width="1.5" width="99.5%" height="99.5%" fill-opacity="0" style="padding: 2px 2px 2px 2px"></rect>
</g>
</svg>
</div>
</div>
</div>
</div>
</div>
The problem is that the following SVG is rendered in different browsers in different ways.
Chrome:
Firefox:
IE 9:
I want the image to be scaled as in chrome version. How can i achieve this?
Fiddle: http://jsfiddle.net/Sq5bL/5/
You can save your SVG in a file and use it as a resource, via <img> or <embed>. I've used both and it scales nicely. <img> stops you from accessing the SVG, so if you need access to the SVG then I would recommend using <embed>.
In my case I did:
<embed id="gaugeSpeed" class="gaugeImage" width="200" height="200" type="image/svg+xml" src="assets/gauges/speed.svg">
and it scaled it nicely. Same for when I use SVG with the <img> tag. I've tested on Transformer Prime and Nexus 7 running both ICS and Jellybean, works fine.
Should work fine with your parent div as well, as it's just treated like a normal img or object.
Well, since you would like to keep your SVG... your problem is caused by the use of the
display: table
on the second div. If you change that to a table-cell or remove it then your problem is resolved.
This is a JSFiddle that shows it working with table-cell