I'm trying to develop an accessible Bar Chart. As there is no formal ARIA role for graphics just yet, I decided to add role="grid" to my SVG. Most of the stuff is working OK, but the gridcell is always blank when I test my chart using Voice Over.
This is the codepen that illustrates my graph. And this is a video of my testing using Voice Over.
This is how I've configured the gridcell for my rect tag:
<g className={barClass} role="gridcell" aria-label={bar.count + ' ' + bar.fruit}>
<rect width={bar.count * 10} height="19" y={20 * index}/>
</g>
Question: Am I doing something wrong? Why voiceover does not recognize the aria label?
UPDATE 1: I'm using Chrome and Safari and the issue is present in both browsers.
Use the <title> and <desc> elements with the aria-label attribute and the img role as a fallback:
<?xml version="1.0"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 20000802//EN"
"http://www.w3.org/TR/2000/CR-SVG-20000802/DTD/svg-20000802.dtd">
<svg width="6in" height="4.5in" viewBox="0 0 600 450">
<title>Network</title>
<desc>An example of a computer network based on a hub</desc>
<!-- add graphic content here, and so on for the other components-->
</g>
<g id="ComputerA" aria-label="computer A: A common desktop PC" role="img">
<title>Computer A</title>
<desc>A common desktop PC</desc>
</g>
<g id="ComputerB">
<title>Computer B</title>
<desc>A common desktop PC</desc>
</g>
<g id="CableA" aria-label="Cable A: 10BaseT twisted pair cables" role="img">
<title>Cable A</title>
<desc>10BaseT twisted pair cable</desc>
</g>
<g id="CableB">
<title>Cable B</title>
<desc>10BaseT twisted pair cable</desc>
</g>
<g id="CableN">
<title>Cable N</title>
<desc>10BaseT twisted pair cable</desc>
</g>
</svg>
The simplest way to specify a text equivalent for an SVG graphic is to include the following elements in any SVG container or graphics element:
title
Provides a human-readable title for the element that contains it. The title element may be rendered by a graphical user agent as a tooltip. It may be rendered as speech by a speech synthesizer.
desc
Provides a longer more complete description of an element that contains it. Authors should provide descriptions for complex or other content that has functional meaning.
References
SVG Accessibility
SVG Accessibility Testing: Test Assertions with Tables
Tips for Creating Accessible SVG
Using ARIA to enhance SVG accessibility
Accessible SVGs
Just how accessible is SVG?
Current State of Authoring Accessible SVG
Inline SVG used for buttons and links
Text Links: Best Practices for Screen Readers
Accessibility: recommended alt-text convention for SVG and MathML?
Related
I am using the Chartist library in AngularJS in order to create a dynamic chart in an application thatI am making. My goal is to change the css of the bars within the graph but I am not sure how.
When I inspect the HTML of the graph in the application, I see the following code:
< svg xmlns:ct="http://gionkunz.github.com/chartist-js/ct" width="100%" height="80" class="ct-chart-bar" style="width: 100%; height: 80;">
<g class="ct-grids"></g>
<g>
<g class="ct-series ct-series-a">
<line x1="22.5" x2="22.5" y1="45" y2="45" class="ct-bar" ct:value="0">
</line>
</g>
</g>
<g class="ct-labels"></g>
</svg>
I have found that in order to manipulate the bar graph that I need, I can change the x1/x2 and y1/y2 coordinates in the code above.
I have checked in my .html, .scss, and .ts pages but am not able to find any elements that look like they can be manipulated in order to make this change. Where would you go to manipulate these elements? Any help would be greatly appreciated.
I would like to do "complex" animation with gsap and svgs.
but I don't know what is the best approach to this.
it is better to create and to import an unique svg with all the elements or maybe it is better 4 different svgs?
I have 4 different characters: a tree, a lamp, a desk and a man.
basically my animation is move the objects on the x, and appearing and to disappearing stuff.
If the elements of the animation are part of one complex animation, you can use one single SVG for this.
To control the DOM of the SVG via CSS and JavaScript you need to add the SVG directly inline into your HTML page. Not embed via img tag or object tag or similar.
<body>
<h1>My SVG Animation</h1>
<svg width="100" height="100" viewBox="0 0 300 100">
<circle class="animation-element-01" cx="50" cy="50" r="40"/>
<rect class="animation-element-01" x="150" y="20" width="150" height="150"/>
<!-- etc -->
</svg>
</body>
Another advantage of this method is, that there is no additional html requests.
Plus the whole animation can be made responsive via the viewBox.
The idea is pretty simple:
I have an SVG path and an Rect,
I need to make the path carve through the Rect, the resulting "hole" should be see-through.
Here's jsfiddle with a copy of how it's looking right now:
https://jsfiddle.net/9u0jyhr7/embedded/result/
current HTML example:
<div id="container">
<svg id="theSVG" xmlns="http://www.w3.org/2000/svg" version="1.1" width="100%" height="100%" xmlns:xlink="http://www.w3.org/1999/xlink">
<rect id="theRect" width="100%" height="100%" fill="#ffffff"></rect>
<path id="thePath" d="M7 25.69305419921875L7 25.6875L7.00505256652832 25.6875L293.9971923828125 25.6875L294 25.6875L294 25.709388732910156L294 90.67454528808594L294 90.6875L294.0021667480469 90.6875L321.85845947265625 90.6875L321.8607482910156 90.6875L294 183.69180297851562L294 206.421142578125L294 206.42408752441406L294 206.42701721191406L294 228.93441772460938L294 228.936279296875L294 228.93814086914062L294 248.68634033203125L294 248.6875L294.0007629394531 248.6875L304.7754211425781 248.6875L304.7763671875 248.6875L304.7773132324219 248.6875L306.581298828125 248.6875L306.581298828125 248.6875L306.582275390625 248.6875L306.582275390625 248.6875L306.583251953125 248.6875L306.583251953125 248.6875L324.73028564453125 248.6875L324.7316589355469 248.6875L324.7330017089844 248.6875L330.1683044433594 248.6875L330.1697998046875 248.6875L330.1712951660156 248.6875L357.22027587890625 248.6875L357.22265625 248.6875L357.2250061035156 248.6875L360.99749755859375 248.6875L361 248.6875L507 172.48577880859375L507 342.3311767578125L507 342.3337097167969L502.9844665527344 341.6875L436.00836181640625 341.6875L436 341.6875L436 341.6893615722656L436 378.0494079589844L436 378.051513671875L436 378.0536193847656L436 406.68511962890625L507 448.48748779296875L507 448.4908447265625L507 578.6819458007812L507 578.6875L506.9949951171875 578.6875L479.0045166015625 578.6875L479 578.6875L289.9993591308594 341.6875L279.00048828125 341.6875L279 341.6875L278.99951171875 341.6875L273.92425537109375 341.6875L273.9237976074219 341.6875L273.92333984375 341.6875L270.4071350097656 341.6875L270.4067077636719 341.6875L270.4062805175781 341.6875L265.60040283203125 341.6875L265.6000061035156 341.6875L265.5995788574219 341.6875L264.8004150390625 341.6875L264.79998779296875 341.6875L264.7995910644531 341.6875L263.8423156738281 341.6875L263.8419189453125 341.6875L263.84149169921875 341.6875L263.2403869628906 341.6875L263.239990234375 341.6875L263.2395935058594 341.6875L253.1584930419922 341.6875L253.15809631347656 341.6875L253.15769958496094 341.6875L251.40040588378906 341.6875L251.39999389648438 341.6875L251.39959716796875 341.6875L245.081787109375 341.6875L245.0813446044922 341.6875L245.08090209960938 341.6875L223.00071716308594 341.6875L223 341.6875L9.995001792907715 578.6875L7.00505256652832 578.6875L7 578.6875L7 578.6819458007812 " fill="#000000"></path>
</svg>
</div>
Here's an image of what it would probably look like if we can carve that hole:
http://i.stack.imgur.com/5fjBR.png
The Path is dynamically generated and can be quite complex, so I can't really eyeball the result.
It has to be done in javascript (or with some very clever usage of styles).
I need the result to be a DOM node that I can eventually move between z-indexes (could be grouped? a resulting "difference" path calculated in js?).
Performance and experimental features are not an issue, this is aimed at nwjs app.
Some other notes:
I'm already using jQuery, svg.js and a bunch of other libraries, so adding
new libraries is not a problem.
The rect could also be replaced by just a color filled div, if that helps solve the problem.
Ive already tried masks and clips but couldnt come to a working solution.
Any help appreciated, Thank you in advance.
A mask is what you need. I'm not sure what you tried before, but it should do what you want.
Just create a mask like so:
<defs>
<mask id="theMask">
<rect width="100%" height="100%" fill="white"/>
<path id="thePath" d="..." fill="#000000"></path>
</mask>
</defs>
Either move the original path into the mask, or copy it and hide the original.
Then apply the mask to the rect
#theRect {
mask: url(#theMask);
}
Demo fiddle here
I'm trying to create an SVG-based menu. I'm completely new to SVG, and have been searching for 1.5 days for a simple example of interaction between JS and SVG. My document structure is:
/LOCAL_FOLDER (not on a server yet)
+index.html
/CSS
+global.css
/JS
+navigation.js
/IMAGES
+navigation.svg
I have a simple html body
<body>
<div id="outer-container">
<div id="navigation-container" onclick="javascript:changeColor();" >
<object id="navigation" type="image/svg+xml" data="images/test.svg" >Your browser does not support SVG</object>
</div>
</div>
</body>
My SVG looks like this (for now)
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<circle id="test" cx="100" cy="50" r="40" stroke="black" stroke-width="2" fill="red"/>
</svg>
This is the general structure I want to use. As you can see, it has JS from the html head (linked) interacting with my SVG #test. For now, I'd deal with having it change opacity on load just so I can start figuring out HOW to interact.
I've tried JQuerySVG, Raphael, straight JS, JS within SVG, etc, and I can't seem to connect. What I'm looking for (and can't seem to find an operational snippet of) is a super basic example that I can then learn from...
From what I've tried, I rarely had success using data="", however using something like container.load(your.svg), I could then modify to my hearts content.
another issue is to make sure that the svg data was standard.
from there (I used jQuery) jQuery('#test').attr('style','stroke:#ff0000') should change the stroke to red.
How would I modify an SVG file after it has been loaded by the browser, preferably through jquery? A simple example would be pressing a button and the color of the SVG element changes. Any documentation would help as well.
EDIT: This link helped a great deal:
w3.org/Graphics/SVG/IG/resources/svgprimer.html#SVG_in_HTML
You can't "modify" SVG files (except by changing them on the server). SVG files define a collection of SVG objects, each of which can be identified with an ID, if you wish. These objects can be manipulated with JavaScript like you would any DOM element (e.g. setAttribute, etc). Check http://www.w3.org/TR/SVG11/types.html#BasicDOMInterfaces for the DOM interfaces. Notice that SVGElement extends Element, which is the basic DOM element type.
EDIT: simple example:
<html>
<body>
<input type="button" onclick="doSVGThing()" value="change">
<svg xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink">
<rect id="aRect" x="10" y="10" height="100" width="100"
style="stroke:#ff0000; fill: #9999ff"></rect>
</svg>
<script type="text/javascript">
function doSVGThing() {
var r = document.getElementById('aRect');
r.setAttribute('style', 'stroke: #00ff00; fill: #99ff99');
}
</script>
</body>
</html>