A website I've worked on has a simple form to login, which is quite similar to the stripped down code snippet below. The one key factor, for the sake of this question, is that there's a 'Forgot password?' link above the password field.
The tab order, by default, when using this form goes: Email input -> 'Forgot password?' link -> Password input -> Submit button.
This, however, is confusing to users - they don't expect there to be an item between the email and password fields.
Possible solutions I've considered are:
tabindex="-1"
to remove the 'Forgot password?' link from the tab order all together. This seems bad though as there's now no way to trigger it with the keyboard.tabindex
to everything on the page so that the 'Forgot password?' link comes after the submit button in the tab order. This seems bad as it feels like unexpected behavior and it's ideal to avoid manual tabindex
values everywhere.What is the correct way to handle the 'Forgot password?' link with regards to tabbing? What follows proper accessibility standards and best practices while also not giving an awkward tab order flow?
Feel free to try out tabbing through the demo below:
label {
display: block;
}
input {
width: 100%;
}
.field {
margin-bottom: 10px;
}
.space-between {
display: flex;
justify-content: space-between;
}
<form>
<div class="field">
<label for="email">Email</label>
<input id="email" type="email" />
</div>
<div class="field">
<div class="space-between">
<label for="password">Password</label>
<a href="#">Forgot password?</a>
</div>
<input id="password" type="password" />
</div>
<button>Submit</button>
</form>
Based on the comments here is a very rough idea of how to fix this issue.
Logical tab order is one of those tricky ones as it is open to interpretation in some instances.
This is a prime example, it is logical that the forgotten password link is after the password input but it appears visually before.
However as the items are grouped together I believe in this instance it is logical to tab to the input and then to the link even if it appears above the input.
A little bit of old school position: absolute
within a position: relative
container does the trick in the below example and is visually the same while fixing the tab order. Obviously you might want to use better CSS selectors in production!
label {
display: block;
}
input {
width: 100%;
}
.field {
position: relative;
margin-bottom: 10px;
}
.field a{
position: absolute;
top: 0;
right: 0;
}
<form>
<div class="field">
<label for="email">Email</label>
<input id="email" type="email" />
</div>
<div class="field">
<div class="space-between">
<label for="password">Password</label>
</div>
<input id="password" type="password" />
<a href="#">Forgot password?</a>
</div>
<button>Submit</button>
</form>