wcag compliance issue with play/pause button - accessibility

As part of making our site WCAG compliance we are adding play/pause buttons for carousel.Here the screen reader is reading in different manner
<div id="imageCarouselPlayBtn" class="cblt-button imageCarouselPlayBtn" tabindex ="0">
►
</div>
<div id="imageCarouselPauseBtn" class="cblt-button imageCarouselPauseBtn" tabindex ="0">
‖
</div>`
in this case screen reader is reading pause button as double vertical line and group for play button.
if we use sprite image instead it is reading as group for both play/pause buttons.
Is there any good solution for this problem instead of using image tags for both ?

You could use WAI-ARIA’s aria-label attribute:
It provides the user with a recognizable name of the object.
Also: Is there a reason why you don’t use button/input instead of div for the play/pause buttons? With buttons, your markup could look like:
<button type="button" aria-label="Play">►</button>
<button type="button" aria-label="Pause">‖</button>

Related

ReactJS. The component's state won't change if click is performed on nested html element

So, I have the IssuesList component, which is the list of issues that I get using ajax and github api, and DevStatus component, which sort of wraps the list up and contains all the logic, triggers state changes by two radiobuttons and so on.
My problem: When I click on one of the radiobuttons, the DevStatus component won't change state if the click was on the text inside the radiobutton. And when I click on the corners of the radiobuttons, the blue areas without text, the state changes perfectly.
Here's the structure of the radiobuttons:
<div className="btn-group" data-toggle="buttons">
<label className="btn btn-primary active"
onClick={this.onChangeRadioButton.bind(this)}
id={this.CLOSED_ISSUE_ID}>
<input type="radio" name="options"
autoComplete="off"
id={this.CLOSED_ISSUE_INPT_ID}
onChange={this.onInputChange.bind(this)} /> Closed Issues
</label>
<label className="btn btn-primary"
onClick={this.onChangeRadioButton.bind(this)}
id={this.OPEN_ISSUE_ID}>
<input type="radio" name="options"
autoComplete="off"
id={this.OPENED_ISSUE_INPT_ID}
onChange={this.onInputChange.bind(this)} /> Open Issues
</label>
</div>
Here's the codepen with the code and here's the full page view so you could better see and understand what I'm talking about.
Please, open the full page view and try to click on parts of the button that contain text and on ones that don't and you'll notice that as long as you click on parts without text - the state changes and if you click on text itself - the state doesn't change at all.
Could you please help me with that problem?
PS: removing onChange from the input element is not the solution.
Update 1
If you go to DevTools and inspect the radiobutton element, you'll see that inside the label tag there're input and weird span elements. The span element is not in the code I wrote, did React automatically add that? For some reason, the onClick event listener is not applied to those input and span elements.
Update 2
I've tried to add click event listener to the radiobutton in the console of dev tools and tried to figure out the target of the clicked element. When I click on the text - it is the span element and when I click on place without text - it is the label element and that's why the click event is not working.
Can my problem be solved using dangerouslySetInnerHTML, so that it won't create the unnecessary span?
Could you tell me please how to solve that?
React is creating a span because your text is not in any div. Also it would create a span if there was any white space (but in your case this is because there is no div around your text).
But the real problem here is the way you check your event. You need to check e.currentTarget instead of e.target
Then no need to use the ugly dangerouslysetinnerhtml!
React appeared to sometimes be adding span tags around text, no matter if there are the free white-spaces or not. The spans didn't allow the onClick event to fire when they were clicked on.
So, to force React not to render the spans, the dangerouslySetInnerHTML may be used:
noSpanRender(text) {
return { __html: `<input type='radio' name='options' autoComplete='off'/>${text}` };
}
render() {
return (
<div className="dev-status-page col-centered">
<div className="graphs">
<h1 className="text-center page-header">
Our Recent Closed and Opened Issues from GitHub
</h1>
</div>
<div className="issues col-centered">
<div className="btn-group" data-toggle="buttons">
<label className="btn btn-primary active"
onClick={this.onChangeRadioButton.bind(this)}
id={this.CLOSED_ISSUE_ID}
dangerouslySetInnerHTML={this.noSpanRender('Closed Issues')} />
<label className="btn btn-primary"
onClick={this.onChangeRadioButton.bind(this)}
id={this.OPEN_ISSUE_ID}
dangerouslySetInnerHTML={this.noSpanRender('Open Issues')} />
</div>
<IssuesList issues={this.state.issues} />
</div>
</div>
)
}
It was vital to avoid those span elements inside the input tag, so using dangerouslySetInnerHTML finally helped.

FontAwesome, Bootstrap and screenreader accessibility

I'm wondering about screen reader accessibility using Twitter Bootstrap framework and FontAwesome icon fonts.
I'm looking at 2 different icon situations:
1) The icon has helper text that a screen reader will pick up:
<span class="fa fa-pencil"></span> Edit
2) And a standalone icon without any helper text:
<span class="fa fa-pencil"></span>
Ideally, in both situations, a screen reader will announce that the element is an "Edit" button.
Per FontAwesome's site:
Font Awesome won't trip up screen readers, unlike other icon fonts.
I don't see any speech css tags related to FontAwesome or Bootstrap and not really clear to me how a screen reader will react to each of these situations.
I'm also aware of aria-hidden and Bootstrap's .sr-only and there has to be an ideal way to handle both situations.
Edit: added title="Edit to example 2.
What advantage does using aria-label="Edit" have over the standard title="Edit"?
Edit 2: I came across this article that explains pros and cons of different use implementations.
First of all, you should probably use <button> instead of <a href="#">. Empty links can be confusing for screen readers, but a button is a button. In short, links take you places, buttons perform actions. (http://www.karlgroves.com/2013/05/14/links-are-not-buttons-neither-are-divs-and-spans/; https://ux.stackexchange.com/questions/5493/what-are-the-differences-between-buttons-and-links).
I would go with a variation of your first code sample, and utilize Bootstraps .sr-only class. If we update your code with button and add in the class, we have:
<button type="button" class="btn btn-default"><span class="fa fa-pencil"></span> <span class="sr-only">Edit</span></button>
We now have a more semantically correct button element; sighted users see the edit pencil icon; and screen reader users will hear "Edit". Everyone wins.
(Note, the button code is straight from Bootstraps CSS Buttons section.)
From my understanding I think it may be useful to also add in:
aria-hidden="true"
to the span class that holds the pencil icon. This will prevent the screen reader from trying to read this element.
<span class="fa fa-pencil" aria-hidden="true"></span>

make style on html5 audio player timeline

I want to make a style on html5 audio player.
<audio id="player" controls="controls">
<source src="song.ogg" type="audio/ogg" />
<!-- using mozilla firefox -->
Your browser does not support HTML5 audio. Please upgrade your browser.
</audio>
Is it possible to put css style on the html5 generic audio player timeline?
-thanks.
The following code, when pasted into Chrome's developer console, reveals a document fragment that describes the audio element's structure:
var aud = document.createElement('audio');
document.querySelector('body').appendChild(aud);
aud.controls = true;
Going to the chrome debugger's elements tab reveals this document fragment:
<div>
<div>
<div>
<input type="button">
<input type="range" precision="float" max="0">
<div style="display: none;">0:00</div>
<div>0:00</div>
<input type="button">
<input type="range" precision="float" max="1" style="display: none;">
<input type="button" style="display: none;">
<input type="button" style="display: none;">
</div>
</div>
</div>
If there was a way to change the style of the time display or the play/pause button without redefining the inner structure(i.e. shadow DOM), it would be through that document fragment. There is neither a function nor an attribute that suggests the ability to access said document fragment.
Youtube does their own HTML5 video timeline in case someone wants to "try something new"(or just hack an easy way to download some of their ad-free WebM videos), so I know it is possible. I'm guessing you would need to do it like this:
<audio id="player" ><!--notice how you get rid of the controls -->
<source src="song.ogg" type="audio/ogg" /> <!-- using mozilla firefox -->
Your browser does not support HTML5 audio. Please upgrade your browser.
</audio>
If you have the audio player hidden, you can add Event Listeners to update the status/progress. You will definitely want to use at least onTimeUpdate
Meanwhile, you can make your own DOM controller with a square tags with border-radius = (width/2) for a circle, or just use a . I suggest you look into the Shadow DOM for a way to hide functionality from both users and other scripts.
If you want to just show the user how far the music has played and not allow the user to seek, use a tag or a tag. Otherwise, you can use an tag and stylize that. Don't forget to add an onInput handler to skip through the track.
edit
I did not see that image. You must have uploaded it while I was answering. I would suggest you use a filter, but that might not work on anything but images. Try making a div transparent over it and allowing the user to click through it
edit #2
It turns out that background-color kinda tints the player in Chrome(only the audio player) depending on the background color, but the play time color does not change color with either background-color or color. You can get full control and uniformity over your style with a custom player, but that would mean extra work for you. I hope that my answers were helpful.

How do I bind a dynamic set of jQuery Mobile buttons using Knockout.js?

I'm using jQuery Mobile (jQM) and Knockout.js (ko) to develop an application. In this application, I need to generate a variable number of buttons that are defined by a constantly updating web service.
So, in my markup, I have:
<div id="answerPage-buttons" data-bind="foreach: buttonsLabels">
<button data-role="button" data-inline="true" data-theme="b" data-bind="text: text, click: $root.submitAnswer" />
</div>
buttonLabels is a list of short strings returned from the web service. It's defined as:
self.buttonLabels = ko.observableArray();
This all works fine when the buttons are not "jQM styled". However, when I style them using:
$("#answerPage-buttons").trigger("create");
problems arise during the update.
The issue seems to be that jQM wraps the buttons in a div (with a sibling span) to make them all nice and mobile looking. However, when the ko applies the updates via the bindings, it only removes the tags, leaving the surrounding stuff, and adds new button tags - which are then also styled by the jQM trigger call.
So, I end up with an ever-growing list of buttons - with only the last set being operational (as the previous ones are gutted by the removal of their button element, but all the styling remains).
I've managed to address this, I think, by placing the following call immediately after the observable is updated:
$("#answerPage-buttons div.ui-btn").remove();
However, my feeling is that there's probably a better approach. Is there?
I found a solution.
If I surround the buttons with a div, it seems to work - e.g.
<div id="answerPage-buttons" data-bind="foreach: buttonsLabels">
<div>
<button data-role="button" data-inline="true" data-theme="b" data-bind="text: text, click: $root.submitAnswer" />
</div>
</div>
I'm guessing this is because the markup added by jQM remains "inside" the markup replicated by ko. Without the div, jQM wraps the button tag, which was the immediate child of the tag that contains the ko foreach binding.

How to add background image and icon to a JSF button?

I am using JSF 2.0
I am able to add Background image to the JSF button but am not able to add icon to the button.
My Requirement is:- JSF button with Background image and a Icon
Following code am using to add background.
<!-- Discard button-->
<h:commandButton action="discard" style="background-image: url('..\\Images\\leftMenuActiveBg.png');width: 150px;height: 30px;color: white;border-color: white;font-size: 15px; " value="#{message.discard}">
<rich:componentControl target="popup" operation="show" />
</h:commandButton>
Can somebody help me in adding a icon to the button too please.
I am updating a image for better Explainanation as what I want to achieve and I what I have achieved till now with above code.
So you want a button with two background images? That's not possible on a single HTML element. The <h:commandButton> generates an single HTML <input type="submit"> element, while you basically need a <button type="submit" class="background"><span class="icon"> instead. You'd need to create a custom component which generates exactly that HTML, or to adopt a 3rd party component librarty which has such a component in its set, such as PrimeFaces. See also the <p:commandButton> showcase.

Resources