Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

css svg and vector-effect="non-scaling-stroke" browser compatibility

Tags:

css

svg

From various sources I gather that vector-effect="non-scaling-stroke" in svg should work in the current versions Opera, Firefox and Chrome. (Not sure about IE10).

However I can only make it work in Opera and Firefox, and then only when it is directly embedded as an image, if it is scaled as a background image in CSS then it doesn't work.

My questions:

Why not chrome?

Why not in background images?

Is there a standard way I can use this in all latest browsers?

A fiddle example.

HTML :

<div><img src="http://dl.dropbox.com/u/60476509/close.svg" /></div>
<div><img id="one" src="http://dl.dropbox.com/u/60476509/close.svg" /></div>
<div id="two"></div>
<div id="three"></div>

CSS :

#one {
    width: 200px;
    height: 200px;
}

#two {
    background-image: url("http://dl.dropbox.com/u/60476509/close.svg");
    height: 100px;   /* native size */
    width: 100px;
    background-size: contain;        
}
#three {
    background-image: url("http://dl.dropbox.com/u/60476509/close.svg");
    height: 200px;
    width: 200px;
    background-size: cover;        
}    
like image 814
SystemicPlural Avatar asked Mar 29 '13 12:03

SystemicPlural


People also ask

Can I use vector effect non scaling stroke?

To get non-scaling-stroke to actually work, you must apply the "vector-effect" attribute directly on the element in question. You can otherwise style it like normal.

What is the effect of a vector?

The vector-effect property specifies the vector effect to use when drawing an object. Vector effects are applied before any of the other compositing operations, i.e. filters, masks and clips. Note: As a presentation attribute, vector-effect can be used as a CSS property.


1 Answers

I have no idea what's going on under the hood, but there is an easier solution, at least for inline SVG's (not sure about backgrounds). Change:

<img src="svg-source.svg"/>

to:

<object type="image/svg+xml" data="svg-source.svg"></object>

In addition, you need to make sure you have viewBox defined for the svg document.

According to this answer, using object is better practice anyway. Here is a decent blog post that recommends (for cross-browser compatibility):

<object type="image/svg+xml" data="svg-source.svg">
    <img src="png-version.png"/>
</object>

I have not tested this latter option, but if it works it is much simpler than this solution.

EDIT: I discovered that as embedded objects, SVGs were interfering with "hover" and "click" events, so I finally buckled and decided that I must embed SVGs fully. But I had no interest in pasting every single one, so I have the following at the top of my javascript file (I'm using JQuery):

$(document).ready(function()
{
    $('.deferred-load').deferredLoad();
}
$.fn.deferredLoad = function()
{
    $(this).each(function()
    {
        $(this).load($(this).attr('data-load'));
    });
}

Now instead of <img src="svg.svg"/> I can write <div class="deferred-load" data-load="svg.svg"></div>.

Of course, this doesn't work without Javascript enabled. But it's way better than pasting all that ugly XML.

like image 66
galdre Avatar answered Oct 22 '22 15:10

galdre