Should aria-label be used to describe user generated content like username links? - accessibility

Let's take an Open Library list page for example. When you visit the page, one of the first things that a user with a screen reader would hear is "link, Mek". Mek is the username. However, in the case of social websites someone could pick any username like "borrow the book" or things that I imagine would be disorienting to people using screen readers.
So, my question is, would it be appropriate to use something like aria-label to say that it is a username since that is not otherwise written on the page? If not, is there another way that people using screen readers deal with this?
I'm new to A11Y and ARIA so maybe I'm looking in the wrong place for answers. I have tried searching this in may ways and read some documents like Using aria-label for link purpose and Using aria-label to provide an invisible label where a visible label cannot be used.
I also looked at the code on social sites such as Twitter, Reddit, and Facebook but as far as I can tell none of do anything special for usernames. Perhaps it is less important for sites that are primarily user generated content.

Linked Example
In the example page you linked those are actually breadcrumbs so technically make sense.
<div class="superNav">
Mek
/
Lists
</div>
With that being said they should be located within an unordered list (as an unordered list is useful for screen reader users to know how many links there are as it will read "1 of 2 option" or similar) and have some form of identification on the <nav> (so it is not considered main navigation):
<nav aria-label="breadcrumbs" class="superNav">
<ul>
<li>
Mek
</li>
<li>
Lists
</li>
<ul>
</nav>
Finally if you have a sophisticated back-end or the first link will always be a link to a user profile then you could add some visually hidden text to the link just for clarity.
HTML
[...]
<ul>
<li>
<span class="visually-hidden">User Profile for </span>Mek
</li>
[...]
CSS
.visually-hidden {
border: 0;
padding: 0;
margin: 0;
position: absolute !important;
height: 1px;
width: 1px;
overflow: hidden;
clip: rect(1px 1px 1px 1px); /* IE6, IE7 - a 0 height clip, off to the bottom right of the visible 1px box */
clip: rect(1px, 1px, 1px, 1px); /*maybe deprecated but we need to support legacy browsers */
clip-path: inset(50%); /*modern browsers, clip-path works inwards from each corner*/
white-space: nowrap; /* added line to stop words getting smushed together (as they go onto seperate lines and some screen readers do not understand line feeds as a space */
}
Social sites
However for social sites there are loads of things you can do.
For example if the image is a link to their profile you can use the alt attribute to indicate the action of the link.
<a class="profile-container"
<img src="profile-image-user-rayb.jpg" alt="RayB profile page" />
</a>
If it is just a static image (and their username is not shown anywhere else) then the alt attribute would change with the context.
<img src="profile-image-user-rayb.jpg" alt="RayB profile picture / avatar" />
If it is a static image and the persons name is located somewhere else within that article / block then you would likely hide the image:
<article>
<h2>Some article Title</h2>
<img src="profile-image-user-rayb.jpg" alt="" role="presentation" aria-hidden="true"/>
<p class="written by">Author: RayB</p>
</article>
** please note:** in the last example an empty alt attribute is sufficient to hide an image from a screen reader. I add role="presentation" and aria-hidden="true" so that I can check for empty alt attributes that are mistakes (e.g. if they do not have aria-hidden="true" then I know they should have an alt attribute filled in).
Why so many variations?
This is where accessibility turns from a set of rules into an art form, you have to pick the best option depending on the circumstances.
A good place to start for alt attributes for example is the alt text decision tree from W3.
Other than that consider things like:
does this add additional information a screen reader user needs?
Is the information available elsewhere / nearby and does this then just duplicate it?
If this is an image in a link does the alt attribute reflect the action of the link in context. etc....
Above all, grab a screen reader and try it, that is without doubt the quickest way to learn (as you can identify an issue / something that confused you / repetition etc. and then it is easy to look for a fix/).
If you need more info just let me know!

Related

Safari voice over not reading aria-label for a span

<span tabIndex='0' aria-label={ariaLabelText} className={classesContainer}>
<span className={classesItem}>{cartItemCount}</span>
</span>
I am trying to read the cart item count
As you will discover from this excellent resource aria-label is not supported on <span> because WAI-ARIA specifies <span> as a 'generic' role, which in turn means that it cannot be named.
You can (of course) override the default role by adding a role attribute which supports naming. Choose wisely. If this is going to be keyboard focusable (which your tabindex value suggests) then you should choose an operable role, such as button or link. Better still, use the HTML5 equivalent : <button> or <a> respectively.
In this particular case, where you simply want to announce the number of items in a cart, I would assume that the 'cart' itself is some kind of button, or perhaps a hyperlink, and the number of items in the cart is a kind of description or annotation for that element.
Your 'cartItemCount' can be included as part of the name, or not as you prefer. In the example below, it is excluded from the name by aria-hidden.
Alternatively, an annotation such as this might call for aria-describedby, so you might do something like this:
<button class="cart" aria-describedby="cartItemCount">
<span class="visibleLabel">{ShoppingCartText}</span>
<span aria-hidden="true" id="cartItemCount" class="items">{cartItemCount}</span>
</button>
In this example, 'cartItemCount' span is excluded from the button's accessible name (using aria-hidden) yet still exposed to assistive technology via aria-describedby.
As a design consideration, the 'description' of aria-describedby is something which assistive tech users might prefer to disable, relying wholly on naming (at least sometimes), so your annotation might not be 'announced' if it is not part of the name.
Screen readers and other ATs will offer different ways of accessing or muting this 'description' value when an element is in focus.
Note: The ARIA annotations spec, not quite final at time of writing is slated for inclusion in WAI-ARIA 1.3. It offers the aria-description attribute (already supported on some browsers) which will allow such state annotations to be added without creating additional elements.
The VoiceOver screen reader on Mac is able to read each element in the page by using Control-Option + left/right/up/down.
Since you are using aria-label then you are simply overwriting any text which would be presented inside the span. So, your span would need to use `aria-label="{ariaLabelText} {cartItemCount}"
However, why not simply add everything as a bit of text inside the span and be done with it?
I suspect you want to display a number, be able to tab to that cart number and when you reach there via VoiceOver you want to be able to reflect some extra bit of text to the screen reader users.
For that you need to do something different:
<button>
<span class="visually-hidden">{cartItemText}</span>
<span class="items">{cartItemCount}</span>
</button>
And below is the CSS for the visually-hidden class:
.visually-hidden {
clip: rect(0 0 0 0);
clip-path: inset(50%);
height: 1px;
overflow: hidden;
position: absolute;
white-space: nowrap;
width: 1px;
}
This way you have interactivity, text displayed in numbers for visual users and also text read out aloud for screen reader users.

How "safe" are Angular 2 custom html tags? (selectors: Custom tags vs. Custom attributes)

This is a question regarding Angular 2 selectors, Custom tags vs. Custom attributes, SEO and browser rendering.
When I first started to look over Angular 2, the very first thing I did when following their quickstart, right of the bat, was to change my selector to '[my-component]' (attribute selector) instead of 'my-component' (tag selector), so I could have <div my-component></div> in my html instead of <my-component></my-component>, which isn't valid html. So I would write html according to standards. Well, at least pretty close to standards (because my-component isn't a valid html attribute, but I could live with only that html validation error)
Then, at some point in a video on youtube, someone from the angular team mentioned that we should use the tag selector, performance wise at least.
Alright I said, screw html validation... or shouldn't I?
So:
Say I ignore the W3C screaming about my html being completely invalid because of the <custom-tags>. I actually have another bigger and more real concern: how does this impact SEO?
I mean don't just think client-side app, because in the real world (and for my angular 2 project as well) I also have server-side rendering, for 2 very important reasons: SEO and Fast initial rendering of the site to the user for that initial view, before the app bootstraps. You can not have a very high traffic SPA otherwise.
Sure, google will crawl my site, regardless of the tags I use, but will it rank it the same in both scenarios: one with <custom-make-believe-tags> and the other with only standard html tags?
Let's talk browsers and css:
As I started to build my first SPA site in Angular 2, I was immediately faced with another concern:
Say (in a non SPA site) I have the following html markup:
<header>
<a class="logo">
...
</a>
<div class="widgets">
<form class="frm-quicksearch"> ... </form>
<div class="dropdown">
<!-- a user dropdown menu here -->
</div>
</div>
</header>
<div class="video-listing">
<div class="video-item"> ... </div>
<div class="video-item"> ... </div>
...
</div>
Angular 2 wise I would have the following component tree:
<header-component>
<logo-component></logo-component>
<widgets-component>
<quicksearch-component></quicksearch-component>
<dropdown-component></dropdown-component>
</widgets-component>
</header-component>
<video-listing-component>
<video-item-component></video-item-component>
...
</video-listing-component>
Now, I have 2 options. Let's just take the <video-listing-component> for example, to keep this simple... I either
A) place the entire standard html tags which I already have (<div class="video-item"></div>) within the <video-item-component> tag, and once rendered will result in this:
<video-listing-component>
<div class="video-listing>
<video-item-component>
<div class="video-item>...</div>
</video-item-component>
...
...
</div>
</video-listing-component>
OR:
B) Only put the content of <div class="video-item"> directly into my <video-item-component> component and adding the required class (class="video-item") for styling on the component tag, resulting in something like this:
<video-listing-component class="video-listing">
<video-item-component class="video-item"></video-item-component>
<video-item-component class="video-item"></video-item-component>
...
</video-listing-component>
Either way (A or B), the browser renders everything just fine.
BUT if you take a closer look (after everything is rendered in the dom, of course), by default the custom tags don't occupy any space in the dom. They're 0px by 0px. Only their content occupies space. I don't get it how come the browser still renders everything as you would want to see it, I mean in the first case (A):
While having float: left; width: 25%; on the div class="video-item", but each of these divs being within a <video-item-component> tag, which doesn't have any styling... Isn't it just a fortunate side-effect that the browser renders everything as you'd expect? With all the <div class="video-item"> floating next to eachother, even though each of them are within another tag, the <video-item-component> which does NOT have float: left? I've tested on IE10+, Firefox, Chrome, all fine. Is it just fortunate or is there a solid explanation for this and we can safely rely for this kind of markup to be rendered as we'd expect by all (or at least most) browsers?
Second case (B):
If we use classes and styling directly on the custom tags (<video-item-component>)... again, everything shows up fine. But as far as I know, we shouldn't style custom components, right? Isn't this also just a fortunate expected outcome? Or is this fine also? I don't know, maybe I'm still living in 2009... am I?
Which of these 2 approaches (A or B) would be the recommended one? Or are both just fine?
I have no ideea!!
EDIT:
D'oh, thanks Günter Zöchbauer. Yeah, since my divs have float: left, that's why the (custom or not) tag they're wrapped in doesn't expand it's height. Seems I've forgotten how css works since I started to look over Angular 2:)
But one thing still remains:
If I set a percentage width on a block element (call it E), I would assume it takes x% of it's immediate parent. If I set float: left, I would expect floating within the immediate parent. In my A case, since the immediate parent is a custom tag with no display type and no width, I would expect for things to break somehow, but still... my E elements behave like their parent isn't the custom tag they're each wrapped in, but the next one in the dom (which is <div class="video-listing> in my case). And they occupy x% of that and they float within that. I don't expect this to be normal, I would think this is just a fortunate effect, and I'm afraid that one day, after some browser update... I'll wake up to find all my Angular 2 sites looking completely broken.
So... are both A and B an equally proper approach? Or am I doing it wrong in case A?
EDIT2:
Let's simplify things a bit. As I got part of my question answered, let's take another example of generated html (simplified a bit, with inlined css):
<footer>
<angular-component-left>
<div style="float: left; width: 50%;">
DIV CONTENT
</div>
</angular-component-left>
<angular-component-right>
<div style="float: left; width: 50%;">
DIV CONTENT
</div>
</angular-component-right>
</footer>
In the original, not yet implemented html (whithout <angular-component-...>, those divs should float left and each occupy 50% of the <footer>. Surprisingly, once they're wrapped in the <angular-component-...> custom tags, they do the same: occupy 50% of the footer. But this just seems like good fortune to me, dumb luck... Unintended effect.
So, is it or isn't it "dumb luck"?
Should I leave it like that, or rewrite so instead of the above code, I would have something like this:
<footer>
<angular-component-left style="display: block; float: left; width: 50%;">
DIV CONTENT
</angular-component-left>
<angular-component-right style="display: block; float: left; width: 50%;">
DIV CONTENT
</angular-component-right>
</footer>
Note that the inline styling is introduced here for simplicity, I would actually have a class instead which would be in an external css file included in the <head> of my document, not through style or styleUrls from my angular components.
The issue is your HTML validator. The - in the element name is required for elements to be treated as custom elements and it is valid HTML5. Angular doesn't require - in element names but it's good practice.
Check for example https://www.w3.org/TR/custom-elements/#registering-custom-elements (search for x-foo) or https://w3c.github.io/webcomponents/spec/custom/#custom-elements-custom-tag-example. I'm sure this dash rule is specified somewhere but wasn't able to find the spec. It is for example required in Polymer that depends on elements being proper custom elements while this doesn't matter much in Angular. The only difference as far as I know is that when you query the element, you get a HTMLUnknownElement when the - is missing in the name and a HTMLElement when it contains a -.
See also this question I asked a few years ago Why does Angular not need a dash in component name
BUT if you take a closer look, by default the custom tags don't occupy any space in the dom. They're 0px by 0px. Only their content occupies space. I just don't get it how come the browser still renders everything as you would want to see it
I'm not sure I understand this question. When Angular processes the template it adds the content dynamically. When you see the content in the browser than it's also available in the DOM and has actual dimensions.
Search engine crawlers are able to process pages that are generated by JavaScript. If this isn't enough, server-side rendered pages can provide static HTML to crawlers that contain the whole view.

Legitimately hide/prevent Rich Snippet html from rendering on screen - is this OK to do?

I am using rich snippets on my site, I have all of the code for them in the footer so that they are centrally located and easy to access. I do not want the text around these snippets rendered on the page because that info is elsewhere on the site. Is it ok to hide this text by using style="display:none" or will Google ignore the rich snippet entirely because the fields are hidden?
<!-- start rich snippet code -->
<div itemscope itemtype="http://schema.org/LocalBusiness">
<span itemprop="name" style="display:none">My Business Name</span>
<div itemprop="address" itemscope itemtype="http://schema.org/PostalAddress">
<span itemprop="streetAddress" style="display:none">123 Example Street, Suite 456</span>
<span itemprop="addressLocality" style="display:none">Major City</span>
<span itemprop="addressRegion" style="display:none">NY</span>
<span itemprop="postalCode" style="display:none">12345</span>
<span itemprop="addressCountry" style="display:none">US</span>
</div>
<span itemprop="telephone" style="display:none">(123) 456-7890</span>
<a itemprop="URL" style="display:none">http://www.mycompanysite.com/</a>
</div>
<!-- end rich snippet code -->
Any info would be much appreciated! Thanks in advance!
As #Diodeus said, ideally you'd have these rich snippets on the actual info that is shown to the user elsewhere on the site. Duplicating it is usually unnecessary.
Yes, Google may well ignore this content based on the display:nones. Can I ask why you're setting it on each element rather than just once on the highest level div?
A way around the display:none potential SEO issue would be to hide it in a different way. For example give the parent div a class of .visuallyhidden and add this to your stylesheet:
.visuallyhidden {
border: 0;
clip: rect(0 0 0 0);
height: 1px;
margin: -1px;
overflow: hidden;
padding: 0;
position: absolute;
width: 1px;
}
I would like to mention that Google tries heavily (using combination of algorithmic and manual things) to find websites which illegitimately use hidden text.
The typical penalty for that would be a removal from index for 30 days. However, you should not be concerned if you use hidden fields legitimate ways.
There is a very nice article Eric Enge Interviews Google's Matt Cutts regarding Google attitude toward illegitimately use of hidden text.
Have a look at this: https://sites.google.com/site/webmasterhelpforum/en/faq-rich-snippets and search for the word 'tempting'.
' It can be tempting to add all the content relevant for a rich snippet
in one place on the page, mark it up, and then hide the entire block
of text using CSS or other techniques. Don't do this! Mark up the
content where it already exists. Except in special circumstances ... '
It might seem like a clever idea to hide elements in a more complex way than by just display:none but, and i guess the same can be applied for hidden honeypot form fields, you are not the only one who can think of that.
Note: It is as easy to determine if a field is hidden by display:none as it is by margin:0; padding:0; width:1px; height:1px; overflow:hidden or by position:absolute; top:-[a value bigger than the page height]px or by something similar.
People would rich-snippet everything as an Apple product page if it would be ok to hide the snippet and provide any other kind of information on the porn - i mean page.
You got all that information already hanging out on the site, so just add the correct microdata tags to the corresponding text passages and google (other search engines, too by the way) will be happy.
So, for example, if your main page title already exists, put the itemprop="description" tag in the <div> tag thats is wrapping the title and you should be fine.
:)

Apply a href-like attribute to non-<a> elements

I've been working on a page where there are several entries contained in different <div>s. Each is only a title linked to a page, an image and a short description. However, the description may contain arbitrary tags, including <a> tags.
Since these are pretty straightforward and the actual link isn't that big, I've made it so a click on the <div> will call location.href = (link URL). However, that's a pretty sad thing, because it's browser-unfriendly: for instance, under Google Chrome, a middle-click on one of said <div>s won't open the link in a new tab.
Considering you shouldn't nest <a> tags, is it possible to make any element in XHTML behave like a link without resorting to Javascript?
I'm using XHTML 1.1, sent with the proper MIME type, and that's the only restriction I'm bound to.
Not really, no. Though it's worth reading Eric Meyer's thoughts on this. Also, it appears that HTML51 includes the capacity for any element to become a link, so it might be worth using that doctype instead of xhtml, if possible.
It's worth also adding that html 5 does allow for an <a> element to enclose block-level elements, see: http://www.brucelawson.co.uk/2008/any-element-linking-in-html-5/, example taken from the linked page:
Instead of:
<h3>Bruce Lawson as Obama's running mate!</h3>
<img src="bruce.jpg" alt="lovegod" />
<p>In answer to McCain's appointment of MILF, Sarah Palin, Obama hires DILF, Bruce Lawson, as his running mate. Read more!</p>
you can say:
<a href="story.htm">
<h3>Bruce Lawson as Obama's running mate!</h3>
<img src="bruce.jpg" alt="lovegod" />
<p>In answer to McCain's appointment of MILF, Sarah Palin, Obama hires DILF, Bruce Lawson, as his running mate. Read more!</p>
</a>
Updated to mention possible inaccuracy
1: I may have misinterpreted part of the document to which I linked, having tried to find support for my claim that '...appears that HTML5...any element to become a link' (in the W3C's html 5 overview) it doesn't seem to be there. I think I was over-encouraged when I saw Meyer's proposal to include that possibility.
I'm too gullible, and naive... =/
If you want a link to cover an entire div, an idea would be to create an empty <a> tag as the first child:
<div class="covered-div">
<a class="cover-link" href="/my-link"></a>
<!-- other content as usual -->
</div>
div.covered-div {
position: relative;
}
a.cover-link {
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
}
This works especially great when using <ul> to create block sections or slideshows and you want the whole slide to be a link (instead of simply the text on the slide). In the case of an <li> it's not valid to wrap it with an <a> so you'd have to put the cover link inside the item and use CSS to expand it over the entire <li> block.
Do note that having it as the first child means it will make other links or buttons inside the text unreachable by clicks. If you want them to be clickable, then you'd have to make it the last child instead.

What's the purpose of "skip link navigation" in HTML generated from yaml-builder?

I'm using yaml builder to create a 3-column CSS layout. In the HTML it generates, there is one section that does not make any sense to me:
<!-- start: skip link navigation -->
<a class="skip" title="skip link" href="#navigation">Skip
to the navigation</a><span class="hideme">.</span>
<a class="skip" title="skip link" href="#content">Skip
to the content</a><span class="hideme">.</span>
<!-- end: skip link navigation -->
Class hideme looks like this:
.hideme {
position: absolute;
left: -1000em; /* LTR */
top: -1000em;
}
Apparently, removing it has no effect in browsers I tried, but I'm afraid it might come back to bite me later. Any ideas what's this for?
This is used to provide accessibility to people using screen readers etc. If the page is being read out to you, it is very annoying to have to listen to 5 minutes of menus that are the same on every page before you get to the information you wanted.
These early links give these readers a chance to bypass the boiler plate stuff on your page and skip to the good stuff.
It's for screen readers and braille displays that blind people use. The link is hidden in most nornal browsers, but the blind will "see" them. It allows them to skip the naviganion/menu. That way they don't have to sit listening to the computer reading out the entire the menu structure at every page load.

Resources