How do you add a link inside an SVG image file? - html

I'm having trouble trying to place a clickable link within my SVG image. I've read a few articles but I still cannot seem to get the hang of it, I would greatly appreciate if anyone could guide me on what I may be doing wrong & how I can resolve the issue with my code, Thank you. I'll add a snippet below:
<div class="apps">
<svg id="app-button" height="24px" viewBox="0 0 24 24" width="24px" fill="#000000">
<path d="M0 0h24v24H0V0z" fill="none" />
<path d="M4 8h4V4H4v4zm6 12h4v-4h-4v4zm-6 0h4v-4H4v4zm0
-6h4v-4H4v4zm6 0h4v-4h-4v4zm6-10v4h4V4h-4zm-6 4h4V4h-
4v4zm6 6h4v-4h-4v4zm0 6h4v-4h-4v4z" />
</div>

Links can be placed inside an svg element by use of the xlink namespace, see https://www.w3.org/wiki/SVG_Links.
For the example in the question you could use something like this,
<div class="apps">
<svg id="app-button" height="24px" viewBox="0 0 24 24" width="24px" fill="#000000"
xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<a xlink:href="http://localhost">
<path d="M0 0h24v24H0V0z" fill="none" />
<path d="M4 8h4V4H4v4zm6 12h4v-4h-4v4zm-6 0h4v-4H4v4zm0
-6h4v-4H4v4zm6 0h4v-4h-4v4zm6-10v4h4V4h-4zm-6 4h4V4h-
4v4zm6 6h4v-4h-4v4zm0 6h4v-4h-4v4z" />
</a>
</svg>
</div>
By placing a reference to the xlink namespace in the svg element (xmlns:xlink="http://www.w3.org/1999/xlink") we can use an anchor element like <a xlink:href="...">...</a> around whatever part of the svg image we wish to make clickable.
In this case only the paths are clickable, not the entire svg viewbox as would be the case if we wrapped the whole <svg>...</svg> in a standard html anchor element.

there's no need to add link to svg
just enclose them inside anchor tag
<a href="somelink.com">
<svg></svg>
</a>

Related

Stretching SVGs in TailwindCSS

I'm currently working on a landing page with TailwindCSS, and I'd like to add a decorative item under my headlines. I've created an SVG and used the after pseudo-element to position it under the item I want. Here's an example:
<span after:h-5 after:bg-[url('../public/svg/underline-large.svg')] after:bg-no-repeat />
However, the issue here is that I end up having to bring in longer and shorter SVGs for different headlines. Ideally I would be able to use one SVG and somehow stretch it to match the width of the title. Any idea of how to do this?
You will need some more (after:) options and a relative class, but the most important part to add this preserveAspectRatio="none" attribute to the svg.
HTML
<h1
class="text-2xl
relative
after:content-['']
after:h-[1rem]
after:w-full
after:absolute
after:bottom-[-1.2rem]
after:left-[0]
after:bg-[url('./underline.svg')]
after:bg-no-repeat"
>
Short Title
</h1>
SVG
<svg preserveAspectRatio="none" viewBox="0 0 63 8" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M5.47663 1.41505C21.2121 3.69552 49.2623 6.09008 61.691 1.41505C52.455 5.86203 35.6249 8.49799 1.14368 4.49373" stroke="#2AADD6" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
</svg>

Why doesn't this SVG display?

I'm working on a project that uses svg. I generate this svg code thanks to an ocaml library:
<svg xmlns="http://www.w3.org/2000/svg" xmlns:l="http://www.w3.org/1999/xlink" version="1.1" width="161.8mm" height="100mm" viewBox="0 0 161.8 100" color-profile="auto" color-interpolation="linearRGB" color-interpolation-filters="linearRGB">
<g fill="none" stroke-miterlimit="9.98123" transform="matrix(100 0 0 -100 -0 100)">
<defs>
<path id="i1" d="M0 0L1.618 0L1.618 1L0 1Z"/>
</defs>
<use l:href="#i1" fill="#50C878"/>
</g>
</svg>
When I use gthumb or GIMP to display the svg, it prints the correct green square. However, when I include this block of code in Chromium or Firefox, the block appears in the html tree but nothing is display. This is the first time I use svg: after several researches on Google, I can't find anything....
Does someone know why it doesn't work ?
Edit
Solve with the answer:
<use xlink:href="#i1">

Filling a simple SVG in a div

Here is my relevant HML with SVG:
<div style="width:24px;height:24px;margin:0px;padding:0px;background:black;">
<svg viewBox="0 0 24 24">
<path fill="red" d="M24 12l-9-9v7h-15v4h15v7z"/>
</svg>
</div>
It renders fine but leaves padding above and below the arrow inside the div.
I tried using SVG as background to the div after base64 encoding the SVG tag, as in:
<div style="width:24px; height:24px;margin:0px;padding:0px;background-image:url('data:image/svg+xml;base64,PHN2ZyBmaWxsPSJyZWQiIHRyYW5zZm9ybT0ic2NhbGUoMSwxKSIgdmlld0JveD0iMCAwIDI0IDI0Ij48cGF0aCBkPSJNMjQgMTJsLTktOXY3aC0xNXY0aDE1djd6Ii8+PC9zdmc+');">
</div>
It displays nothing!
Yes there are similar questions asked but this is NOT a duplicate. Nothing in the answers posted to similar questions on SO resolve this problem.
I'm not very sure I understand your question. Maybe this is what you need:
I've changed the viewBox to viewBox="0 3 24 18". In order to get this value I've console.log(thePath.getBBox())
The method getBBox() returns an object with the position and the size of the bounding box of the path. I'm using this values for the new viewBox
viewBox = bb.x bb.y bb.width bb.height
Where bb is the bounding box.
<div style="width:24px;height:18px;margin:0px;padding:0px;background:black;">
<svg viewBox="0 3 24 18">
<path id="thePath" fill="red" d="M24 12l-9-9v7h-15v4h15v7z"/>
</svg>
</div>
The fill needs to be on the path instead of the svg element.
Also, try adding the width="24" and height="24" to the svg element.

Define an inline svg completely with css instead of in the html file itself

I have an html file that uses inline svg. I use this so I can add classes to my svg and style them with CSS. The following snippet works:
<div>
<svg class="icon" viewbox="0 0 512 512">
<path d=" ... "/>
</svg>
</div>
Howeever, the tag can be quite long if the svg is complex. I'm currently using this svg in 3 different locations, and everytime I need to copy paste the entire path. It would be better if I could define the path only 1 time, preferabvly in a css class like this:
<div>
<svg class="icon" viewbox="0 0 512 512">
<path class="compleximage"/>
</svg>
</div>
.compleximage
{
d: ... ;
}
But this doesn't seem to work. Maybe I'm getting it wrong syntactically, or maybe it can't be done this way. If so, are there ways other to prevent having to copy/paste the svg in my html files? I'm trying to follow the "0,1 or infinite" design pattern, and copy/pasting code 3 times break that.
You can use the use tag to display the path in more than one place. Just give the path an id attribute and then refer to that in the xlink:href of the <use> element.
Something like
<defs>
<path id="image1" d="..." />
</defs>
<use x="20" y="10" xlink:href="#image1" />
<use x="50" y="50" xlink:href="#image1" />
etc.
In HTML5 you can do it.
Please try this:
<svg width="100" height="100">
<circle cx="50" cy="50" r="40" stroke="green" stroke-width="4" fill="yellow" />
</svg>
On the other hand, you can create your own SVG and get it via <img src="" />.
Sample below:
<img class="papa" src="http://s.cdpn.io/3/kiwi.svg">
Reference here:
(1) http://css-tricks.com/using-svg/
Another reference here how to change it via css:
(2) http://codepen.io/chriscoyier/pen/evcBu
You cannot set svg attributes using CSS. You can only set styles like stroke, fill, etc.
The only way would be to use javascript to set those paths dynamically. I would recommend jQuery.
this link should be helpful for using jQuery to modify svg files.
Modify a svg file using jQuery

Best way to style SVG without having them inline

I have a menu with about 10 items. Each item has its own icon. This icon is a SVG file.
For example:
<li class="active">
<a href="/home">
<svg version="1.1" id="svg-menu-home"
xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"
x="0px" y="0px" width="31px" height="31px" viewBox="-8 -8 31 31"
overflow="visible" enable-background="new -8 -8 31 31" xml:space="preserve">
<mask maskUnits="userSpaceOnUse" x="0" y="0" width="15" height="15" id="maskTop">
<polygon fill="#FFFFFF" points="12,6.036 2,6.036 2,14.036 6,14.036 6,9.036 8,9.036 8,14.036 12,14.036"/>
<polygon fill="#FFFFFF" points="7,0.036 0,7.036 14,7.036"/>
</mask>
<rect mask="url(#maskTop)" fill="#939598" width="15" height="15"/>
</svg>
<span>Home</span>
</a>
</li>
When a user interacts with the menu item I can assign a class etc to it (hover, select, active).
Having the entire source inline seems to be the only way I can change SVG using CSS, such as:
<style>
li.active svg polygon {
fill: red;
}
</style>
The problem is:
Having any significant number of SVG files inline makes code unreadable, and
Doesn't make it easy to maintain the SVG if you reference it elsewhere.
I would much rather make reference to the file src the way you would an IMG (<img src="x.jpg"/>) and avoid a Javascript dependent solution.
However all the ways I've seen don't allow for CSS styling of the SVG element (or require JS).
Any thoughts/workarounds?
Probably not the most elegant solution, but you could organize them into php includes:
<?php include 'inc/svg-menu-home.svg.php'; ?>
I think is not a bad way to have a look over http://raphaeljs.com/ . It helped me to create this http://screencast.com/t/rNr0Cbqkb ( every area is a svg )