Alt Text for generated SVG - svg

HOW can i add alt text for the following generated SVG ? I have only access to the html. the flowing SVG is in div. This is reading the numbers generated by Js function.
<svg class="barcode" role="img" aria-labelledby="title desc" jsbarcode-format="code39" jsbarcode-value="" jsbarcode-textmargin="0" jsbarcode-width="1" width="116px" height="140px" x="0px" y="0px" viewBox="0 0 116 140" xmlns="http://www.w3.org/2000/svg" version="1.1" style="transform: translate(0,0)"><rect x="0" y="0" width="116" height="140" style="fill:#ffffff;"></rect><g transform="translate(10, 10)" style="fill:#000000;"><rect x="0" y="0" width="1" height="100"></rect><rect x="4" y="0" width="1" height="100"></rect><rect x="6" y="0" width="3" height="100"></rect><rect x="10" y="0" width="3" height="100"></rect><rect x="14" y="0" width="1" height="100"></rect><rect x="16" y="0" width="1" height="100"></rect><rect x="18" y="0" width="1" height="100"></rect><rect x="20" y="0" width="3" height="100"></rect><rect x="24" y="0" width="1" height="100"></rect><rect x="28" y="0" width="3" height="100"></rect><rect x="32" y="0" width="3" height="100"></rect><rect x="38" y="0" width="1" height="100"></rect><rect x="40" y="0" width="1" height="100"></rect><rect x="42" y="0" width="1" height="100"></rect><rect x="44" y="0" width="3" height="100"></rect><rect x="48" y="0" width="1" height="100"></rect><rect x="50" y="0" width="3" height="100"></rect><rect x="54" y="0" width="1" height="100"></rect><rect x="56" y="0" width="1" height="100"></rect><rect x="60" y="0" width="3" height="100"></rect><rect x="64" y="0" width="1" height="100"></rect><rect x="66" y="0" width="3" height="100"></rect><rect x="70" y="0" width="1" height="100"></rect><rect x="72" y="0" width="1" height="100"></rect><rect x="76" y="0" width="3" height="100"></rect><rect x="80" y="0" width="1" height="100"></rect><rect x="84" y="0" width="1" height="100"></rect><rect x="86" y="0" width="3" height="100"></rect><rect x="90" y="0" width="3" height="100"></rect><rect x="94" y="0" width="1" height="100"></rect><text style="font: 20px monospace" text-anchor="middle" x="48" y="120">NULL</text></g></svg>

If you don't have any ability to change the <svg> element itself, the easiest approach is to wrap it in a DIV with the ARIA img role, and use aria-label to provide the text alternative:
<div class="svg-wrapper" role="img" aria-label="A cowboy riding a triceratops">
<svg role="img" aria-labelledby="title desc" ... >
<rect x="0" y="0" width="116" height="140" ... ></rect>
<!-- more SVG elements -->
</svg>
</div>
Semantically, <div role="img" aria-label="foo"> is equivalent to <img src="foo.png" alt="foo">. You can find an example at IMG Tag & ARIA role="img" attribute/value.
Note that the ARIA img role is defined as having "children presentational", which means the browser should not pass the content nested inside the DIV to assistive technology. So the fact that the nested SVG has it's own image role and a broken aria-labelledby attribute shouldn't matter.
If you can control the content of the <svg> element, then this pattern will work:
<div class="svg-wrapper">
<svg role="img" aria-labelledby="unique-id-123" ... >
<title id="unique-id-123">A cowboy riding a triceratops</title>
<rect x="0" y="0" width="116" height="140" ... ></rect>
<!-- more SVG elements -->
</svg>
</div>
Be careful to give the <title> element a unique ID attribute.

Your SVG has an aria-labelledby="title desc" attribute, but there isn't any element with id="title" or id="desc" in the SVG code.
This means that you must define two elements with id="title" and id="desc" in order for your SVG to be accessible.
For instance:
<h2 id="title">My SVG title</h2>
<div id="desc">This is an SVG description</div>
<!-- insert your original svg code after -->

You can only set a role="img" and aria-label="something" to your <svg>.
More info here.

Related

How to include SVG within an SVG document which has JavaScript code?

Please understand this question properly before marking as duplicate.
There are many questions like this one in StackOverflow, but my question is slightly different from those.
I have a chakra.svg file, whose code is this:
<svg xmlns="http://www.w3.org/2000/svg" width="100" height="100" id="b">
<circle cx="50" cy="50" r="45" stroke-width="2" stroke="blue" fill="none"/>
<script>
<![CDATA[
for(i=0;i<24;i++)
{
var l=document.createElementNS("http://www.w3.org/2000/svg","line");
l.setAttributeNS(null,"x1","50");
l.setAttributeNS(null,"y1","50");
l.setAttributeNS(null,"x2","5");
l.setAttributeNS(null,"y2","50");
l.setAttributeNS(null,"stroke-width",2);
l.setAttributeNS(null,"stroke","blue");
l.setAttributeNS(null,"transform","rotate("+(i/24*360)+",50,50)");
document.querySelector("#b").appendChild(l);
}
]]>
</script>
</svg>
The output is rendered as expected, like this:
I have another file, India_flag.svg whose code is this:
<svg xmlns:xlink="http://www.w3.org/1999/xlink" xmlns="http://www.w3.org/2000/svg" width="170" height="100">
<rect x="0" y="0" height="33" width="180" fill="#f93"/>
<rect x="0" y="33" height="34" width="180" fill="white"/>
<rect x="0" y="67" height="33" width="180" fill="green"/>
</svg>
The output of this file is also rendered as expected:
But, now the problem is, when I am trying to insert the chakra.svg file inside the India_flag.svg file using the image tag like this:
<image xlink:href="chakra.svg" x="70" y="35" height="30" width="30"/>
The output should have been that the wheel is placed at the centre of the flag, but I am getting this output:
The chakra.svg file is rendered, but the JavaScript code in that file did not run, only the circle is rendered. What am I doing wrong and how to achieve my objective?
SVG documents when loaded inside an <image> tag (or HTML <img> for that matter) are sand-boxed and won't allow the execution of scripts, nor will they be interactive (i.e no user-event).
To circumvent that, you need an other way to append you svg. The simple solution would be to copy its markup directly in the main one:
<svg xmlns:xlink="http://www.w3.org/1999/xlink" xmlns="http://www.w3.org/2000/svg" width="170" height="100">
<rect x="0" y="0" height="33" width="180" fill="#f93"/>
<rect x="0" y="33" height="34" width="180" fill="white"/>
<rect x="0" y="67" height="33" width="180" fill="green"/>
<svg x="70" y="35" height="30" width="30" id="b" viewBox="0 0 100 100">
<circle cx="50" cy="50" r="45" stroke-width="2" stroke="blue" fill="none"/>
<script>
<![CDATA[
for(i=0;i<24;i++) {
var l=document.createElementNS("http://www.w3.org/2000/svg","line");
l.setAttribute("x1","50");
l.setAttribute("y1","50");
l.setAttribute("x2","5");
l.setAttribute("y2","50");
l.setAttribute("stroke-width",2);
l.setAttribute("stroke","blue");
l.setAttribute("transform","rotate("+(i/24*360)+",50,50)");
document.querySelector("#b").appendChild(l);
}
]]>
</script>
</svg>
</svg>
An other solution, would have been to do the inverse: load your flag image from the one with the script: plnkr.

How to make vertical svg rect height start from the bottom?

Desired behaviour
Make a "bar chart" style icon with vertical bars.
Actual Behaviour
The following displays the desired result if I flip it with scaleY().
/* uncomment below for desired appearance */
/*
svg {
transform: scaleY(-1);
}
*/
<svg style="background: yellow" width="20" height="20" viewbox="0 0 20 20">
<rect x="2" y="0" width="1" height="5" style="fill:rgb(0,0,0)"/>
<rect x="7" y="0" width="1" height="8" style="fill:rgb(0,0,0)"/>
<rect x="12" y="0" width="1" height="15" style="fill:rgb(0,0,0)"/>
<rect x="17" y="0" width="1" height="10" style="fill:rgb(0,0,0)"/>
Sorry, your browser does not support inline SVG.
</svg>
Question
What is the correct way to start the height from the bottom, rather than the top?
SVG's Y axis goes from the top down to the bottom (source)[https://developer.mozilla.org/en-US/docs/Web/SVG/Tutorial/Positions#The_grid].
In order to display the bars from the bottom of the icon, you need to calculate each bar's y coordinate accordingly: iconHeight - barHeight.
Adapted snippet:
/* uncomment below for desired appearance */
/*
svg {
transform: scaleY(-1);
}
*/
<svg style="background: yellow" width="20" height="20" viewbox="0 0 20 20">
<rect x="2" y="15" width="1" height="5" style="fill:rgb(0,0,0)"/>
<rect x="7" y="12" width="1" height="8" style="fill:rgb(0,0,0)"/>
<rect x="12" y="5" width="1" height="15" style="fill:rgb(0,0,0)"/>
<rect x="17" y="10" width="1" height="10" style="fill:rgb(0,0,0)"/>
Sorry, your browser does not support inline SVG.
</svg>

svg groups and fill inheritance

My goal is to have the first group of 3 squares be blue and the next group of 3 squares be red. To minimize code, I want to take advantage of grouping in SVG. All the rectangles remain blue. I have tried inline styling on the second group element and on the use element, but that doesn't solve the problem. Thank you for your assistance.. Here's the code:
<svg width="1000" height="800"
xmlns="http://www.w3.org/2000/svg" version="1.1"
xmlns:xlink="http://www.w3.org/1999/xlink">
<style>
.blue {fill:blue;}
.red {fill:red;}
</style>
<g id="g1" class="blue">
<rect x="0" y="0" width="100" height="100" />
<rect x="0" y="105" width="100" height="100" />
<rect x="0" y="210" width="100" height="100" />
</g>
<g class="red">
<use xlink:href="#g1" transform="translate(0,315)" />
</g>
Here are changes from above that now have it working:
<g class="blue">
<g id="g1">
<rect x="0" y="0" width="100" height="100" />
<rect x="0" y="105" width="100" height="100" />
<rect x="0" y="210" width="100" height="100" />
</g>
</g>
<g class="red" transform="translate(0,315)">
<use xlink:href="#g1" />
<!-- <g id="g1">
<rect x="0" y="0" width="100" height="100" />
<rect x="0" y="105" width="100" height="100" />
<rect x="0" y="210" width="100" height="100" />
</g> -->
</g>
... I commented out some of the old svg as well.
Here's the solution in a clearer form (some of the commented code above, actually came from further experimenting).
<svg width="1000" height="800"
xmlns="http://www.w3.org/2000/svg" version="1.1"
xmlns:xlink="http://www.w3.org/1999/xlink">
<style>
.blue {fill:blue;}
.red {fill:red;}
</style>
<g class="blue">
<g id="g1">
<rect x="0" y="0" width="100" height="100" />
<rect x="0" y="105" width="100" height="100" />
<rect x="0" y="210" width="100" height="100" />
</g>
</g>
<g class="red" transform="translate(0,315)">
<use xlink:href="#g1" />
</g>
Looks like styling needs to be done at a level above a group in my case and that the as Robert pointed out will retrieve the previous group as written.

svg: filtering background image, google chrome

I am struggling with an svg to blur background under text on Google Chrome 36.0.1985.125 linux. The svg is like
<svg width="500px" height="500px" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<defs>
<filter id="myfilter" filterUnits="objectBoundingBox" x="0" y="0" width="100%" height="100%">
<feGaussianBlur result="blurOut" in="BackgroundImage" stdDeviation="2" />
<feBlend in2="blurOut" in="SourceGraphic" mode="normal" />
</filter>
</defs>
<g enable-background="new">
<text x="10" y="100" stroke="none" fill="red" fill-opacity="1" font-size="24">BACKGROUND</text>
<text x="20" y="100" stroke="none" fill="black" fill-opacity="1" font-size="26" filter="url(#myfilter)">text</text>
</g>
</svg>
Fiddle: http://jsfiddle.net/2o2trpc1/
Thus I would like to blur "BACKGROUND" behind "text", but "text" does not appear at all. Can someone please look at this what I am doing wrong? Where can I check that the browser version supports filtering background image?
thanks a lot,
Balazs
You will have to work around the lack of BackgroundImage. There are multiple ways to do that, if your code is as simple as the fiddle you posted something like this could work:
<body>
<svg width="500px" height="500px" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<defs>
<filter id="blur" filterUnits="objectBoundingBox" x="0" y="0" width="100%" height="100%">
<feGaussianBlur result="blurOut" stdDeviation="2" />
</filter>
</defs>
<g>
<text x="10" y="100" stroke="none" fill="red" fill-opacity="1" font-size="24" filter="url(#blur)">BACKGROUND</text>
<text x="20" y="100" stroke="none" fill="black" fill-opacity="1" font-size="26">text</text>
</g>
</svg>
</body>
See fiddle.
Another option is to use <feImage xlink:href="#background"/> in the filter, instead of using BackgroundImage. This can bring in whatever element you want.
<body>
<svg width="500px" height="500px" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<defs>
<filter id="myfilter" filterUnits="userSpaceOnUse" x="0" y="0" width="100%" height="100%">
<feImage xlink:href="#background"/>
<feGaussianBlur stdDeviation="3" />
<feBlend in="SourceGraphic" mode="normal" />
</filter>
<text id="background" x="10" y="100" stroke="none" fill="red" fill-opacity="1" font-size="24">BACKGROUND</text>
</defs>
<g>
<text x="20" y="100" stroke="none" fill="black" fill-opacity="1" font-size="26" filter="url(#myfilter)">text</text>
</g>
</svg>
</body>
See fiddle.

How to place <rect>s side-by-side?

I want to place filled squares in SVG next to each other, but there are thin lines between them. How to eliminate these lines?
Example:
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="3cm" height="3cm" viewBox="0 0 10 10">
<rect x="0" y="0" width="1" height="1" fill="black" />
<rect x="2" y="0" width="1" height="1" fill="black" />
<rect x="4" y="0" width="1" height="1" fill="black" />
<rect x="6" y="0" width="1" height="1" fill="black" />
<rect x="8" y="0" width="1" height="1" fill="black" />
<rect x="0" y="1" width="1" height="1" fill="black" />
<rect x="2" y="1" width="1" height="1" fill="black" />
<rect x="3" y="1" width="1" height="1" fill="black" />
<rect x="4" y="1" width="1" height="1" fill="black" />
<rect x="5" y="1" width="1" height="1" fill="black" />
<rect x="6" y="1" width="1" height="1" fill="black" />
<rect x="7" y="1" width="1" height="1" fill="black" />
<rect x="9" y="1" width="1" height="1" fill="black" />
<rect x="0" y="2" width="1" height="1" fill="black" />
<rect x="2" y="2" width="1" height="1" fill="black" />
<rect x="8" y="2" width="1" height="1" fill="black" />
<rect x="0" y="3" width="1" height="1" fill="black" />
<rect x="1" y="3" width="1" height="1" fill="black" />
<rect x="3" y="3" width="1" height="1" fill="black" />
<rect x="5" y="3" width="1" height="1" fill="black" />
<rect x="6" y="3" width="1" height="1" fill="black" />
<rect x="8" y="3" width="1" height="1" fill="black" />
<rect x="9" y="3" width="1" height="1" fill="black" />
<rect x="0" y="4" width="1" height="1" fill="black" />
<rect x="1" y="4" width="1" height="1" fill="black" />
<rect x="5" y="4" width="1" height="1" fill="black" />
<rect x="6" y="4" width="1" height="1" fill="black" />
<rect x="8" y="4" width="1" height="1" fill="black" />
<rect x="0" y="5" width="1" height="1" fill="black" />
<rect x="3" y="5" width="1" height="1" fill="black" />
<rect x="4" y="5" width="1" height="1" fill="black" />
<rect x="9" y="5" width="1" height="1" fill="black" />
<rect x="0" y="6" width="1" height="1" fill="black" />
<rect x="5" y="6" width="1" height="1" fill="black" />
<rect x="6" y="6" width="1" height="1" fill="black" />
<rect x="8" y="6" width="1" height="1" fill="black" />
<rect x="0" y="7" width="1" height="1" fill="black" />
<rect x="4" y="7" width="1" height="1" fill="black" />
<rect x="5" y="7" width="1" height="1" fill="black" />
<rect x="6" y="7" width="1" height="1" fill="black" />
<rect x="8" y="7" width="1" height="1" fill="black" />
<rect x="9" y="7" width="1" height="1" fill="black" />
<rect x="0" y="8" width="1" height="1" fill="black" />
<rect x="1" y="8" width="1" height="1" fill="black" />
<rect x="2" y="8" width="1" height="1" fill="black" />
<rect x="7" y="8" width="1" height="1" fill="black" />
<rect x="8" y="8" width="1" height="1" fill="black" />
<rect x="0" y="9" width="1" height="1" fill="black" />
<rect x="1" y="9" width="1" height="1" fill="black" />
<rect x="2" y="9" width="1" height="1" fill="black" />
<rect x="3" y="9" width="1" height="1" fill="black" />
<rect x="4" y="9" width="1" height="1" fill="black" />
<rect x="5" y="9" width="1" height="1" fill="black" />
<rect x="6" y="9" width="1" height="1" fill="black" />
<rect x="7" y="9" width="1" height="1" fill="black" />
<rect x="8" y="9" width="1" height="1" fill="black" />
<rect x="9" y="9" width="1" height="1" fill="black" />
</svg>
My reputation doesn't allow me to post images, but you can look closely at my avatar.
You're seeing antialiasing at work.
Add shape-rendering="crispEdges" to the root <svg> element (or alternatively to each rect) to get the display you want.

Resources