Adding aria-label to text elements - html

So I have an HTML button, with 2 divs inside it - each of which displays certain text. Sample code below. I need to insert some text between the 2 divs such that it is only to be read by screen readers and isn't needed visually speaking. This is a large shared component so I can't really modify the control itself, hoping to just tweak the accessibility part:-
I tried using aria-label on div2, and arialabelledBy keeping the label text hidden on the screen (display: none).
<button>
<div id="div1" >Main text here</div>
<div id="div2" >sub text here</div>
</button>
In the above example, I need the screen reader to read something like:-
"Main text here, in between, sub text here". How do i represent "in between" above. I tried aria-label \ labelledBy but those get ignored by Narrator.

You need the additional text in its own <div> and then use a class to visually hide the element but still allow screen readers to read it. This is a very common practice. See What is sr-only in Bootstrap 3? for an example of a class that will do this.
Also check out "Invisible Content Just for Screen Reader Users" by WebAIM.
So you'd have something like:
<button>
<div id="div1" >Main text here</div>
<div class="sr-only" >in between</div>
<div id="div2" >sub text here</div>
</button>

Related

NVDA not reading aria-label on div

I have a div element with role="listitem". It contains multiple divs with some text inside. When he outer div is focused, I want a custom aria-label to be read instead of the inner texts. Here is my sample code:
<div role="listitem" aria-label="Hello World" tab-index="0">
<div> A </div> <div> b </div> <div> c </div> <div> d </div>
</div>
On JAWS and Narrator, it works as expected. On NVDA, it's reading the inner text.
On changing outer div to anchor tag, NVDA is reading correct aria-label, but I cannot do that in prod code.
NVDA seems to honor the aria-label for some roles but not others. It works for button and menuitem, it reads both the aria-label and the nested <div>s for checkbox, and ignores aria-label for listitem, as you mentioned.
This seems to be a current bug. See https://github.com/nvaccess/nvda/issues/7807

Is it possible to display as "block" if content "line breaks" but display "inline" otherwise?

I have code that looks a little bit like this:
<div class="some-class">
<span>NameOfThing</span>
<div class="block-or-inline">
<span style="white-space: nowrap">ValueOfThing1</span>
<span style="white-space: nowrap">ValueOfThing2</span>
</div>
</div>
If the content inside div.block-or-inline is shorter than the width of its container (no line break) I would like all the content to render on a single line. But if the content is wider - causing a line break - I would like BOTH spans inside to break to the new line.
Is this possible?
I just left my keyboard for a few minutes and realized a simple way to solve this would be to to place the two pieces of content that I want to break to the new line under the same "white-space: nowrap" span:
<div class="some-class">
<span>NameOfThing</span>
<span style="white-space: nowrap">ValueOfThing1 ValueOfThing2</span>
</div>
If you want render the content in a single line you can put the css attribute overflow:hidden; to the div.block-or-inline and an specific width, and if the content is wider to the div, the rest of it will disappear.
It's a way to show the content avoiding the line-break.

Clear a span text field

im using Span text fields, and i want it to be cleared when clicking on them, how do i do?
My code looks like this:
<div class="text3">
<span contenteditable="true">något</span>
</div>
How would you edit the text if you clear it everytime you click ?
Anyway here is a trick :
<div class="text3">
<span contenteditable="true" onclick="this.innerText=''">något</span>
</div>
Use the node’s textContent property to set the “inner” text, which is the actual text node.
To clear the text when the span gets the focus for editing its content, use the onfocus attribute to set an empty string:
span{
display:inline-block;
min-width:30px;
min-height:18px;
outline:1px dotted grey;
}
<div class="text3">
<span contenteditable="true" onfocus="this.textContent='';">något</span>
</div>
Since the content will be set to empty string, the <span> inline element will be nearly invisible without entering any text. You probably should add some visual to the interface in order to guide the user. The above CSS will keep it at arbitrary minimum dimensions, adding an outline to keep the “input” from disappearing.
Also, you could select the text content instead of removing it. Unfortunately, it seems the Range interface doesn’t work for contenteditable non-input elements, so that’d be qualified for another question.

Change html element accessibility text

On a webpage I have a div
<div class="expand">+</div>
Tapping this div expands content.
I need to change what screen readers say when they encounter this element. I've been able to come close with:
<div class="expand" role="button" title="Tap to expand">+</div>
If you tap the button, the iPhone will say
Plus ... Button ... Tap to expand
Ideally it would just say "Button ... Tap to expand," or I could have complete control over what is said.
Additionally, tapping changes the content and the title to "Tap to hide." The element is focused immediatley and the new content is read, but for some reason the title is not included this time:
Hyphen ... Button
If you tap it again it will say the title.
Is there any way to control what is said by the screen reader when you tap an element? If not, is there any specific rule that prevents the title from being read in the second case?
Suggestions from http://alxgbsn.co.uk/2011/06/06/making-web-content-more-accessible-with-ios-voiceover/ made this possible.
<div class="hide" id="tap-show">tap to expand</div>
<div class="hide" id="tap-hide">tap to hide</div>
<!-- repeat -->
<div class="expand" role="button" aria-labelledby="tap-show"></div>
You can use JavaScript to change aria-labelledby, which works.
It is important to note that the role=button is necessary and the <div> must be empty. It can contain at most whitespace. You can use a background image, or:
.expand:after { content: "+"; }
In general you should be very careful about controlling this text exactly. People using screen readers use many apps / sites, and get used to how things are read out. In the case of button text, VoiceOver will generally announce:
[Content of button]... Button... [title of button]
If this is specific to iOS then I think your initial example is good, as VoiceOver considers the title to be 'help text', which is why it's read last. Assuming you have quite a few of these, then brevity is good.
Hyphen doesn't mean much, but you could use − to get it to announce "minus", and update the title to "Tap to hide".
Something you might consider including as hidden text is what it is that will be shown. Perhaps in your interface it is obvious visually and from a screen reader point of view, but in general it would be useful to know what is going to be shown.
You could hide some text, for example:
<div ...>+<span class="hidden"> description of the content</div>
Then move the .hidden off-screen with CSS.

Aligning Columns while Sizing Rows

I've got two pages, one made with div's and CSS, one made with the notorious table.
The CSS Page...
...and the Table page.
At first glance, they're pretty similar. Both sport a 2x2 grid of rounded "buttons", which resize based on the window around them.
Now, put this in the context of a mobile phone. That's right, shrink that result-frame down (horizontally, don't worry about vertical).
Originally, i just had the CSS version, but there's specific browser widths in which text on the left drops down to two lines where text on the right stays at one, as the strings are different lengths. It just so happens that with the actual strings, most phone resolutions cause this annoying situation to occur.
However, the table predictably acts the way I would want it to. The table has a concept of "rows" as well as "columns", so the columns stay aligned and as a cell in one row gets taller, so do all the rest.
Is there a way to mimic this behavior in CSS? I'm constantly told how bad tables are for accessibility, etc. And I'm a fan of keeping <table> for actual tables of data, not layout.
I know of the adjacent-selector, but I couldn't find a way to say "make your min-height the same as my height, and vice-versa".
Also, obviously this could be done with a script. But unless someone here has a passionately feels that for this problem, javascript > CSS && javascript > Table, let's stick to CSS.
Every sane browser today should support the display: table/table-row/table-cell/... property, which converts your divs to a nice table, but without touching the html markup.
Here is your transformed code:
http://jsfiddle.net/eU6Xe/5/
HTML:
<div id="main">
<div class="row">
<div class="button">
Some text here
</div>
<div class="button">
And more text here
</div>
</div>
<div class="row">
<div class="button">
More Text
</div>
<div class="button">
Lots of text here
</div>
</div>
</div>
​CSS:
div #main {
display: table;
width: 100%;
}
div.row {
display: table-row;
}
div.button {
display: table-cell;
}
​
To be honest both versions are not accessible, and both are equally as annoying to use.
First and foremost: Why aren't you using <button>s or <input type="button">?
It isn't semantically correct for both demos. Tables are not meant to do anything besides hold data. A button should be used for submitting/cancelling/clearing forms. A <div> is that whatchamacallit you keep in your junk drawer, that you use for a last resort.
Table Method
There is no way to make the table accessible. It will be always bee seen as a table, but since this is being incorrectly used, the WAI-ARIA role of presentation needs to be used. However this will tell assistive technology to ignore the fact it is a table, thus chunking the words together. The only way to make the cells clickable, is via an onClick, which may be fired automatically depending on the AT and the way you construct the onClick. Thus not allowing the person get past it, and since they won't know it is a table, they can't jump over it.
CSS Method
First the <h2> elements are used incorrectly. <h2> are to denote sections of a page that contribute to page hierarchy, which it makes little sense that a button would be part of the hierarchy. Next, a <div> doesn't recieve focus by default. Third, if you attach an onClick to the <div>, you run into the same issue as above.
Using ARIA, you can make <div>s act like buttons but your code becomes:
<div class="left-col">
<div class="button" tabindex="-1" role="button">
Some text here
</div>
<div class="button" tabindex="-1" role="button">
And more text here
</div>
</div>
OR
<input type="button" value="some text here" />