How do you style a external svg with css - css

Is it possible to style an external .svg with css like you would with text? What am I missing?
My mark up and css looks like this:
<style type="text/css">
#ob {
color: blue;
}
svg {
fill: currentColor;
}
<object id="ob" type="image/svg+xml" data="czo_svg_icons/czo_extra_closed.svg">Your browser does not support SVG</object>

If you include your svg image by referencing an external file, like you do with the object tag, the elements in the svg image are not included to your main documents DOM tree. They comprise their own tree. Therefore, the elements in the external image can't be matched by CSS selectors in the main document.
You can style the object element like you could most other elements, for example giving it a border. But you can't (this way, at least) access the elements in the external image. In your case, you try to style #ob's color. That would apply to the objects text color, not to any color inside the referenced svg image. On browsers not supporting svg, the "Your browser does not support SVG" notice would probably rendered in blue.
The case with your CSS selector for svg is similar: CSS selectors in the main document match only to elements in the main document, and there's no svg to be found, just an object.
There are some ways to apply CSS styling to svg elements. The idea generally is to bring the CSS and the svg elements to the same DOM tree, either by getting the svg elements from the external file to the main document or the CSS from the main document to the external file:
Embed your svg element and its child elements directly into the main document instead of referencing an external file. In this case, the svg element and its children will be part of the man document's DOM tree, so they're accessible to the main document's CSS.
Embed an svg element into your main document and use xlink's use to reference an external svg image (rather, a part of it). For the general idea, see this answer or this answer.
Load the elements from the external image to the main documents tree via AJAX/XHR. For the general idea, again see this answer.
You can grab a hold of the external images' tree with JavaScript and edit their styles from there. The keyword for that would be contentDocument, see this answer.
If you can't get the elements from your external svg image to your main document's DOM tree, so the main documents CSS selectors can match to it, you can try the other way around: Add your CSS to your svg file. Similar to the ways you can include CSS into a html document, you can use inline style attributes, use a style element like in html's head or reference an external CSS file with <?xml-stylesheet ... ?>. For more information, see for example this tutorial.

Related

How to reference SVG elements inside iframe using CSS?

I am trying to style elements of SVG using CSS. I used iframe in my index.js file to reference my SVG, and the SVG displays fine. However, my CSS styling didn't apply as it would have had I just copy/pasted the SVG contents into my index.js. The contents are stored under an object #document. How do you reference iframe contents using CSS?
Are you using an <iframe> or an <object>? Your title says the former, but your questions suggests the latter.
Assuming you really mean an <iframe>. Then the answer is: you can't. CSS does not work over document boundaries. So you can't style the contents of an iframe from the page that contains the iframe. The content of the iframe is a separate file (the SVG file).
If you want to style the SVG, then you will need to put the CSS in the SVG (using a <style> element), or reference the CSS file using the XML way of including style sheets:
<?xml-stylesheet href="common.css"?>
See: https://www.w3.org/TR/xml-stylesheet/
Assuming your svg is on the same domain, you could append a stylesheet after loading via js:
let svgIframe = document.querySelector('.svgIframe');
if(svgIframe){
svgIframe.addEventListener("load",function(e){
let svgDoc = svgIframe.contentDocument;
let iframeSvg = svgDoc.querySelector('svg');
let css = document.createElementNS("http://www.w3.org/2000/svg", "style");
css.textContent = 'path{fill:red;}';
iframeSvg.appendChild(css);
});
}

Set CSS class/id in figma and have it declared on the exported svg file

I've been using Figma a lot lately to draw / edit images and export them as SVG files so I can quickly use inside my apps' code bases.
There's just one drawback with that: Looking through the SVG code to find out what element is what.
Up to this moment I'm having to go through the SVG manually in order to mark the elements (with classes or ids) so that I can manipulate them properly via CSS or Javascript, what's quite tedious :-/
It would be really convenient to be able to set an id or a class to each element (path, line, circle etc..) via Figma and have it reflected in the exported code, I strongly believe that there must be a way to do so...
So here I ask: Is there a way to set certain CSS **class** or **id** atribute in Figma and have it declared on the svg code that gets exported?
There's a checkbox "include id attribute" in the export section.
It inserts the element's layer name as the id attribute on the resulting svg tag.
yay 🎉

SVGs override each others CSS-style

I am working with Vue.js and try to place some SVG Icons I made in Illustrator for my Webapp. I loaded the icons with Webpacks "require". It is not possible to access the svg's with their source (src attribute of img tag) so we insert them with vue like that:
<div class="section-icon" v-html="getIconForEvent(event)"></div>
This displays the right icons at the right place, but I ran into some problems with this approach.
The SVGs are all styled with a style-tag within the svgs. So the last SVG overwrites the style of all previous SVGs because they somehow all have the same class. In the Chrome Devtools this looks like
this.
What can I do to not let the style of SVGs overwrite each others classes? I didnt put the style tags there myself, those are just the style that the SVG had itself. Thanks!
There is nothing you can do other than modifying the class names in each SVG so that they don't clash.
It looks like you are using Illustrator to produce those SVGs. To work around the problem, make sure you tell Illustrator, when you save the SVG, to not use <style> elements for element styling.
When you save, use File > Save As > SVG, then click on "More Options" and change the "CSS Properties" setting. If it is set to "Style Elements", change it to one of the other options. If you do that, it won't use classes and your SVGs won't clash with one another.
To fix your current SVGs, you should be able to load them in, then resave them using the method above.
Try targeting them via CSS using children:
.cls-3:first-child {
fill:yellow;
}
.cls-3:nth-child(2) {
fill:red;
}
...
.cls-3:last-child {
fill:blue;
}
Fill with what colors you need to see if it works. If that does not overwrite it, you may need to use !important, although it is not a best practice, rather a worst case scenario.

How do I add CSS (transition) to an item from a SVG file? [duplicate]

This question already has an answer here:
CSS Transitions and transforms on SVG elements
(1 answer)
Closed 8 years ago.
I've created an illustration in Adobe Illustration, which I want to use on a webpage. I also would like to add some CSS transitions to a few items in the illustration. Those items consist each of multiple Illustrator layers.
To add CSS to such thing, I would think of a SVG format file. The problem is: How do I add CSS (transition) to a certain item from a SVG file, instead of the whole file itself?
When I check the uncompressed SVG code, I do see thinks such as <g id="Guitar"> and other items with ID's.
Based upon that, I would think of #guitar:hover { transform:rotate(4deg);transition: all 0.4s ease;}
But I'm unsure about that.
I hope for some feedback. Thanks!
Yes, you can do this. There are three things you need to take into account though:
If you want to target SVG elements with your css, the stylesheet must be inside that SVG, like here
If the svg is loaded using an IMG tag, you can always target the IMG itself. If that SVG contains css files though, they will not apply since an image has to be loaded in a single request, so loading a SVG file that it iself loads a CSS file using an IMG tag, the styling will not work
If you load the SVG as a background image, the browser handles it as an image file, not as an SVG document. So things like :hover, :focus and :active will not work
You can style the SVG elements using the same CSS selectors you would normally use for HTML

Apply media queries in a style attribute (not tag, but attribute)?

I'm experimenting with responsive SVG files, and really want to select the appropriate image independently from the HTML page.
I want to have a setup, where I can pass in an SVG to an img tag, without any further dependency. Then have the SVG rendered before it gets returned in order to display.
As far as I noticed, if I put a style tag into the SVG, then it gets evaluated after the page has loaded, and can access page's DOM elements only, not encapsulated "in-SVG-only" elements. The only way to evaluate styles before loading the page is to put CSS into a style attribute of the entire svg tag. And having media queries there would be awesome.
Does this make sense to you? Is it possible at all?
Inline style attributes don't support media queries.

Resources