I'm working with an SVG pattern that uses a custom font, so as to use that pattern as a background image on an HTML page.
Everything renders fine in Chrome and Safari but it starts to get funny in Firefox:
Firefox renders the SVG along with the custom font text just fine when I open the SVG file itself (so far so good!);
However, Firefox does NOT render the custom font anymore when that same SVG file is used as the background to an HTML element (!)
I've spent hours trying to isolate the issue and a fresh pair of eyes would be welcome.
Here's what I've got in short:
CSS:
#import url(http://fonts.googleapis.com/css?family=Indie+Flower);
body {
background: url(pattern-google.svg);
}
SVG file:
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" xmlns:xlink="http://www.w3.org/1999/xlink" height="200" width="200">
<style type="text/css">#import url(http://fonts.googleapis.com/css?family=Indie+Flower);</style>
<defs>
<!-- Geometry -->
<g>
<rect id="square" x="0" y="0" width="200" height="200" />
</g>
<!-- Patterns with Text -->
<pattern id="pattern" x="0" y="0" width="40" height="40" patternUnits="userSpaceOnUse" text-anchor="middle" font-size="20" font-family="Indie Flower, sans-serif" style="font-family: Indie Flower, sans-serif;">
<rect x="00" y="00" width="40" height="40" fill="transparent" />
<text x="00" y="00" fill="#777">S</text>
<text x="40" y="00" fill="#777">S</text>
<text x="20" y="20" fill="#777">S</text>
<text x="00" y="40" fill="#777">S</text>
<text x="40" y="40" fill="#777">S</text>
</pattern>
</defs>
<!-- Graphics -->
<use xlink:href="#square" transform="translate(0, 0)" fill="url(#pattern)"/>
</svg>
The HTML itself does not really matter but I've linked it below.
I did not produce a jsfiddle in the end because I could not host the SVG file there.
(Outside of the demo, the real-world application here is that I want to use a custom font to display phonetic symbols. (As background image, to help people learn them.) Doing so in SVG saves me the hassle to export to bitmap anytime I make a change in design.)
You are using SVG in an image context. I.e. either via the html <img> tag, the SVG <image> tag or in your case as a background image.
In Firefox (and likely in other UAs at some point) images must consist of a single file only. Any data external to the image file (pattern-google.svg) is ignored. If you display the SVG directly then external data is loaded/used.
So what can you do...
Load the data as a data URI. I.e. base64 encode http://fonts.googleapis.com/css?family=Indie+Flower but read the final paragraph before you do this and then stick that data directly in the svg file itself.
So the import would look like this...
#import url('data:text/css;base64,whatever the base 64 encoded data looks like...')
Do be careful though because http://fonts.googleapis.com/css?family=Indie+Flower itself has external data so that data itself must itself be encoded as a data URI. I.e. you must go all the way down the rabbit hole. And change that file as I've sketched out below.
#font-face {
font-family: 'Indie Flower';
font-style: normal;
font-weight: 400;
src: local('Indie Flower'), local('IndieFlower'), url(**convert this file to a data URI too before you convert the whole file to a data URI**) format('woff');
}
Once you've done that you can then encode the whole file as a data URI and #import it.
So, to reiterate step by step...
Convert http://themes.googleusercontent.com/static/fonts/indieflower/v5/10JVD_humAd5zP2yrFqw6nhCUOGz7vYGh680lGh-uXM.woff to a data URI
Replace http://fonts.googleapis.com/css?family=Indie+Flower with a version that has the data URI from step 1
Convert the file in step 2 to a data URI
#import the data URI from step 3
There are plenty of sites online that will create data URIs.
Related
I have an SVG file freshly exported from Figma.
I don't want to inline it because it's used on multiple places.
I can't specify it as <img src="..."> because I need to style its parts.
So, I tried to include it like this:
<svg>
<use xlink:href="http://example.com/myshape.svg"></use>
</svg>
But it doesn't work. MDN states:
The <use> element takes nodes from within the SVG document, and duplicates them somewhere else.
It takes nodes from the document. With SVG sprites, you have <symbol> tags with id attributes and you reference them with <use> by adding xlink:href="mysprite.svg#symbolid". However, here I need to use the whole document, I.E. the root node. Is there a way to do that?
It would also be great if I don't have to edit the source SVG file, as it's uploaded via an admin panel by the user. It's just a file exported from any vector graphics program.
SVG 2 (when implemented in browsers) will allow to reference another SVG file without any fragment identifier:
New in SVG 2: An href without a fragment allows an entire SVG document to be referenced without having to ensure that it has an ID on its root element.
Before:
<!-- my-vector.svg -->
<svg id="icon" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
<circle r="10" cx="12" cy="12" />
</svg>
<use href="my-vector.svg#icon"></use>
After (there will be no need to define id="..." on the svg):
<!-- my-vector.svg -->
<svg viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
<circle r="10" cx="12" cy="12" />
</svg>
<use href="my-vector.svg"></use>
SVG 2 seems to be in the process of development in major browsers (see this Chrome feature and specifically this Chromium issue: Issue 366545: [SVG2] Allow to reference entire files).
I'm having a problem with CSS styling of inline SVG code in HTML.
I have a HTML page index.html, CSS file style.css and SVG file external.svg.
In the SVG file I created a few hexagonal objects in symbol tags. I use this file only as library of svg objects.
In the HTML file I use inline SVG that's using objects from the SVG file.
And the CSS file should change color of some inline SVG text in HTML file.
This is an example of the inlined SVG code from the HTML file. The <use ...> tag imports objects from the SVG file.
<svg id="zab4text" xmlns="http://www.w3.org/2000/svg" version="1.1" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0,0,300,300">
<a xlink:href="https://www.google.com" xlink:title="google">
<use xlink:href="external.svg#hex4" fill="none"/>
<text font-size="40" font-weight="bold" font-family="DejaVu Sans">
<tspan x="55" y="105">first line</tspan>
<tspan x="55" y="150">second line</tspan>
<tspan x="75" y="230">third line</tspan>
</text>
</a>
</svg>
The CSS used to style this part of code is this:
#zab4text {
width: 150px;
height: 150px;
fill: red;
}
The result should be a red text in a hexagon. The hexagon is fine, but the text is black. The fill attribute has no effect on the text.
When I want to have a red text I have to give an id directly to the <text> tag and style it. Then it works.
I looked in the inspector in google chrome 55 what's happening.
When the fill attribute was for the svg tag as in the example, I saw in the inspector that the fill color for the text was inherited from zab4text but it didn't set the color.
If the fill attribute was for the text tag, then it was his fill color and it worked fine.
Could it be some bug in google chrome?
When I first opened the HTML page the color was red, but when I opened the link it is pointing to, it changed color to black and I couldn't get the red back.
I tried it in firefox 50 and the same behavior.
I know about the google chrome external file behavior, I use simple python3 web server sudo python3 -m http.server 80.
Has somebody any idea what I am making wrong or where is the problem?
So I found the answer.
The line
<text font-size="40" font-weight="bold" font-family="DejaVu Sans">
should be
<text font-size="40" font-weight="bold" font-family="DejaVu Sans" fill="inherit">
then it will take the color from the <svg> tag in all browsers I tried.
I'm working with an SVG pattern that uses a custom font, so as to use that pattern as a background image on an HTML page.
Everything renders fine in Chrome and Safari but it starts to get funny in Firefox:
Firefox renders the SVG along with the custom font text just fine when I open the SVG file itself (so far so good!);
However, Firefox does NOT render the custom font anymore when that same SVG file is used as the background to an HTML element (!)
I've spent hours trying to isolate the issue and a fresh pair of eyes would be welcome.
Here's what I've got in short:
CSS:
#import url(http://fonts.googleapis.com/css?family=Indie+Flower);
body {
background: url(pattern-google.svg);
}
SVG file:
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" xmlns:xlink="http://www.w3.org/1999/xlink" height="200" width="200">
<style type="text/css">#import url(http://fonts.googleapis.com/css?family=Indie+Flower);</style>
<defs>
<!-- Geometry -->
<g>
<rect id="square" x="0" y="0" width="200" height="200" />
</g>
<!-- Patterns with Text -->
<pattern id="pattern" x="0" y="0" width="40" height="40" patternUnits="userSpaceOnUse" text-anchor="middle" font-size="20" font-family="Indie Flower, sans-serif" style="font-family: Indie Flower, sans-serif;">
<rect x="00" y="00" width="40" height="40" fill="transparent" />
<text x="00" y="00" fill="#777">S</text>
<text x="40" y="00" fill="#777">S</text>
<text x="20" y="20" fill="#777">S</text>
<text x="00" y="40" fill="#777">S</text>
<text x="40" y="40" fill="#777">S</text>
</pattern>
</defs>
<!-- Graphics -->
<use xlink:href="#square" transform="translate(0, 0)" fill="url(#pattern)"/>
</svg>
The HTML itself does not really matter but I've linked it below.
I did not produce a jsfiddle in the end because I could not host the SVG file there.
(Outside of the demo, the real-world application here is that I want to use a custom font to display phonetic symbols. (As background image, to help people learn them.) Doing so in SVG saves me the hassle to export to bitmap anytime I make a change in design.)
You are using SVG in an image context. I.e. either via the html <img> tag, the SVG <image> tag or in your case as a background image.
In Firefox (and likely in other UAs at some point) images must consist of a single file only. Any data external to the image file (pattern-google.svg) is ignored. If you display the SVG directly then external data is loaded/used.
So what can you do...
Load the data as a data URI. I.e. base64 encode http://fonts.googleapis.com/css?family=Indie+Flower but read the final paragraph before you do this and then stick that data directly in the svg file itself.
So the import would look like this...
#import url('data:text/css;base64,whatever the base 64 encoded data looks like...')
Do be careful though because http://fonts.googleapis.com/css?family=Indie+Flower itself has external data so that data itself must itself be encoded as a data URI. I.e. you must go all the way down the rabbit hole. And change that file as I've sketched out below.
#font-face {
font-family: 'Indie Flower';
font-style: normal;
font-weight: 400;
src: local('Indie Flower'), local('IndieFlower'), url(**convert this file to a data URI too before you convert the whole file to a data URI**) format('woff');
}
Once you've done that you can then encode the whole file as a data URI and #import it.
So, to reiterate step by step...
Convert http://themes.googleusercontent.com/static/fonts/indieflower/v5/10JVD_humAd5zP2yrFqw6nhCUOGz7vYGh680lGh-uXM.woff to a data URI
Replace http://fonts.googleapis.com/css?family=Indie+Flower with a version that has the data URI from step 1
Convert the file in step 2 to a data URI
#import the data URI from step 3
There are plenty of sites online that will create data URIs.
I am completely clueless, what is going wrong with my svg pattern. I defined it in the def section of the svg and then tried to reference it. But it doesn't show up once I include the svg in an img-tag. If I open it on itself in the browser everything is good though.
See the following examples:
http://kijani.co/img/sketch/index.html
http://kijani.co/img/sketch/livingroom.svg
And my code:
<defs>
<pattern id="paper" patternUnits="userSpaceOnUse" width="200" height="200">
<image xlink:href="http://kijani.co/img/pattern/paper.jpg" width="200" height="200"/>
</pattern>
</defs>
<g id="background">
<path id="paper" fill="url(#paper)" d="..."/>
</g>
This might be a really stupid question, but I am fairly new to svg and couldn't find a solution anywhere so far.
This is svg's referencing mode probrem.
Using img element to display svg image is restrected for refering outer resources.
So you should use object element to display svg image, or embed pattern image into svg by data scheme format.
I have multiple SVG pictures embedded into single HTML page.
Every SVG has own defs section that I am referencing to in my use elements.
It looks like I can't define element with the same id inside multiple defs and reference to it.
Second SVG use will pick the definition form the first SVG defs section, and ignore the local redefinition.
Does anybody know how I can reference to the LOCAL defs section?
The same story in Chrome and Firefox.
See the example below:
<html><head></head><body>
<svg height="50" width="50">
<defs>
<rect id="mybox" height="40" width="40" style="fill:#00F;"></rect>
</defs>
<use xlink:href="#mybox"/>
</svg>
<svg height="50" width="50">
<defs>
<rect id="mybox" height="20" width="20" style="fill:#F00;"></rect>
</defs>
<use xlink:href="#mybox"/>
</svg>
</body></html>
An SVG file with multiple identical IDs is invalid per http://www.w3.org/TR/SVG/struct.html#IDAttribute
Your options are either make all the IDs unique or move the SVG into separate files and reference them via <object> or <iframe> tags.
I created a tool to randomize definition id's to avoid this issue with inline svg's referencing the same #id, hopefully it will be useful for someone else. http://hugozap.com/randomize_svg_def_ids.html
One way to solve this is using svgo
svgo --enable=prefixIds *.svg
svgo can be installed via npm and is available as a library as well