I have a grid of images, which the user can select by clicking anywhere on them, similar to selecting images in a photos app like Google Photos:
Are there any accessibility issues with the following markup / can it be improved in any way?
<label for="image-checkbox-1">
<span class="labelText">Select Image 1</span>
<input type="checkbox" id="image-checkbox-1">
<img src="image.jpg" alt="image description" />
</label>
Note that the text is hidden by CSS using font-size:0, but this is not really part of the question, I'm more concerned with whether or not wrapping an image inside a checkbox label is good practice or not.
That practice should be ok.
As per Accessible Name and Description Computation 1.2, the <label>’s contents become the <input>’s name.
While computing the name
contents of alt attributes get included in the name computation
hidden elements get excluded (the span)
So when focusing your checkbox, a screen reader would announce
image description, checkbox, unchecked
Could you do something better?
Remove your for attribute, as it’s redundant with wrapping the input inside the label
Remove the <span> entirely, as font-size: 0 also hides it from screen readers. So it’s simply hidden from everybody
Provide width and height attributes for the images, so that the browser can reserve the correct space while images are still being loaded
<label>
<input type="checkbox">
<img src="image.jpg" alt="image description" width="100" height="200" />
</label>
If you do want to provide extra text for assistive technology, but not include it in the image alt text, you should use a tested CSS class like visually-hidden.
Related
I am currently studying the web accessibility guidelines that concern HTML5.
Concerning images, I am currently adding images in HTML as follows:
<!-- Normal Images -->
<img src="https://placeholder.pics/svg/300x300" title="Image Placeholder" alt="Image Placeholder" aria-labelledby="Image Placeholder" width="300" height="300">
<!-- Decorative images -->
<img src="https://placeholder.pics/svg/100x100" role="presentation" aria-hidden="true" alt="" width="100" height="100">
Is it recommended by WAI-ARIA to add both aria-labelledby and alt tags together for normal images? or is there something else that I should adopt?
Do I need to add role="presentation", aria-hidden="true", and alt="" to every decorative image? All three of them should go together? or only one of them? (if only one or two of them then which ones?)
Is it a good practice to add both aria-labelledby and alt tags together for normal images? or is there a better practice that I should adopt.
aria-labelledby
No, in fact adding aria-labelledby and alt together will result in some screen readers reading the name twice. Just use an alt attribute, that is what it is there for, it has the widest support (100%) and will do the job just fine.
Also aria-labelledby requires at least one element in the DOM that contains text, you reference it by ID. You can have more than one label too just for reference. It is designed to be used on other elements that can't be labelled using semantic HTML, not really for images (there are always exceptions but they are rare and this is general guidance).
e.g.
<span id="ID1">Read First</span>
<span id="ID2">You can add a second label that will be read second</span>
<div aria-labelledby="ID1 ID2"></div>
title attribute
Also don't use a title attribute unless you are planning on making it the same as the alt attribute. Otherwise mouse users get a different experience to screen reader users as the title attribute is not accessible to most screen readers. See this in-depth answer I gave about the title attribute and how to roll an accessible version if you want to use it.
accessible image example
So your final, accessible image would look like this:-
<img src="https://placeholder.pics/svg/300x300" alt="Image Placeholder" width="300" height="300">
Perfectly accessible and easy to maintain.
Do I need to add role="presentation", aria-hidden="true", and alt="" to every decorative image? All three of them should go together? or only one of them? (if only one or two of them then which ones?)
alt attribute
All you need to do is add an empty alt attribute. Notice how I said empty and not null.
e.g. alt="" NOT just alt. Using alt as a null attribute will result in it being ignored by some screen readers so the file name will get read out.
role="presentation"
For completeness you can add role="presentation" but it will not add any extra support as far as I am aware.
With that being said I personally add role="presentation" to decorative images as our unit testing will flag any empty alt attributes unless this is added. This was a deliberate decision so when we run tests we don't keep checking the same empty alt attributes are correct.
As support for empty alt attributes is also at 99/100% it is also perfectly valid and accessible to just use alt="".
aria-hidden
The only place (well the main time, there are always exceptions) where you would want to use aria-hidden on an external image is if you are going to dynamically hide and show it. Some screen readers monitor WAI-ARIA changes better than DOM changes.
aria-hidden and inline SVGs
I would recommend adding aria-hidden="true", role="presentation" and focusable="false" on inline SVGs that are purely decorative though as Internet Explorer can sometimes allow them to be focused.
Note that you don't use alt attributes on inline SVGs anyway.
decorative images examples
So your final decorative image would be:-
<!--all image types loaded externally using `img` including SVGs-->
<img src="https://placeholder.pics/svg/100x100" alt="" width="100" height="100">
<!--exception for inline SVGs due to focus bug in IE-->
<svg aria-hidden="true" role="presentation" focusable="false">...</svg>
final note on WAI-ARIA
WAI-ARIA is there to provide information when there is no semantic way to do so.
Adding extra WAI-ARIA all over actually makes accessibility worse. You should always start with 'is there a native way to give the information to a screen reader', if there is, WAI-ARIA is not needed or in fact recommended.
After Thought
I mentioned inline SVGs not using the alt attribute, instead you want to use <title> as part of the SVG. Read this quick article on accessible SVGs for a quick overview.
The image inside this anchor tag throws a "Linked image missing alternative text" error in the WAVE accessibility checker:
<img src="google.jpg" alt="" />
You can't have a decorative image being the sole element of a link. This image is a link, it's not decorative.
<img src="google.jpg" alt="" />
When an image is the only content inside the link, its alternative should contain the link destination description.
In other cases, adding the role="presentation" would have been sufficient to explicitely state that you willingly wanted a decorative image which is not the case here.
Support for the title attribute in screen readers and other assistive technologies is extremely limited; it is also useless for sighted keyboard users.
See for example,
Don't Rely on the Title Attribute for Accessibility (2016)
Using the HTML title attribute – updated (2013)
If a link contains only an image and no text, the content of the alt attribute constitutes link's "link text", i.e. this is what a screen reader will announce when the link receives focus. For this reason, the alt attribute cannot be empty in this case. You need something like the following:
<img src="google.jpg" alt="Google" />
If you include actual text next to the image, as in the following example, you can leave the alt attribute empty:
<img src="google.jpg" alt="" />Google
In the last example, the image can be treated as a decorative one, due to the presence of proper link text. If the string Google were included in the alt attribute, it would be announced twice by a screen reader.
Adding a title attribute to the link is not a great idea for the following reasons:
It is useless to sighted keyboard users who cannot hover the mouse pointer over the link.
Screen reader support for the title attribute is not entirely consistent, as can be seen from the test results A "click here" link with TITLE attribute: Screen reader compatibility (last updated in April 2019). Adding the attribute title="google link" to the above examples would just lead to needless repetition in those screen reader and browser combinations that actually support that attribute on links.
Trying to figure out why a Lighthouse audit flagged a bunch of my links as failing the elements have discernible names
<h3>
My New Post Title
</h3>
My question is do all links need aria-labels because I thought if it's just a normal link the text inside the link is what is required?
Or is there something else going on with the structure of my markup? Another flagged element is this one:
<a class="custom classes" href="https://...">
<div class="custom classes" style="background-image: url('https://...');"></div>
<div class="article-thumbnails-small__title">Post Title</div>
</a>
For that one I understand that the a has no text so the aria-label should go on the div with the actual post title, correct?
SOLVED
I was looking at the wrong element... Have a nice day.
Both of your examples are fine and should not be flagged. Something else must be going on. Is the code you posted exactly what was being tested?
ARIA attributes should be used sparingly and are only meant to be used when native markup isn't sufficient. For links, as you said, if there's any text between the <a>...</a>, then that's "discernible text".
If the link doesn't have any direct text but if a child element does, then you're also ok, such as your second example. The <a> doesn't have text but the second <div> has "Post Title". All the child elements of the <a> are considered when looking for the "discernible text". When I tab to that link, I'll hear "Post Title, link" from a screen reader.
However, CSS can affect this. If your class="article-thumbnails-small__title" on the second <div> has a display:none or visibility:hidden, then that text will not be discernible because it's hidden.
If the class has width/height:0px, then it might not be discernible either. Sometimes 0 sized elements are considered hidden.
If your link does not have text but has a nested <img>, as long as the image has alt text, then you're ok.
Good:
<a href="foo.html">
<img src="foo.jpg" alt="foo">
</a>
No Discernible Text:
<a href="foo.html">
<img src="foo.jpg">
</a>
The aria-label attribute on links (a elements with a href attribute) should only be used when, for whatever reason, it is not possible or not desirable to use perceivable link text. (This includes the alt attribute in image links.) If you have normal link text, you should not use the aria-label attribute because that attribute would override the link text. See step F of the text alternative computation in the document Accessible Name and Description Computation 1.1: the a element has an inherent role that allows the computation of its name from its content (i.e. the link text and/or the alt attribute on an img in the link). However, this step is only followed if there is no aria-label attribute on the link element (see step C.
See also Principle 2: ARIA Can Both Cloak and Enhance, Creating Both Power and Danger in the WAI-ARIA Authoring Practices 1.1, which points out that ARIA sometimes overrides the original semantics or content, citing aria-label as an example.
So if Lighthouse flags links with perceivable link text and no aria-label attribute, there must be something else going on, such as CSS that hides elements.
I'm trying to find the semantically correct way to describe an HTML element that represent a way to get help (e.g. help icon) and its help content.
I tried to search on this topics but searching help on help isn't an easy business. Here would be a simple example of what I have in mind (using a simple script to show/hide the help content as well as leveraging the "title" attribute):
<div>
Please enter your password
<a class="help" title="Your password must have 5 characters">
<img src="/images/help.svg" alt="">
</a>
<span class="helpText displayNone">
Your password must have 5 characters.
</span>
<input type="password>
</div>
Is there a better way to represent this (in this format). The idea is to have an accessible and SEO friendly way to describe "toggleable help content".
The question is about HTML/HTML5 and WAI-ARIA attributes (not JavaScript) - I'm looking for the best element representation of my example (if such concept exists).
I think this question is larger than you intend based on your markup. First let's clean up your example so there are appropriate semantic and structural elements in place that also make this accessible to users:
<div>
<label for="pwd">Please enter your password</label>
<input type="password" id="pwd">
</div>
That makes for an accessible field. No script, no ARIA. Just a <label> that is properly associated with the field.
Now you want to offer some help to the user and still associate it with the field.
First, do not use an anchor. That tells users of assistive technology that it will take them away from the page and they may not want to click or activate the control. Use <button>.
Then you can use ARIA to associate that tip with the field. In this case aria-describedby will be announced along with the field.
You also need to fill out the alt attribute, or your image will not be announced to a screen reader user at all.
The best ARIA role to use in this context is the role=tooltip (read more in the ARIA spec).
Here is one way you could approach it:
<div>
<label for="pwd">Please enter your password</label>
<button><img src="/images/help.svg" alt="Help"></button>
<span id="pwd-tip" role="tooltip">Your password must have 5 characters.</span>
<input type="password" id="pwd" aria-describedby="pwd-tip">
</div>
You can use CSS to determine if the button has focus and display the following sibling span (button:focus + span) if you must avoid script, but that is sloppy. You can use script to toggle a class on the button which uses similar CSS to then display the span.
You can put the text into the <label> and hide it by using a CSS off-screen technique, meaning it will always be announced to screen readers and then you can dump the aria-describedby.
Frankly, you can skin this a few different ways. Check out the keyboard interactions you must consider also over at the ARIA Practices description for a tooltip.
However, for the most part you are better off making your help text always visible (especially if you want to satisfy the nebulous notion of SEO). In a vacuum I would just put this text in the <label> and be done with it.
$<input id="" name="" value="V" type="radio"><img id="" src=".../image.gif" alt="" border="0"><input id="" name="" value="V" type="radio"><img id="" src=".../image.gif" alt="" border="0"><input id="" name="" value="V" type="radio"><img id="" src=".../image.gif" alt="" border="0">
$<div class="wrapper">
As you see here i have like 3 lines or more in a php file and when i open it with any browser it shows me 2 on the same line and the last one under'em so how to keep these three pics on the same line .. is this have a relation with the page size ? if bigger it will show them on the same line ? is this true ?
Thanks for reply :)
Apologies in advance if I'm misinterpreting what you're asking, but if you want to display the three images in one line, you can use CSS. In each of your image tags, you can add inline styling by adding the "style" attribute:
<img id="" src=".../image.gif" alt="" style="display: inline; border-width: 0px;" />
If you have text-level (inline) content like input elements, img elements, and text in HTML source, they will appear in the same line if the available width permits that and there is nothing that causes a line break (such as <br>).
For usability and accessibility, there should normally be one input item (an input element and associated label) on one line. This is best achieved using HTML tags that cause such rendering, such as wrapping the item in a div element.
But if you wish to put the content on one line, you can wrap it all inside a div element and set white-space: nowrap on it in CSS (or, somewhat more effectively, wrap it all inside the nonstandard but well-supported nobr element). This may then force horizontal scrollbars, if the content does not fit into the available width.