If I have the following SVG image for example:
<svg role="img" viewbox="0 0 100 50" height="100px">
<title>Site Logo</title>
<rect x="0" y="00" width="100" height="10" fill="red"></rect>
<rect x="0" y="10" width="100" height="10" fill="salmon"></rect>
<rect x="0" y="20" width="100" height="10" fill="pink"></rect>
<rect x="0" y="30" width="100" height="10" fill="aqua"></rect>
<rect x="0" y="40" width="100" height="10" fill="blue"></rect>
</svg>
I should be hitting a11y svg guidelines by setting role=img and including a <title> element
However, when I run the Accessibility Audit in Firefox, it adds a warning for every element/graphic inside the SVG (path, rect, circ) with the following warning:
Content with images must be labeled. Learn more
But surely I don't need to mark up every individual path within the svg?
What should I do to improve a11y or indicate to FF what the correct alt text is?
Here's a demo page in fiddle that will reproduce this issue
I found that including a <title>Image title</title> tag within the <svg role="img"></svg> tags led FireFox to stop showing the error. Note the inclusion of the role attribute on the svg tag (as noted in an earlier comment), along with any other attributes you may need for the opening tag.
According to MDN Web Docs:
The element provides an accessible, short-text description of
any SVG container element or graphics element.
So, like an alt tag for an <img> element. It sounds like a <desc> tag could be used for additional descriptive information.
I am pretty sure this is a bug, or design flaw in FF's accessibility tool. I have reported it here.
Remember that automated accessibility audits can not catch every issue, and often report false positives. Try installing (e.g.) the WAVE accessibility add-on, which is another automatic accessibility auditor. It makes no such complaint.
w3 says
An img represents a single graphic within a document, whether or not
it is formed by a collection of drawing objects.
So you are right that role="img" on the SVG root should do The Right Thing. The accessibility API will not try to expose the children, but Firefox's current beta version of the accessibility tool obviously does.
I tried your code (wrapped in a bare bones HTML doc) with a screen reader (NVDA) and it didn't try to announce the rects, which is what I would expect. It did announce the accessible name. Actually it announces it twice (which is a known NVDA bug at time of writing).
I also tried putting a <g role="presentation"> element around the contents of the svg, but the accessibility tool still flagged warnings on all the children. This shouldn't be necessary.
So, I think you're good.
Elements with img role have the children presentational property set to true. So rect elements can't have an alternative name.
It's likely due to a bug in this Firefox plugin.
Note that (curiously?) the Accessible Name and Description guidelines state that the name can be:
generated from [...] a host language labeling mechanism, such as the alt or title attribute in HTML, or the desc element in SVG.
So according to this statement you should use the desc element. I'm not sure if it's an error in the documentation as the title element seems to be a more suitable choice.
This might come in late, but it helps all the time.
Since the svg does not have text, including aria-label="descriptive text here" and alt="svg description here" should help with the text label checks.
However, if the svg is just for presentational purpose, using empty alt helps out as well. This is to make screen readers recognise the svg, but will not describe the image (instead they'd just say "image", or similar).
Related
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.
I have a star rating component that currently has the following semantic. The SVG are just stars.
<div role='img' aria-label="6 out of 6 ratings">
<svg role="presentation"></svg>
<svg role="presentation"></svg>
<svg role="presentation"></svg>
<svg role="presentation"></svg>
<svg role="presentation"></svg>
<svg role="presentation"></svg>
</div>
I have used the role='img' aria role as I want to ideal treat this image as one image. I have then used the role='presentation' aria role on the SVG as I think the SVG's alone provide no extra information so want to remove the semantic meaning to the SVG and it's children. I read about the presentation role here.
I read a article on SVG accessibility and they go with slightly difference approach. The example they give is the following:
<body>
...
<svg xmlns=http://www.w3.org/2000/svg role="img" aria-labelledby="title desc">
<title id="title">Circle</title>
<desc id="desc">Large red circle with a black border</desc>
<circle role="presentation" cy="60" r="55" stroke="black" stroke-width="2"
fill="red" />
</svg>
…
</body>
They use role='img on the svg. I believe this does not apply to my situation and would be better for me to keep role='presentation' on my SVG?
They use title and desc. I believe that as a single star SVG it would not provide any extra benefit to the user? Also hovering over the SVG would reveal the title (and desc?) which I do not want.
Coming back to my example of how I currently have it:
Is there anything I can do to improve the accessibility/ semantic design to make it more user friendly?
Have I correctly used the right aria role for the container and the SVG?
Should I be able to tab through my rating image (as a whole) as for the aria-label to be read out?
Are there any other aria attributes I should be using?
Looking at the example on semantic-ui, they have no aria roles from what I can see.
The MDN Web docs for img role has a link to a star rating role="img" example
They use aria-hidden instead of role="presentation"
According to the specs, the img role should already make its children presentational
I would add that being accessible implies more than just being accessible for screenreaders. For instance "3 blacks stars, 2 white stars" in the MDN example is something people may not understand (eg. people naturally reading from right-to-left).
"Grandma: Honey, Is it better to have 5 white stars, or 5 black stars?"
I would say that adding "Note: 3/5" next to the ratings, might be a good help.
I have an SVG file that I am applying CSS to. Most rules seem to work, but when I apply rules about the rounding of corners (rx:5; ry:5) it has no effect. 'Inline' style rules work, but I'm having no luck with embedded and external style sheets:
<svg ...>
<defs>
<style type="text/css" >
<![CDATA[
rect{ rx:5; ry:5; }
]]>
</style>
</defs>
<rect
height="170" width="70" id="rect7"
x="0" y="0" />
</svg>
Any idea where I am going wrong?
rx and ry are regular attributes rather than presentation attributes. Only presentation attributes can be styled by CSS. The various regular/presentation attributes are listed here
See also Presentation Attribute and Property from the SVG 1.1 specification.
The upcoming SVG 2 specification proposes that most presentation attributes become CSS properties. So far Chrome and Firefox have implemented this part of the draft specification. I imagine other UAs will implement this in due course.
Scripting can't be simpler, why not to use it:
yourRect.setAttributeNS(null, "rx", "5");
yourRect.setAttributeNS(null, "ry", "5");
I stumbled upon a problem.
I am using Chrome 34.0.1847.116 m - latest verstion.
The <use> seems to work OK on <circle> but not on <foreignObject> tag.
<svg height="400" width="400">
<foreignObject id="first" x="120" y="120" width="180" height="180">
<div xmlns="http://www.w3.org/1999/xhtml" style="height: 800px">
<ul>
<li><strong>First</strong> item</li>
<li>
<em>Second</em> item
</li>
<li>Thrid item</li>
</ul>
</div>
</foreignObject>
<!--<circle id="first" cx="150" cy="50" r="100" fill="lime" />-->
<polygon id="second" class="poly-in" points="300,200 200,300 100,200 200,0" style="fill:blue;stroke:purple;stroke-width:1" />
<use id="use-first" xlink:href="#first" href="#first" />
Sorry, your browser does not support inline SVG.
</svg>
This doesn't work (bug) ...
But, I can get <use> to work when referencing a <circle>
And, I can get <foreignObject> to work when not referenced by a <use>
I am very confused and don't know if I am misunderstanding something or is it a bug. I've been reading w3c paper on SVG and cannot figure it out.
I am looking identical behaviour than in example 2 but for the code posted here with <foreignObject>.
The "unexpected behaviour" is actually an expected -- if not very well documented -- limitation of the <use> element.
The W3 specs you linked to only allow to reference , or a graphics element -- a <foreignObject> tag is not a valid reference for <use>.
You could technically get around the specs by referencing a <g> or <svg> tag which then contains the <foreignObject> as a child. However, most browsers don't support foreign objects in a <use> element however it is worded.
Although your example of a bulleted list is harmless, there would be serious implementation difficulties from supporting arbitrary copies of any and all HTML, especially when you factor in the way style properties are supposed to be inherited from the <use> element. See this thread on the W3 SVG mailing list for more discussion (use the "next in thread" link to read all the responses).
Browsers currently have enough problems with interactive graphics properties and <use> elements, I would not expect to see an extension of <use> to foreign objects any time soon (although hopefully SVG2 will have clearer language indicating that it isn't possible).
Working around the issue will really depend on the specifics of what you're trying to do. #gilly3 made some suggestions. You may need to resort to Javascript if you want to copy a large chunk of HTML for use in multiple contexts.
If you wrap your <foreignObject> in a <switch> and add a corresponding fallback element (such as <text>) you can reference the <switch> from the <use> and the fallback element will display. Obviously, this is less than ideal. And it doesn't work in FireFox or IE.
http://jsfiddle.net/Uz6XZ/4/
As an alternative, if your goal is just to bring the <foreignObject> to the front, I've found you can do so by specifying position: relative on the <div>. That's a bit of a hack and only works in Chrome, not FireFox or IE.
http://jsfiddle.net/Uz6XZ/3/
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.