Accessibility: show/hide password button in a password input - javascript

It's common for password inputs to have a show/hide button but I'm finding little content on the web about any accessibility concerns relevant to them - should I be attaching any kinds of ARIA attributes to the button or password input? Does it make sense for that to be a checkbox or is a button that triggers JS to achieve the effect fine too?
Not sure what I should be looking out for as someone not very steeped in, but wanting to understand accessibility best practices.

Interesting question.
This is perhaps the most relevant bits of litterature I could find on the subject:
A disclosure is a button that controls visibility of a section of content. When the controlled content is hidden, it is often styled as a typical push button with a right-pointing arrow or triangle to hint that activating the button will display additional content. When the content is visible, the arrow or triangle typically points down.
(and)
The element that shows and hides the content has role button.
When the content is visible, the element with role button has aria-expanded set to true. When the content area is hidden, it is set to false.
Optionally, the element with role button has a value specified for aria-controls that refers to the element that contains all the content that is shown or hidden.
See https://www.w3.org/TR/wai-aria-practices-1.1/#disclosure
I'm no usability expert at all but it doesn't seem crazy to see a connection with your use case. So to answer your question here are the ARIA attributes I'd apply, along with some JavaScript.
function toggle_visibility(el) {
const control = el.getAttribute('aria-controls');
const expanded = el.getAttribute('aria-expanded') === 'false';
document.querySelector(`#${control}`).type = expanded ? 'text' : 'password';
el.setAttribute('aria-expanded', String(expanded));
el.textContent = expanded ? 'hide' : 'show';
}
document.querySelector('button').addEventListener('click', ({
target
}) => toggle_visibility(target));
<div>
<label for="password">password</label>
<input type="password" id="password">
<button aria-controls="password" aria-expanded="false">show</button>
</div>
And here's a screencast of the Chrome Dev Tools. Note how in the Accessibility panel we're able to refer to the password control.

As none of the so-far given answers cover the topic completely, I'll try to do it here.
You have at least three possibilities:
A checkbox;
A toggle button;
A button with changing text.
Checkbox
This is the easiest solution.
<label><input id="showPwd" type="checkbox"> Show Password</label>
And then you add some JavaScript to change your password input type from password when the check box is cleared to text when it is checked.
From the user perspective this solution is also the most obvious: both screen reader users and users of other assistive technologies usually easily perceive the state of the check box. Another benefit of this approach is that the status is seen immediately with no need to re-check it with additional commands.
Toggle Button
This involves some ARIA, not much, though.
<button id="showPwd" aria-pressed="false">Show password</button>
This way you will need to change both the button CSS styling and the value of the aria-pressed attribute in your JavaScript (and, of course, change the type of your password input accordingly).
From the user perspective, this approach has both advantages and drawbacks. the main advantage for screen reader users is that when the button is pressed, the user will hear "Show Password button pressed" vs. "Show password button" which would help to spot the status of the button for users with hearing and/or cognitive issues better and faster.
Button with Changing Text
An easy, but kind of oldish solution. You basically have a <button> that says "Show Password", and when the password is revealed, the button would say "Hide Password".
This is the worst solution from the assistive technology user perspective, since a screen reader would not notify its user automagically when the text on the button changes (unless you add some additional black magic like ARIA alerts, but it's not worth it, I'm sure). Typically when the text changes, the user should re-check the status with a command that announces the current line or object.
There is another drawback that spans both button solutions: screen readers usually have a possibility to navigate by element and to spawn lists of elements of the same type. In this case a confusion may occur as the form contains more buttons (at least the submit one). With check boxes the chance of such confusion is much lower, if the form is not crowded with many check boxes.

Related

Empty button error in wave accessibility check

Hello Im new web developer. i get empty button error from wave.webaim.org - WCAG 2.0 Level AA Accessibility.
Thats the code.
<button type="button" role="presentation" class="owl-prev disabled h-hidden" title="none">
any help on that?
Thanks in advance.
"An Empty Button error means that one of the buttons present on the web page is empty or contains no text describing the function of the button. Or, if it’s an image button, the image contained in the button is missing alternative text."
Source: https://equalizedigital.com/accessibility-checker/empty-button/
It could be that there's no text on the button. If you don't want to put a visible text on the button, you could put a visually hidden text that is read by screen readers, sometimes called the sr-only class in css.
More info: How to hide a text and make it accessible by screen reader?
You need to have actual text inside the button. If you don't want to have a visible text because you style the button in a certain way, using PisteVW solution from above works just fine.
Alternatively, you can use the attribute aria-label="button text here" to give the button a label.
Also, you need to remove role=presentation as the button performs a clear action, it's not there to simply indicate presentational images, for example: https://www.w3.org/TR/wai-aria-1.1/#presentation

jQuery UI dialogs and aria-controls

Would using aria-controls on a button to reference a jQuery UI dialog element that it opens be appropriate usage of ARIA?
I already notice that jQuery UI automatically wraps the div in another separate div that has role=dialog and aria-labelledby with the title of the dialog. I've seen aria-controls on relationships between tab links and tab panels as well as buttons and form elements (inputs, dropdowns, etc) but not between buttons and dialog boxes.
Here is a code example to demonstrate what I'm asking about:
$('button[aria-controls$="-dialog"]').on('click', function() {
var $dialog = $('#' + $(this).attr('aria-controls'));
$dialog.dialog('open');
});
$('.jqui-dialog').dialog({
modal: true,
autoOpen: false
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
<script src=https://code.jquery.com/ui/1.11.4/jquery-ui.min.js></script>
<link rel=stylesheet type=text/css href=https://code.jquery.com/ui/1.11.4/themes/dot-luv/jquery-ui.css>
<button type=button aria-controls=add-new-item-dialog>
Add new item
</button>
<div id=add-new-item-dialog class=jqui-dialog title='Add new item'>
<p>A form here.</p>
</div>
In the jQuery current implementation, I don't think it's appropriate.
According to the ARIA documentation for "aria-controls"
http://www.w3.org/TR/wai-aria/states_and_properties#aria-controls
Identifies the element (or elements) whose contents or presence are controlled by the current element. See related aria-owns.
What does this mean?
This can be used for buttons which control a video, a slider, a tab panel, or whatever needs to be controlled.
When you focus such button, JAWS announces "Use Jaws key + alt + m to move to the controlled element". So if the element has display:none, it won't work. If you want to control the "presence" of an element you'll have to target a parent element or play with visibility/z-index CSS attributes.
The expected result is that the screen reader can lead you to the affected element, without requiring that you pressed the button.
In your case, you have, when the page loads, an ui-dialog with the css property display: none. So when the screenreader will announce that the button can affect another element, you won't be able to jump to it unless you effectively press it before as the element is not already in the visual flow.
TL;DR: the aria-controls attribute indicates which element can be affected by a control. The screen reader will give you a quick access to that element (without requiring you to effectively press the control itself). This requires that the visual focus could be moved to the targeted element.
Yes, using aria-controls for an element role button is allowed per the ARIA spec and your use case makes sense. It would be up to the user agent/assistive technology to provide whatever behavior it deems appropriate for this relationship (with JAWS you can use INSERT-ALT-M to navigate to the controlled element. If the dialog is not modal and the button toggles it, this provides useful navigational support. If the dialog is modal, it does not add much to the user experience).
What will improve the user experience in your case is if you aria-haspopup="true" to indicate that the button will spawn a popup. This will then be announced to screen reader users.
Here Leonie Watson (ARIA WG member) specifically uses a button as an example for ARIA controls and talks about how screen readers currently (as of the writing) support it http://tink.uk/using-the-aria-controls-attribute/

How to handle auto-focus on field elements when you try to update an object

We tend to position the cursor on the first element of all newly created objects (e.g. name field for user or the email id field on the login page). Does it make sense to auto-focus on the name field for user on User.update, since the user could modify any other field of the User and doing on auto-focus while doing User.update actually marks the entire name field instead of positioning the cursor on the name element. What should be the right behavior?
The purpose of auto-focus behavior on a web page is to save users from moving off the keyboard to make a mouse action for the most common task on that page.
So you need to ask the question: "What is the most common task performed on this page?"
Then ask, "What is the first UI element (field) a user needs to access or edit to accomplish the most common task(s) on this screen?"
Your answer should determine where your auto-focus goes. But be careful - users expect the auto-focus to go on the first field on the page. So only place it elsewhere if you are sure that this is desirable to the users. And also in that case, consider moving that field to the top of the page.
In your case, the "name" element gets entirely marked (selected) because that is how auto-focus works for fields that already contain data. This is the most desirable behavior because it allows the user to replace the contents of the field without doing further work with the cursor and delete keys, and if they only want to edit, they can simply use the Home/End and arrow keys to quickly move the cursor where they need it.
===== Edit / Addendum =====
I forgot to add this in the original answer, but it's such a huge pet peeve of mine that I have to mention it here.
Please, if you do an auto-focus, make sure it doesn't fire if the user is already typing! There is NOTHING more annoying than having your cursor moved automatically while you're in the middle of logging in.
This used to happen on Yahoo! Mail's login screen all the time. If the page was loading slowly, the login form would render a few seconds before the DOM was ready and the auto-focus only fired when it was ready. So I'd click manually to focus in the login field, and I'd already be halfway through my password when auto-focus would silently move my cursor back to the login field and I'd look up at the screen to find half my password in plain text up in the login field, smashed up against my username.
The fix is so simple; just check if the login field is still blank before focusing there. Otherwise don't because you then know the user already typed something and the convenience of auto-focus would turn into a frustration. Here's example code, assuming your field is given an id="username":
function focusIfBlank(){
username = document.getElementById('username');
if(username.value == "") {
username.focus();
}
}
Also consider calling focusIfBlank() inline instead of when the DOM is ready, because you'll increase the chances of it being useful to the user since it will focus almost instantly after it's rendered.
I am not sure whether its your answer,
<body>
Name: <input type="text" autofocus /> <br />
Email: <input type="text" />
</body>
Refer this,and this for more options..

HTML text field to behave like a password field

I have a registration form, and i want to use a password field. The problem is, i want it to have a placeholder saying "Password" at the begining so i'm using a text field instead. I need to turn the characters into asterisks or black circles like a password field when the user starts typing.
I've tried changing the "type" attribute to "password" through javascript, so i'm stuck.
Is there a simple way to resolve this with css? or does anyone know of a good javascript(preferably jquery) to hack this?
Thanks
Use a regular password field
Don't abuse the value as a placeholder — it becomes invisible to, among others, screen reader users.
Put the label in a <label>
Position the label behind the input
Restyle the input with JS to change the background
Demo at http://dorward.me.uk/tmp/label-work/example.html
You could use the HTML5 placeholder attribute However, that will not work in all browsers (especially older ones).
<input type="password" name="pwd" placeholder="Enter Password" />
Hover a div or a span tag over your text (password) field, then hide it when the password field takes focus or the div/span is clicked.
Generally, browsers frown at changing the type attribute of input elements via JavaScript. Most workarounds involve cloning the input with the new type, and removing the original.
You could absolutely position the label over the input form, and remove it on focus.
You should consider the implications of not using type="password" - it is the semantically correct option.
Update
Upon reading David Dorward's answer, you should strongly consider his very valid points.
I had a similar problem, where I had the Value of the inputs as my labels, and when you clicked inside one, some Javascript would run, clearing the input. But on the password field, you needed to change the input type from "text" to "password", which works in browsers like Safari or Firefox, but not IE (IE doesn't support the setAttribute function very well). So I was killing myself trying to figure out how best to do this (IE conditionals, etc.)
I found this thread, and I think Quentin had the best idea. Not only because it works and should work in all browsers, but it also provides an actual Label in the code, which, Screenreaders aside, is good practice. Plus, you should always consider those who use screenreaders to some extent.
Here is the basics of the solution:
The HTML:
<label>Enter Password
<input type="password" name="password" class="input" /></label>
The jQuery (note: I am not a jQuery expert. This could probably be written better or more efficient, but for two fields, it works):
$("input[name=password]").focus(function() {
var value = $("input[name=password]").val();
if(value == "") {
$(this).toggleClass("inputBg");
}
});
$("input[name=password]").blur(function() {
var value = $("input[name=password]").val();
if(value == "") {
$(this).toggleClass("inputBg");
}
});
The CSS starts with the Label tag, styled the same as your input class, with a position relative and display block added. Then there are two classes for the input. One that is the correct width, height, etc. positioned absolute, with a higher z-index than the label, BUT WITH NO BACKGROUND. The second class is exactly the same, but WITH THE BACKGROUND.
The jQuery just toggles between the two classes, so you'll see the label under the input, but when you click on the input, the background appears and you can type in text on top of it. Works great, should work in all browsers (although only tested in Safari on Mac and IE/Firefox on Windows). Nice idea Quentin!

Title Attribute on Disabled Elements in Firefox

I am building a very dynamic web-based application using a lot of Javascript to handle user events. I am in the process of making things a little more usable and came across a problem that I've never had before.
I am using jQuery, so factor that in to your answers. Thanks in advance.
I have a set of button elements defined as:
<input type="button" title="My 'useful' text here." disabled="disabled" />
I have these buttons with a default style of:
div#option_buttons input {
cursor: help;
}
Then, using jQuery I run something like this as a click-event on a select box:
window.current_column = '';
$('select.report_option_columns').live('click', function() {
var column = $(this).val();
if ( column == window.current_column ) {
// clear our our previous selections
window.current_column = '';
// make this option no longer selected
$(this).val('');
$('div#option_buttons input').attr('disabled','disabled');
$('div#option_buttons input').attr(
'title',
'You must select a column from this list.'
);
$('div#option_buttons input').css('cursor', 'help');
} else {
window.current_column = column;
$('div#option_buttons input').attr('disabled','');
$('div#option_buttons input').attr(
'title',
'Add this option for the column "' + column + '"'
);
$('div#option_buttons input').css('cursor', 'default');
}
});
So, as you can see, when a column is selected in the select box (not shown here), I want the button to be enabled and behave like a button would (with my own click-events). But when a column is not selected (including the default load), I want the button disabled. The usability developer in me wanted to give the users subtle contextual clues as to what they can do to enable the button through the native rendering of the title attribute as a lightweight tooltip. I do this already in other areas of the application (this is a crazy beast of a project) and our usability tests have shown that the users are at least capable of recognizing that when the cursor changes to "help" that they can hover over the element and get some information about what is going on.
But this is the first time I've ever tried this with a form element. Apparently when I put disabled="disabled" in the element, it completely ignores the title attribute and will never display the tool tip.
Now, I know I have a few options (at least the ones I could think of):
Write my own custom tool tip plug-in that is a little bit more robust.
Don't "disable" the element, but style it as disabled. This was the option I was leaning on the most (in terms of ease to develop) but I hate having to do this.
Leave the button as enabled but don't process the click event. I don't like this option as much because I like to leave things natively styled as they should logically be. A disabled button "feels" the most correct and the look of a disabled button is instantly recognizable as a disabled button.
So, with all that said, am I missing something? Is there something easy that I can do that I just haven't thought of? Google searches have failed me on this topic, so I thought I'd toss this out on StackOverflow to get some fresh eyes on this.
**Edit**
I just found another StackOverflow question on this same topic, though that person used a very different set of terms describing his problem (probably why I didn't find it).
The url to the question is: Firefox does not show tooltips on disabled input fields
Both of the answers on that question are pretty good, though I'd like to see if anyone has any other suggestions. Maybe something more jQuery specific? Thanks again.
I had a similar problem and I just surrounded the disabled element in another element and interacted with that div, i was using tipTip to show tooltip for disabled checkbox
<div style="cursor: pointer;" class="disabled" title="Do something to make it work" >
<input disabled="disabled" type="checkbox">
</div>
There are several validation plugins that are very robust. You can find them in the jQuery plugins area.
Another option for you though which I happen to love and tends to be trending now adays is using the "Tipsy" plugin. You can put little '?' icons to the right of your text fields and people can mouse over them to get a "facebook-like" tool tip. This plugin is very sharp and I highly recommend it.
Good luck!
I haven't tested whether or not that solves the problem with the missing title, but you could also disable the button(s) using jquery on $(document).ready()
regards,
harpax
If that doesn't break your design totally, you can replace your button by a "span", "p",... tag with "My 'useful' text here."
And swap it with the button only when the user makes the correct move.

Categories