0

After reading several stack posts about WHY you might want to use an <img> or <object> tag to reference a svg file, I've yet to find one that answers a specific question i have with regards to CSS and svg <path> tags. If you embed the svg into the js or html, you can manage all hover events for example, in the CSS rules

A CSS rule like so if i wanted to have a hover effect on a svg map of buildings.

path[id^="building"]:hover {
    opacity: 0.5;
}

But if the svg file is very large (200kb), full of path vectors, and you want instead reverence the svg instead (see below samples), then you will break the above CSS rule. All paths with id beginning with "building" will stop showing the hover effect of .5 opacity.

<object type="image/svg+xml" data="http://localhost:49031/my.svg" `width="300" height="300"></object>`'

Or

<img id="map" src="http://localhost:49031/my.svg"></img>

I cant seem to wrap my head around a way to access the paths inside a reference svg file. I've started reading on <use> and <g> svg tags, but i have not come across the missing link that pulls this all together for me.

IMPORTANT NOTE: I realize you can specify <style> tags inside each svg, but i would rather not manage my code this way if there is a better option, which I'm sure there is. These svgs will be used as a svg map, with clickable hotspots that trigger maps in and out of view so individual buildings, or rooms on a floor plan can be selected, and write the objects id to a form field.

Paul LeBeau
  • 97,474
  • 9
  • 154
  • 181
Dogbyte
  • 99
  • 2
  • 10
  • These are a few of the questions that i was referencing: http://stackoverflow.com/questions/12583879/linking-to-css-in-an-svg-embedded-by-an-img-tag http://stackoverflow.com/questions/18434094/how-to-style-svg-with-external-css – Dogbyte Jul 16 '15 at 15:53
  • And I suspect that if you check over most of those questions the answer comes back..."You can't" reference sub-elements in linked SVGs with CSS...*yet*. There are several workarounds mentioned there but perhaps they don't scale in your case. – Paulie_D Jul 16 '15 at 16:07
  • @Paulie_D Yes you are right, like i said im hoping there is an option that i havent seen yet, that does lend itself to conventional CSS styling functionality. I may just have to style each svg individually and manage it accordingly. – Dogbyte Jul 16 '15 at 16:21
  • Could you pop the svg example on a fiddle that doesn't work ? – Ian Jul 16 '15 at 19:02
  • Well since fiddle doesnt let you reference local files, i'd have to embed the svg inside the js or html, in which case the css will work perfectly since it can access the sub elements. Im not sure if i have access to a img hosting site that takes svg's either, so same jsFiddle issue, unless im mistaken about javascript/browsers use of local files being a no no. – Dogbyte Jul 16 '15 at 20:16
  • Just a link to the svg would probably be enough along with the test case code (ie that one could copy to their own server to test). – Ian Jul 16 '15 at 21:37
  • There is a great jquery hack that will convert your uploaded svg with inline svg: http://stackoverflow.com/questions/11978995/how-to-change-color-of-svg-image-using-css-jquery-svg-image-replacement. Try with this. Then you'll have explicit `svg` + `path`. – dingo_d Jul 17 '15 at 06:14

2 Answers2

0

Faced this reflexion before, img/svg file referenced with url is not "really" in the dom and is not "source editable"

Did not find any working solution using css. So, to "trick" this, I used javascript/jquery. Since referenced files are not "really" editable in the dom, I used ajax to insert them. This way, the svg items are "really" on the page and css can be used.

For example, you get the svg source code from a request, and put it into a div you come to something like this :

<div id="image">
    <svg xmlns:svg="http://www.w3.org/2000/svg" version="1.0" width="830.69293" height="275.62558" id="svg2">
    //SVG ITEMS
    </svg>
</div>

In this example, I use a svg file from there : https://upload.wikimedia.org/wikipedia/commons/5/57/WHComplex.svg (I removed useless tags from the svg file and only used svg items from it)

Then, I used jQuery event handlers to set style on the svg items, this way :

$('body').on('click','#rect2384',function(){
    //THIS IS WORKING 
    $(this).css('fill','red');
    $(this).css('opacity','0.2');
});

Now, if you use css style, like this :

//CSS : 
<style>
    .border{
        fill:red;
        opacity:0.2;
    }
</style>

//JS/JQuery
$('body').on('click','#rect2384',function(){
    $(this).toggleClass('border');
});

THIS IS WORKING TOO, class is added BUT only "common css" attributes are working. FILL not working, but OPACITY works fine this is why I think that, actually, the best solution for svg dynamic styles is to avoid referenced files, and manage it with javascript/jquery and not with css sheets.

So, to me, there is actually no way to use css/styling on "referenced by url" svg items... except tricking this by getting image source code and insert it on the page.

Here is a quick fiddle, in HTML part you can see "simplified source code" of the svg file I used, wikipedia original svg link, and a div with id "imageTwo" that will get the svg code... In css part you see the class border style I use in my example. In js part you see the svg code (I did it without ajax but effect is the same) in a variable, and eventhandler on the rect item (it is the "ROSE GARDEN" item).

http://jsfiddle.net/pe24t8Lk/1/

So, in my own problem, I used class attributes on the svg items I had to style. Used style tag in svg to define "main items style" and used jquery eventHandlers to set dynamic style attributes like you're doing with :hover.

Hope this will help you...

Julo0sS
  • 2,096
  • 5
  • 28
  • 52
  • Yes this is the same approach as I am using now, putting the svg in the DOM with JS. I may just have to quit being butt hurt about looking at all the big svg files i have, and get used to seeing it in visual studio instead, and not in the form that actually gets loaded into the DOM or what you can see via F12. I appreaciate the time you took to lay out your approach. while this is not the answer i was hoping for, i did learn a few things from your technique. – Dogbyte Jul 17 '15 at 14:19
  • @Dogbyte Sorry that I can't give you the answer you hoped. Svg files are meant to be smaller than any other kind of vector image files you can use. This is why, IMO, including a svg file straight into a web page is not a problem. Biggest files I used are most under 500Ko, and nowadays, a 500Ko file loaded in a webpage is no more a problem... Now another idea : What about an iframe to display your svg instead of img tag? code would be reachable into the iframe container... Good luck ;) – Julo0sS Jul 22 '15 at 08:52
0

As described in @Julo0sS's answer, the contents of externally referenced SVGs aren't included in the DOM. If styling your SVG programmatically is where you want to go and inlining isn't, you can use jQuery to inline the contents of the SVG dynamically. The following SO post walks you through it.

This SO post walks you through it.

This CodePen shows a modified implementation of it in action. It implements as follows:

HTML

<img src="some-svg.svg" class="svg">

JS

inlineSvgElements();

CSS

.select-all-the-svg-elements {
}