Problem with imported stylesheet in svg file after webpack processing - svg

According to https://www.w3.org/TR/SVG/styling.html#StylingWithCSS, in order to configure svg to use styles defined in an external stylesheet, you can import them as follows:
<svg xmlns="http://www.w3.org/2000/svg">
<style>
#import url(mystyles.css);
</style>
<rect .../>
</svg>
This works fine in Chrome when the files exist in their original format, whether served from a web server or read from the local filesystem, but after building with webpack the resulting app's svg elements have no styling, so clearly the stylesheet isn't getting found.
All of the searches I've done turn up lots of info on what is more or less the reverse operation - referencing svg files from within css (e.g., to specify an svg image as the background for an element).
Does anyone know of a webpack plugin and/or configuration specifically for this case?

Related

How to reference SVGs in html with access to css styling

I have a number of different SVGs to include in my project (Angular 10).
Some of them are used multiple times with different sizes and fill colors etc.
I am trying to find a way to reference them in my html code and have access to via styling:
CSS:
.svg {
fill: red;
}
Referencing:
<svg>
<use></use>
</svg>
<object></object>
<img></img>
<embed></embed>
As yet, I have not been able to find a solution that allows me to reference them but also have the ability to access the fill property in the SVG itself as i can when adding inline.
Inline:
<svg>
<path>
</path>
</svg>
Adding them inline is going to be messy.
How is this usually handled?
Your help is appreciated!
You can't. CSS does not apply across document boundaries. If the CSS rules are in the HTML (or imported into the HTML via <link>) then it cannot affect the content of external files.
One solution people have used in the past is to use a bit of Javascript to inline SVG files at runtime.
Otherwise, you will need to put the CSS in the external SVG itself.

Relative filepaths and SVG symbols

It took me a lot of time to figure out an error while playing around with SVG symbols and I still have the question "why?".
I tried to include and SVG symbol using xlink:href like this:
<svg class="icon">
<use xlink:href="../node_modules/icons/icons.svg#my_icon_24px"></use>
</svg>
but the icon did not render at all. Althought the file was linked correctly. (I could open it when I clicked on the link to the SVG file in the source code.)
But when I copy the file icons.svg into the same dir my html file is in and then include it like this:
<svg class="icon">
<use xlink:href="icons.svg#my_icon_24px"></use>
</svg>
it works perfect. Are there any known issues with relative filepaths regarding xlink:href? I guess the .. was the problem.
The SVG didn't render in Firefox neither in Chrome. But why?
UPDATE
Okay seems to be a problem of opening a local HTML file without a webserver. I opened the HTML file in the browser with file://. When I open it over a webserver both paths work perfect.
At least Google Chrome gives a hint:
Unsafe attempt to load URL file:///....../node_modules/icons/icons.svg#my-icon from frame with URL file:///....../web/index.html. 'file:' URLs are treated as unique security origins.

How to specify font-family in SVG

I have this piece of SVG picture:
<text
xml:space="preserve"
style="font-size:18px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;
font-family:'Arial;Sans';
-inkscape-font-specification:'Arial;Sans';font-stretch:normal;font-variant:normal"
x="11.764346"
y="192.01521"
id="text3607"
sodipodi:linespacing="125%"><tspan
sodipodi:role="line"
id="tspan3609"
x="11.764346"
y="192.01521">PCI-E</tspan></text>
which I edited on linux using inkscape. It used font "sans" which is not available on windows. I would like to specify a font-family that contains fonts available on all major operating systems, but whatever syntax I use it doesn't work. So far I tried:
font-family:'Arial' - works on windows
font-family:'Sans' - works on linux
font-family:'Sans,Arial' - broken
font-family:'Sans;Arial' - broken
What is correct syntax for this to work? I was rendering the picture in IE and Firefox, both seems to have same problems.
in order to change font-family in svg you should first import font in defs in svg like this:
<defs>
<style type="text/css">#import url('https://fonts.googleapis.com/css?family=Lato|Open+Sans|Oswald|Raleway|Roboto|Indie+Flower|Gamja+Flower');</style>
</defs>
then you can change font-family either using an inline style or by javascript
<text xmlns="http://www.w3.org/2000/svg" style="direction:rtl ;font-family:Gamja Flower" id="nametxt" class="text" transform="matrix(1 0 0 1 390 88.44)">text</text>
and for javascript:
svgTextNode.style.fontFamily=FontFamily
It seems that problem was I had it wrapped in quotes. Correct syntax (or at least it works to me):
font-family:Sans,Arial; (no quotes)
In case if we need to declare global style we could use the following syntax:
<svg width="100" height="100"
xmlns="http://www.w3.org/2000/svg">
<style>
text {
font-family:Roboto-Regular,Roboto;
}
</style>
...
</svg>
For security reason, embedded svg images have to be standalone images. You will need to make the svg 'standalone' by embedding all external assets (in our case is the font definition) into it.
To embedded the font inside svg file, follow these steps:
1. Generate the embedded font url as base64
Download the font file you want to use under .ttf extension.
We will need to have the embedded as data URI scheme.
Upload this font file to any online Data URI converter,
I'm using dopiaza.org data URI generator for simplicity (or you can use any File to Base64 converter tool, as long as you follow the same data-uri generated pattern).
Upload the font file to the converter. Ensure Use base64 encoding is checked. Since we're embedding font, so choose Explicitly specify mime type
and put the mime type is application/font-woff
Hit the Generate Data URI and let the tool do the job, it should present you the following data URI format:
data:<mime-type>;base64,<the_encoded_font_as_base64_content>
In our case using font as Mime-Type, it will be:
data:application/font-woff;base64,AAEAAAATAQAABAAwR0RFRv4pBjw....
2. Declare the embedded font inside our SVG file
Edit our SVG file that's using the font. Declare #font-face inside the tag. Put the generated data-uri URL above in the src: url("<generated_data_uri>")
<svg>
<defs>
<style>
#font-face {
font-family: Inter;
src: url("data:application/font-woff;base64,AAEAAAATAQAABAAwR0RFRv4pBjw....")
}
</style>
</defs>
<!-- The rest of your SVG content goes here -->
</svg>
In my case I was converting an SVG as a base64.
Using font-family="Arial, sans-serif;" was not working, but when I removed ";" semi-colon from last portion, voila! it worked.

Why this MathJax SVG in an image data URI does not work?

<img src='data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz48c3ZnIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIiB2aWV3Qm94PSIwIC04NjUuMzU4Mjg5OTIwMzI5MSAxMDM0LjA4ODkyNDQ5OTIwNjUgOTAzLjA0MjIyMTE2NTUiIHN0eWxlPSJ3aWR0aDogMi4zNjdleDsgaGVpZ2h0OiAyLjA4OGV4OyB2ZXJ0aWNhbC1hbGlnbjogLTAuMTM5ZXg7IG1hcmdpbjogMXB4IDBweDsiPjxkZWZzPjxwYXRoIGlkPSJNSk1BVEhJLTc4IiBzdHJva2Utd2lkdGg9IjEwIiBkPSJNNTIgMjg5UTU5IDMzMSAxMDYgMzg2VDIyMiA0NDJRMjU3IDQ0MiAyODYgNDI0VDMyOSAzNzlRMzcxIDQ0MiA0MzAgNDQyUTQ2NyA0NDIgNDk0IDQyMFQ1MjIgMzYxUTUyMiAzMzIgNTA4IDMxNFQ0ODEgMjkyVDQ1OCAyODhRNDM5IDI4OCA0MjcgMjk5VDQxNSAzMjhRNDE1IDM3NCA0NjUgMzkxUTQ1NCA0MDQgNDI1IDQwNFE0MTIgNDA0IDQwNiA0MDJRMzY4IDM4NiAzNTAgMzM2UTI5MCAxMTUgMjkwIDc4UTI5MCA1MCAzMDYgMzhUMzQxIDI2UTM3OCAyNiA0MTQgNTlUNDYzIDE0MFE0NjYgMTUwIDQ2OSAxNTFUNDg1IDE1M0g0ODlRNTA0IDE1MyA1MDQgMTQ1UTUwNCAxNDQgNTAyIDEzNFE0ODYgNzcgNDQwIDMzVDMzMyAtMTFRMjYzIC0xMSAyMjcgNTJRMTg2IC0xMCAxMzMgLTEwSDEyN1E3OCAtMTAgNTcgMTZUMzUgNzFRMzUgMTAzIDU0IDEyM1Q5OSAxNDNRMTQyIDE0MyAxNDIgMTAxUTE0MiA4MSAxMzAgNjZUMTA3IDQ2VDk0IDQxTDkxIDQwUTkxIDM5IDk3IDM2VDExMyAyOVQxMzIgMjZRMTY4IDI2IDE5NCA3MVEyMDMgODcgMjE3IDEzOVQyNDUgMjQ3VDI2MSAzMTNRMjY2IDM0MCAyNjYgMzUyUTI2NiAzODAgMjUxIDM5MlQyMTcgNDA0UTE3NyA0MDQgMTQyIDM3MlQ5MyAyOTBROTEgMjgxIDg4IDI4MFQ3MiAyNzhINThRNTIgMjg0IDUyIDI4OVoiPjwvcGF0aD48cGF0aCBpZD0iTUpNQUlOLTM0IiBzdHJva2Utd2lkdGg9IjEwIiBkPSJNNDYyIDBRNDQ0IDMgMzMzIDNRMjE3IDMgMTk5IDBIMTkwVjQ2SDIyMVEyNDEgNDYgMjQ4IDQ2VDI2NSA0OFQyNzkgNTNUMjg2IDYxUTI4NyA2MyAyODcgMTE1VjE2NUgyOFYyMTFMMTc5IDQ0MlEzMzIgNjc0IDMzNCA2NzVRMzM2IDY3NyAzNTUgNjc3SDM3M0wzNzkgNjcxVjIxMUg0NzFWMTY1SDM3OVYxMTRRMzc5IDczIDM3OSA2NlQzODUgNTRRMzkzIDQ3IDQ0MiA0Nkg0NzFWMEg0NjJaTTI5MyAyMTFWNTQ1TDc0IDIxMkwxODMgMjExSDI5M1oiPjwvcGF0aD48L2RlZnM+PGcgc3Ryb2tlPSJibGFjayIgZmlsbD0iYmxhY2siIHN0cm9rZS13aWR0aD0iMCIgdHJhbnNmb3JtPSJtYXRyaXgoMSAwIDAgLTEgMCAwKSI+PHVzZSB4bGluazpocmVmPSIjTUpNQVRISS03OCI+PC91c2U+PHVzZSB0cmFuc2Zvcm09InNjYWxlKDAuNzA3MTA2NzgxMTg2NTQ3NikiIHhsaW5rOmhyZWY9IiNNSk1BSU4tMzQiIHg9IjgxNiIgeT0iNTEzIj48L3VzZT48L2c+PC9zdmc+' />
Here's a sample fiddle: http://jsfiddle.net/elhoyos/KL489/
I took the liberty to include the deps glyphs MathJax provides in another SVG element of the same document.
When you embed SVG within html namespaces are optional when you reference a file where the svg node is the root then they are not.
You are missing the SVG namespace in your encoded data i.e. you need
xmlns="http://www.w3.org/2000/svg"
on the root node.
Your example works for me with that change.

Inline SVG with .html extension displays correctly, with .svg extension it doesn't

I have a pie-chart SVG generated by d3. If
I save the content in a file with .svg extension
none of the browsers are able to display it.
If I save the same content in a file with
extension .html, it gets displayed fine.
Why ?
The SVG content is here http://pastebin.com/9QPKT5ju
To add to more detail, there is no web server involved,
just saving the content in a file with .html extension
& loading the file in browser makes it display correctly,
while changing the extension to .svg & reloading it in
browser makes it disappear.
The reason I am doing this, is that I am generating the
svg using Node.js on server side & want to embed the
generated svg in a html page & a PDF file. For the above
experiment I just wanted to see if generated svg displays
properly in browser as it would be loaded dynamically in
a fixed HTML template.
You need to add the following to the base svg element:
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
Your color definitions also need to be like this:
<radialGradient id="grad-0" cx="0" cy="0" r="190"><stop offset="0" stop-color="#ace98c"></stop><stop offset="0.3" stop-color="#ace98c"></stop><stop offset="1" stop-color="#70c046"></stop></radialGradient>
instead of radialgradient (i.e. the camel casing is important.)

Resources