I'm not a fan of using images for site logos, I prefer using text with a designed font style... Since they are just text, browsers and crawlers might not understand what it stands for and I keep wondering how I can initialize my text-based logo to be recognized by HTML.
So I thought of doing something like this:
<h1 role="logo">Stack Overflow</h1>
But this isn't correct because there is nothing like role=logo in HTML.
How can I do this?
If you want browsers and assistive technologies to interpret something as an image, you can use the ARIA img role. But don't place this on the <h1> element, because the role="img" attribute will replace the semantics of the heading with an image. Instead wrap it in a <span> and place the role attribute on it, in order to preserve the heading. Also, don't forget your aria-label attribute.
Don't do this:
<!-- don't do this -->
<h1 role="img" aria-label="Logo">Logo</h1>
<!-- because it gets interpreted as this -->
<img alt="Logo">
Instead, if you must:
<!-- if you must, do this -->
<h1><span role="img" aria-label="Logo">Logo</span></h1>
<!-- because it gets interpreted as this, preserving the heading -->
<h1><img alt="Logo"></h1>
However, I can't think of any tangible benefits to forcing browsers to see your text logo as an image. You're fine just leaving it as a normal <h1>.
It seems your use case is covered by existing ARIA img role. Quoting the docs:
Any set of content that should be consumed as a single image (which
could include images, video, audio, code snippets, emojis, or other
content) can be identified using role="img".
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.
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.
How can I add accessibility to this
Text:
Buttons and Images and anchors:
<div class="btn-group" role="group">
<button class="btn btn-default">
<img class="profile-img">
<span id="user-name">john</span>
</button>
<button class="btn btn-default">
Log out
<i class="fa fa-sign-out fa-lg"></i>
</button>
</div>
<div>
Change recipient
</div>
Too little information provided. Context needed. That being said:
Add an alt attribute to the <img>,
make sure the link has a valid href,
don't rely on FontAwesome icons to convey critical information,
maybe dump the role attribute as it may not be needed (context necessary to know if needed).
Only you are suited to properly add semantics to your code and content, so we really can't do this for you. But, here are some important things to remember/do/follow:
Your HTML is not event valid, so start by correcting that.
Don't ever use an HTML element because of the way it makes the
visible page look (i.e. using a heading like <h4> to make text
small and bold). CSS should be used for all layout and presentation.
Use the most appropriate HTML elements to convey the semantics of the content you have. For
example, go ahead and use the <table> element if you actually are
trying to display tabular data and use <ul> and <li> to make menus.
Despite the (many) myths, the HTML5 sectioning elements (section,
article, nav, aside) are not recognized by most screen readers. Their use actually makes creating a valid document outline much more difficult.
The proper use of heading (<h1>...<h6>) elements is the best
thing you can do to convey a proper document structure.
Use WAI-ARIA landmark roles where applicable as that has been a
standard for many years and all the major screen readers understand
it.
For images, provide the alt attribute to the <img> tag, which is a description of the image. For example, <img class="profile-img" alt="profile picture">.
For semantics, use <em> instead of <i> and <strong> instead of <b>.
Also, look into ARIA (Accessible Rich Internet Applications). A useful ARIA attribute is the role attribute. It provides extra content about the element's purpose and functionality.
<a href='' itemscope itemtype='http://schema.org/Brand' itemprop='brand'><i class="logo" itemprop='logo'></i></a>
The above class='logo' applies a font to the icon element. Can we apply the 'glyph' defined in the class (e.g., font-family: 'AnyFont'; content: '/e600') as a Microdata Markup DataType "Brand > Logo" to render the Logo in a rich-snippet the same as a image would render in the rich-snippet?
This doesn't seem likely as an image has a URL based src="..." property and a font character does not, none the less I've been researching this I've found no documentation or discussion on this and need to know if the community is aware of a way to make this work if it does't already work. Or do we have to forfeit the many well-known benefits of using an icon-font to display a logo in rich-snippets?
As validation to the common application of microdata to an image and not an font-character we see that this heavily used microdata generator doesn't give us an option to apply microdata to an element with a font applied to it. And based on the 'Brand > Logo' documentation, the only options are ImageObject and URL (which many very well may believe this answers the question (there's bound to be a way to do this without having to go back 4 years and use an image instead of a font)).
You could use a link element (which may be used in the body in HTML5+Microdata) to provide the URL of the logo:
<a itemprop="brand" href="" itemscope itemtype="http://schema.org/Brand">
<span class="logo"></span>
<link itemprop="logo" href="logo.png" />
</a>
(I used span instead of i. And for the record, I don’t agree that it’s a good idea to include a site’s logo via CSS instead of HTML.)
The "h1 tag with an image" debate seems as old as time itself, but with HTML5 explicitly allowing multiple H1 tags as part of its spec, all the previous questions on this subject seem out of date.
As I understand it, the following works perfectly with the HTML OA:
<body>
<header>
<h1>
<a href="http://www.example.com">
<img src="logo.png" alt="Ernie's Restaurant - Great Italian food">
</a>
</h1>
</header>
<nav><!-- the site-wide navigation --></nav>
<article>
<h1>About us</h1>
<p>…</p>
</article>
</body>
But I'm working with an SEO company on a website and they've told me:
"The logo link CAN’T be H1. It doesn’t make sense."
Are they right? Is there something bad about the above document outline? If you can't put the logo in a H1 tag, why do the W3C do it themselves on their website?
These people are supposedly SEO experts, but I just don't understand their complaint. What am I missing?
Most of the time, you'd want to wrap the image in an anchor, which also has a title... See This answer and This answer.
Maybe they were just nervous about the lack of a proper anchor? The img tag is entirely legitimate.
Yes, you can have an img element as content of an h1 element.
Yes, it makes sense to have the img-logo as h1 (in case it belongs to the body sectioning root, like it does in your example).
If your site doesn’t show a separate textual name, you definitely should do this. Otherwise, the document outline could be wrong (if you don’t use sectioning elements wherever needed) or at least the outline would have an unlabeled top-level entry, which is not very user friendly/accessible.
If you have a site logo and a textual site name, it’s discussible: either include the img together with the text in the same h1, or have only one of these elements in h1 (either one is possible) and have the other one as "alternative title", e.g., together in a header element.
For examples, see some of my related answers on SO (1, 2, 3) and Code Review (1, 2, 3).
(Your "SEO expert" is not the only one having a problem with this, as you can see in some of the comments to my linked answers. I have yet to see an argument against it ….)