How (else) can I make an SVG clickable for linking? - html

I'm using object to embed some SVGs that I would like to href to other pages.
First option is to change the xml inside
See Inkscape FAQ-s 1.8.1
http://wiki.inkscape.org/wiki/index.php/Frequently_asked_questions
But I want to use javascript to dynamically change the url if they have js enabled. AND i want to reuse the same SVG doc anyway but with different links. So I need another option.
Second option, wrap the embedded object in a 'a href' tag, but that doesn't seem to work, it makes the div part that ISN'T covered by SVG a clickable link but not the svg.
{Further complicated because inside the object I have a .png (made clickable by using usemap) which if the browser falls back to I get TWO clickable areas. The PNG and DIV remainder....}
Third Option, a USEMAP for the svg itself! No that doesn't seem to work either.
Are there any other options? Javascript answers welcome, for reference purposes, but ideally not.
EDIT to add HTML code
<object class="svg" type="image/svg+xml" data="svgimage.svg" >
<img src="pngbackupforIEpre9androidpre3.png" type="image/png" usemap="#mapping"/>
</object>
</a>
<map name="mapping">
<area shape="rect" coords="0,0,100,100" href="svgfreezone.php" />
</map>
EDIT to add SVG XML code
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns="http://www.w3.org/2000/svg" height="100%" viewBox="0 0 617.875 320.75" width="100%" version="1.1" xmlns:cc="http://creativecommons.org/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/">
<metadata>
<rdf:RDF>
<cc:Work rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage"/>
<dc:title/>
</cc:Work>
</rdf:RDF>
</metadata>
<g transform="translate(-66.78125,-339.125)">
<rect style="stroke:#000000;stroke-miterlimit:4;stroke-dasharray:none;stroke-width:3.5999999;fill:#ff0000;" height="317" width="614" y="341" x="68.6"/>
</g>
</svg>
Notes; The svg has been vacumed def'd, saved as plain and then optimised using "Simplify colours Y, Style to xml N, Group Collapsing Y, Enable ID stripping Y, Embed rasters N, Keep editor data N, Enable viewboxing Y, Strip xml prolog N, Set precision 3, Indent None."

Well, I see two options:
First option: (This will be only good if this is a web app; if its a "regular" website this may not be suitable for you)
Use a regular href in the SVG, which links to an anchor. That is - a #something url. Just a hash.
Now use a "special" hash which you can recognize, and then hook to the window's "hashchange" event, and see if the hash == '#my_special_hash' - then redirect to wherever you like.
Second option:
Put a placeholder href in the SVG, and read the SVG content with JavaScript.
Then replace the href with the url you really want, and inject it to the page.
Most browsers support SVG as a source image, and as an object.
You can see how the Raphael library builds SVG if you need actual code. Note that it uses VML for fallback because of lack of support in some old browsers.
Good luck! :-)

Set the background-image css property on the anchor to the svg image and it will be clickable.
I used one in this page.
#infoButton {
display: block;
float: left;
background-image: url('info.svg');
background-repeat: no-repeat;
width: 70px;
height: 70px;
}

Be sure to always put display: block; when using SVG some browsers don't support SVG properly.

Related

How can I set the "preserveAspectRatio" attribute in a nested SVG?

We have a server generated SVG which cannot be modified and which needs to be displayed nested inside of another, larger, SVG.
It is necessary to modify the "preserveAspectRatio" attribute of the contained (inner) SVG to
preserveAspectRatio="none"
for it to display correctly.
The current approach is to define the nested SVG inside of a DEFS tag as follows:
<defs>
<svg id="serverSetID"
viewBox="0 0 200 200"
>
svg content here
</svg>
</defs>
and then reference it as follows:
<use
xlink:href="#serverSetID#svgView(preserveAspectRatio(none))"
x="0"
y="0"
width="200"
height="200"
/>
Note: the nested SVG has a server generated ID attribute that is unique for that page.
If I leave out the "#svgView(preserveAspectRatio(none))" then it displays although not the way I want it to.
But if I include "#svgView(preserveAspectRatio(none))" then it does not display at all.
I have looked into other strategies such as directly including the code of the inner SVG within the body of the outer SVG without using the DEFS tag. But the problem with that strategy is that there does not appear to be a way to manipulate the "preserveAspectRatio" attribute since, as far as I can tell by experimentation and research, that attribute is not exposed to CSS in an SVG.
We are anxious NOT to use JavaScript for this because the page already has a LOT of very complex JS and we are trying to pare it down where possible.
Does anybody have any suggestions please?
PS. If I overlooked something (highly likely) or if "preserveAspectRatio" is indeed manipulable by CSS I will be humbly grateful for somebody to point out my error.

Most efficient way to add inline SVG?

I have a webpage with lots of SVG icons that will be in the HTML. Rather than include them as an IMG tag and possibly slow the page with those HTTP requests, I'm placing the SVG code like this:
<svg xmlns="http://www.w3.org/2000/svg" width="9" height="9" viewBox="0 0 9 9"><path fill="#C5C2BD" fill-rule="nonzero" d="M4.5 3.435L1.286.22A...LOTS OF CODE HERE..."/></svg>
Note: where it says "lots of code here", there is a huge string of numbers/letters that make up the path for this SVG.
The issue this creates is it's very ugly when not easily maintainable in the HTML (to the point where my editor bogs own because these SVG strings are so long).
Is there a cleaner, simpler way to include these SVG icons in my HTML while still eliminating the extra HTTP requests?
Thanks for your time.
The most proven way is to collect all the icons SVG in one file - the sprite SVG
Creating a Sprite and connecting it to HTML
The action plan is as follows:
Creating a Sprite
Connecting it to HTML
Calling SVG images from the sprite
Styling icons
Creating a Sprite
The main task of the sprite is to be a repository for icons that before the call to a specific place HTML pages should be invisible.
To do this,the code for each icon is wrapped with <symbol id =" .. "> ... </ symbol> tags with a unique identifier, which will be followed by the <use>
Template Sprite:
<div id="container">
<svg version="1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"
viewBox="0 0 126 126" >
<symbol id="picasa">
<path d="M113.5 57.... 72.8z" />
</symbol>
<symbol id="wordpress" viewBox="0 0 126 126">
<path stroke ="black" d="M113.5 57.7l-8.5-11.4 .. 86.1 62.9z"/>
</symbol>
<symbol id="twitter">
<path d="M113.5 57.6l-8.5-11.4.... 7.4-2.4V85.4z"/>
</symbol>
<symbol id="apple">
<path d="M113.5 57.7l-8.5-11.4... 78.5 78.7 82z"/>
</symbol>
</div>
As you can see, all <path> attributes are removed for later styling of icons from an external CSS file.
Adding a sprite file to HTML
There are several ways to add SVG files to HTML, but the most reliable way is to add it using the <object>
<object type="image/svg+xml" data="Sprite.svg" width="200" height="200">
Your browser does not support SVG
</object>
Adding icons from the sprite
<div id="container">
<svg viewBox="0 0 126 126" >
<use xlink:href="#apple"></use>
</svg>
</div>
The viewBox attributes should be like thesvg icon or change the scaling inside HTML if necessary.
Icons as links
For this, in SVG, unlike HTML, its own form of record
<svg viewBox="0 0 126 126" >
<a xlink:href="https://www.apple.com/ru/"><use xlink:href="#apple"></use></a>
</svg>
Styling icons
When using the <use> command, the icon falls into the shadow DOM and its attributes behave strangely, - there is an icon of the icon, but it can not be controlled from the outside.
In addition, the icon attributes for example: style = "fill: gray; stroke: crimson;" have the highest priority. Therefore, we deleted these attributes. see the example of the sprite above.
To solve the problem of inheritance of parental properties by objects in shadow DOM, you must use forced inheritance
svg path{
fill:inherit;
stroke:inherit;
}
and then to the icons you can already apply CSS rules from the external table
svg path:hover{fill:yellow;}
#picasa{fill:black;}
#apple{fill:purple;}
#twitter{fill:black;}
#wordpress{fill:blue;}
If you go for the first time along this path, then inevitably there will be many questions.
Ask, do not be shy.
All sooner or later it turned out to be done and customized sprite.
The main recommendation is to do everything yourself manually for the first time, to understand how it is arranged, and then you can already openly use special utilities to automatically create sprites.
You should convert all your .svg files to one font file, here is how:
How to convert .svg files to a font?

<img src='x.svg'> Make svg pick up the font face defined by me, aka font-family [duplicate]

I have an SVG that displays fine in Chrome, but when I use it in an HTML page, it doesn't use the right font, instead using the default.
<svg version="1.1" xmlns="http://www.w3.org/2000/svg">
<defs>
<style type="text/css">
<![CDATA[
/* latin-ext */
#font-face {
font-family: 'Roboto-Black';
src: url(./Roboto-Black.ttf)
}
]]>
</style>
</defs>
<text style="font-family: 'Roboto-Black'; font-weight:normal;" transform="matrix(1, 0, 0, 1, 239.2, 51.394)">
<tspan x="-101.469" y="27" font-family="Roboto-Black" font-size="72" fill="#000000">TEST</tspan>
</text>
</svg>
The SVG displays fine in Chrome, but when displayed in an HTML page, it doesn't use the right font.
<html>
<head></head>
<body>
<img src="test.svg" width="100%">
</body>
</html>
What am I missing?
Addendum:
Although a valid solution was offered below, I found it was easier to include the svg code directly in the html, instead of referencing an svg file. That way the problem doesn't arise.
When used as an image (via an html <img> tag, an SVG <image> tag or as a CSS background-image) SVG must be consist of a single file in order to protect user privacy.
You can use a font, but you'll need to convert the font data to a data URI and embed the font in the SVG file.
Instead of incorporating/linking to a font, often you can also export the SVG using the option "Export text as curves for font independence". This is at least possible with Affinity Designer. This does make the file a bit heavier, but if you only use the font in this SVG, then of course it is much lighter overall.
Depending on the circumstance, this might be an option worth looking into.
How I solved it:
Instead of using the <img> tag, I have included the .svg file content:
<?php
$svg_file = file_get_contents(get_template_directory_uri().'/test.svg');
echo $svg_file;
?>
Without being encapsulated inside the tag, the included .svg can require and use the font-family.

How to create hoverstates with svg <use> tag

So I recently found this svg technique on csstricks and decided to use it in conjunction with the grunt task grunt-svgstore. I thought this was the perfect thing since you have access to the actual svg with css and javascript without pasting the whole svg code in the html. But I found one major problem I can't solve which is hoverstates (and similar). The problem is the following. If that's my html body (with the svg on top)
<body>
<svg>
<symbol id="arrow">
<path ... />
</symbol>
</svg>
<svg id="icon-arrow">
<use xlink:href="#arrow"></use>
</svg>
</body>
I can access the #icon-arrow svg or the #arrow symbol but neither will give me the ability to create a hoverstate. When doing #icon-arrow I can get a hoverstate but I can't access the actual shape because it is not actually a child of the #icon-arrow so doing #icon-arrow #arrow:hover won't work. On the other hand directly selecting the shape doesn't work because the shape is not actually there but it's only a reference. Is it actually possible to do hoverstates using this technique? Or are there any other solutions?

Embed group from svg file into html

I want to embed a group from an SVG file, that can be identified with an id. My naive approaches were:
1. embed
<embed src="cards/svg-cards.svg#joker_red"
id="embsvg"
width="300" height="220" type="image/svg+xml"
pluginspage="http://www.adobe.com/svg/viewer/install/"
viewBox="0 0 100 100"
/>
2. image
<image id="i" x="10" y="20" width="80" height="80"
xlink:href="cards/svg-cards.svg#joker_red" />
3. object
<object data="cards/svg-cards.svg#red_joker"></object>
and I tried some more silly variants including the USE element and javascript.
The svg document was taken from here: Sourceforge
I found it out myself.
The important piece was, to give all visible elements a class attribute, say class="card" and specify 'svg .card { display: none }' as a style. That will make everything disappear. Then only the item that is selected via # behind the svg file name is actually displayed.
It doesn't really matter if the part to be displayed is a group or svg element.
Robert's posted code did it this way, but it was not obvious to me how important the class was.