Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using an SVG and Apply CSS from Stylesheet

So I've browsed several articles and questions here, but no holy grail.

I have an external file icon.svg, and I want to use it in several HTML files and have a different fill and sizes for each use.

I can't use <object> from what I gather since it doesn't allow for styles from CSS sheets unless you reference that sheet from the SVG file itself, which kind of defeats the entire purpose.

The only way I found how to do this is like this:

<svg class="icon">
     <use xlink:href="icon.svg#symbolid"></use>
</svg>

And the CSS applies. But I can only seem to do it if I add symbol nodes in the SVG file and give them an ID, which I'd rather not do.

Also, could it be that this might be not supported in all major browsers ?

Any way to achieve this ?

Update:

Added tags for javascript/angularjs since the solution was JS based. (see answer)

like image 397
Omri Aharon Avatar asked Jun 25 '15 07:06

Omri Aharon


1 Answers

OPTION 1 - Using generic css styles

Personally I create several fill colours and simply apply the class to the svg where required.

HTML

<svg class="icon red">
   <use xlink:href="icon.svg#symbolid"></use>
</svg>

CSS

.icon{
  fill:#000;
}
.red{
  fill:#b00;
}
.blue{
  fill:#ddf;
}

OPTION 2 - SVG's targeted by unique class

If your svg has several paths you can target each using other classes.

HTML

<svg class="icon symbol">
   <use xlink:href="icon.svg#symbolid"></use>
</svg>

CSS

.icon{
  fill:#000;
  height:20px;
  width:20px;
}
.symbol{
  height:40px;
  width:40px;
}
.symbol .path1{
  fill:#b00;
}
.symbol .path2{
  fill:#ddf;
}

OPTION 3 - SVG's as background images

DEMO

To utilise svg's like images they can be targeted with css and even used as background images in css but each svg symbol would need to be a unique file.

<div class="icon"></div>

.icon{
  display:block;
  height:20px;
  width:20px;
  background: url(icon.svg);
  background-size: 20px 20px;
}

To use the svg as different height and widths simply edit in css using additional classes to overwrite defaults using specificity:

.svg40{
  height:40px;
  width:40px;
}
.svg100{
  height:100px;
  width:100px;
}

OPTION 4 - Inline Svgs (My recommendation)

DEMO

Place the svg file directly in your html to reduce http requests and improve control.

HTML

Place just after your body tag at the top of your html

<div style="height:0;width:0;position:absolute;visibility:hidden;">
  <svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
  <symbol id="symbolid1" viewBox="0 0 64 64">
  <title>symbol 1</title>
  <path ... />
  </symbol>
  <symbol id="symbolid2" viewBox="0 0 64 64">
  <title>symbol 2</title>
  <path ... />
  </symbol>
</div>

Then you can call the svg's from anywhere using the svg's id.

<svg class="icon"><use xlink:href="#symbolid"/></svg>

CSS

.icon{
    display:inline-block;
    fill:currentColor;
    width:20px;
    height:20px;
}
like image 144
DreamTeK Avatar answered Sep 23 '22 08:09

DreamTeK