Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Manipulating external svg file style properties with CSS

Tags:

html

css

svg

I am trying to manipulate an external .svg file via CSS.

HTML

<body>     <div class="mysvg">     <img src="decho.svg" alt="decho" width="200px"></img>     </div> </body> 

CSS

div.mysvg img {     opacity: .3;     transition: opacity 1s linear 0s; }     div.mysvg img:hover {     opacity: 1; } 

This code works for opacity, but not for fill or other svg specific attributes like stroke. I am aware I can't do that with an img tag, but I've been looking for hours and I can't find the correct way to do it with svg or object.

So basically, my questions is, how do I achieve the same result as the code which I linked, but to be able to manipulate fill, stroke etc. properties and it must be an external file, not just an inline svg code pasted in the html.

If someone is able to show me the correct way to do it, I'd be most grateful. Thanks.


EDIT:

I managed to do it by adding a css inside the .svg file itself. It must be right after the svg opening tag.

<svg ...> <style type="text/css" media="screen">       <![CDATA[       g {           fill: yellow;           stroke: black;           stroke-width: 1;         transition: fill 1s linear 0s;     }     g:hover {         fill: blue;     }     ]]>   </style>  <g>     <path ...> </g> </svg> 

You also need to insert it as an object in the html, otherwise it won't work.

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

Hopefully this helps to someone looking for an answer like mine in future. This is what helped me http://www.hongkiat.com/blog/scalable-vector-graphic-css-styling/.

like image 683
decho Avatar asked Mar 07 '14 14:03

decho


People also ask

Can you use CSS to style SVG?

Not only does it mean that SVG properties can be styled using CSS as presentation attributes or in style sheets, but this also can be applied to CSS pseudo-classes such as :hover or :active . SVG 2 also introduces more presentation attributes that can be used as styling properties.

Can you edit SVG in CSS?

If you load SVG as an image, you can't change how it is displayed using CSS or Javascript in the browser. If you want to change your SVG image, you have to load it using <object> , <iframe> or using <svg> inline.

Can we add style to SVG?

The SVG <style> element allows style sheets to be embedded directly within SVG content. Note: SVG's style element has the same attributes as the corresponding element in HTML (see HTML's <style> element).

Which properties would you use to change the color of an SVG using CSS?

The fill property is a presentation attribute used to set the color of a SVG shape.


2 Answers

This is in my opinion the greatest flaw in svg: sandboxing.

Svg files are sandboxed: in their own document, which is why a typical 'fill:' style will not apply. Likewise, the css you write in your svg will not apply to the rest of your site.

Adding css directly to an svg: Not a good solution as you will end up rewriting the css in every svg you use.

The real solution: An "icon-system". Svg font-face or svg sprites. Read more about them here.

The reason opacity works: Opacity applies to the svg object/frame itself, not the contents of the svg (which are inaccessible).

I should also note that no matter how you load those svg's, inline, by reference, in an object, as a background, you will not be able to get inside the sandbox. This is why converting them to a font or using sprites is necessary for using hover, focus, and other effects/transitions.

like image 151
Robot Avatar answered Sep 20 '22 21:09

Robot


This is possible providing the SVG is hosted on the same domain (thanks @FabienSnauwaert) and it does not have a fill colour defined on itself, and you do not contain a parent selector within the CSS. For example:

I have the following files:

  • icon-sprite.svg (my external sprite of SVGs)
  • buttons.scss
  • test.html

icon-sprite.svg

I have omitted the other SVGs for clarity.

<svg xmlns="http://www.w3.org/2000/svg" style="width:0;height:0;visibility:hidden;">     <symbol viewBox="0 0 1500 828" id="icon-arrow-3pt-down">         <title>arrow-3pt-down</title>         <path d="M1500 0H0l738.9 827.7z"/>     </symbol> </svg> 

test.html

<button class="button--large">     Large button     <svg class="svg" width="20px" height="20px">         <use xlink:href="icon-sprite.svg#icon-arrow-3pt-down"></use>     </svg> </button> 

buttons.scss

.svg {     fill: red; } 

This would not work if I was to use body .svg due to shadow DOM boundaries.

SVG external css styling

See this CSS Tricks article for more info

like image 34
Ben Crook Avatar answered Sep 22 '22 21:09

Ben Crook