It is pretty easy to create a pop-up with the "title" attribute in SVG. But how do you achieve the same effect with CSS.
This is for an illustration I'm making for Wikimedia and I strive to have most things other wikipedians would like to correct within an embedded stylesheet, with style properties grouped by real-life subject. Most wikipedia editors are computer illiterates, you can't expected them to hunt through a lot of code to make their modifications and if they have to change anything but simple CSS-values within the code, then you probably get a nasty mess out of it. If I make this to hard for their poor brains, then sooner or later someone will make the file unmaintainable by using Inkscape, Illustrator or some other equally horrible vector editor.
I could use Javascript, but that would make the illustration less accessible and make the code even more confusing for people who need to edit it. Also, some SVG-files using Javascript have been removed from Wikimedia because of that, but I'm not sure if that is an absolute rule.
I just discovered when I validated my file that the title-attribute in SVG is not allowed where I have been using it, but it works with most browsers. According to the standard you should use the title-element, but that doesn't seem to work with any browsers. Also, according to the standard, I could give a title-attribute to a style-element, but that doesn't seem to work with any browser and it would require me to use 180 style-elements instead of just one (the code is generated by a script, so it isn't a problem for me to create them, it is just that it would make the code much larger and harder to understand).
The two "answers" I've gotten thus far have not been for the question I asked, and is not even remotely useful.
I don't care if the image is editable in Inkscape. Inkscape is a good tool for creating bitmap images (even if you have to run them through some other program to get better compression afterwards). Inkscape sucks at creating SVG files (or any vector based image files intended for an audience, the vector based image files Inkscape creates is only really usefull with Inkscape), Inkscape is a really, really, really poor tool to choose for creating SVG images intended as an end product; Sodipodi was a good tool for that, but Inkscape is not Sodipodi, only based on Sodipodi (unfortunatly, the old C-version of Sodipodi don't run well on modern computer systems and the C++ version was never finished). I want to make my image easy to edit with a text editor, so that no Wikipedian is tempted to use Inkscape and make the file unmaintanable (and in the process increase the size from slightly less then 2 MB to more then 60 MB, if you save it in Inkscape as a "standard" SVG image (which not always give a standard complient file), Inkscapes own svg-based file format makes even larger files).
I don't think wikipedia allow javascript within SVG-images, so Javascript is out of the question.
I already know how to create tooltips with javascript and two different methods to create them in SVG (but not in CSS embedded in SVG). The reason, in addition to the one already mentioned in the original question, that I don't want to use SVG code for the tooltips is that no web-browser support the standard, but SVG-viewers do (but not the non-standard tooltips that work with browsers), so someone who would manually make corrections to a tooltip in the file (with a text editor), would have to change the text in two different places, most likely, with time, resulting in different tooltips when viewed in different browsers/viewers.
<title> — the SVG accessible name element. The <title> element provides an accessible, short-text description of any SVG container element or graphics element. Text in a <title> element is not rendered as part of the graphic, but browsers usually display it as a tooltip.
The <title> tag for an SVG should be brief, much like an alt attribute for an image. In the SVG tag, include an aria-labelledby attribute that points to the <title> tag. If there is more than one shape, it can be a good idea to include a title tag for each shape group.
To make a simple tooltip, we'll first create the HTML element that triggers the tooltip when hovered over. We'll create this element as a div and assign it the class hover-text. Next, we'll create the element for the tooltip itself. This will be a span element with the class tooltip-text.
The alt attribute specifies an alternate text for an area, if the image cannot be displayed. The alt attribute provides alternative information for an image if a user for some reason cannot view it (because of slow connection, an error in the src attribute, or if the user uses a screen reader).
I often resort to using the (invalid) title="" attribute on SVG elements as it's so simple and seems to work in most browsers. I understand your requirement is that it is standards compliant and that people can edit the graphic in InkScape transparently and without breaking the tooltips - for this you will have to use some JavaScript. Here's a quick example I hope you'll find helpful, it will attach the mouseover event to each <title> element's immediate parent and load the text content in a tooltip displayed next to the cursor. This while retaining InkScape compatibility and the ability to use InkScape's "Object Properties" dialog box to set the tooltip text.
Given the following example SVG:
<svg xmlns="http://www.w3.org/2000/svg">
<title>Main Title</title>
<g id="group1">
<title>Title One</title>
<circle cx="120" cy="60" r="40" fill="#993333" />
</g>
<g id="group2">
<title>Title Two</title>
<circle cx="60" cy="60" r="40" fill="#339933" />
<g id="group3">
<circle cx="180" cy="60" r="40" fill="#333399" />
<title>Title Three</title>
</g>
</g>
</svg>
First add a dummy tooltip element:
<g id="toolTip" transform="translate(0,0)">
<rect width="150" height="25" />
<text x="5" y="18"> </text>
</g>
Give it some styling:
<style>
g#toolTip {
visibility: hidden;
}
g#toolTip rect {
fill: #FFCC00;
}
g#toolTip text {
font-size: 16px;
}
</style>
Then insert a sprinkling of JS:
<script>
<![CDATA[
var toolTip = document.getElementById('toolTip');
var titles = document.getElementsByTagName('title');
for (var i = 0; i < titles.length; i++) {
titles.item(i).parentNode.addEventListener('mouseover', function(e) {
showTip(this,xy(e));
}, true);
titles.item(i).parentNode.addEventListener('mouseout', function() {
hideTip();
}, true);
}
function showTip(element,pos) {
var text = element.getElementsByTagName('title')[0].childNodes[0].nodeValue;
toolTip.getElementsByTagName('text')[0].childNodes[0].nodeValue = text;
toolTip.setAttribute('transform', 'translate(' + pos + ')');
toolTip.style.visibility = 'visible';
}
function hideTip() {
toolTip.style.visibility = 'hidden';
}
function xy(e) {
if (!e) var e = window.event;
if (e.pageX || e.pageY) {
return [e.pageX,e.pageY]
} else if (e.clientX || e.clientY) {
return [e.clientX + document.body.scrollLeft + document.documentElement.scrollLeft,e.clientY + document.body.scrollTop + document.documentElement.scrollTop];
}
return [0,0]
}
]]>
</script>
Caveats: The JS block needs to go at the bottom of the SVG file - and if you use the XML editor in InkScape (rare) it will mess up the script (this may be solved by moving to an external JS file and adding some DOM ready detection).
The approach also expects that a) all <title> elements should be rendered as tooltips and b) that there is only ever one <title> element per parent (oddly, the SVG spec allows multiple) - here I have hard coded it to simply use the first <title> child element encountered, ignoring any subsequent ones.
Note: the xy(e) function is only needed to get round browser inconsistencies when it comes to reporting the cursor position - you may not need it, or you may prefer to roll your own.
Bonus: This could easily be extended to make use of the <desc> element as well, should you need more elaborate tooltips with longer bits of text.
As far as i can tell you can't. The SVG element seems to behave oddly.
I thought you could apply a similar concept as this using CSS3:
<style type="text/css">
acronym {
position: relative;
}
acronym:after {
content: attr(title);
position: absolute;
position: absolute;
left: 100%;
margin-left: -10px;
top: -0.5em;
z-index: 2;
padding: 0.25em;
width: 200px;
background-color: #f1f1f1;
text-align: center;
display: none;
}
acronym:hover:after {
display: block;
}
</style>
<acronym title="Keep It Simple Stupid"><a href="/">KISS</a></acronym>
But the :after
Selector doesn't seem to work on the SVG element
I think your best bet is a jQuery script which runs on $(document).ready()
and does all the heavy lifting for you.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With