If someone is using keyboard navigation on the default phpBB registration form, they cannot access the two time zone selects (#tz_date and #timezone) nor can they access the "Anti-Spammer/Bot Test" select (#pf_antispam).
The reason is misuse of tabindex. The first five inputs, and the submit button at the end of the form, all have a positive tabindex set. Respectively: 1, 2, 3, 4 and 8 for the inputs, and 9 for the submit button.
Obviously, if the other inputs have tabindex set the selects should also have values set (5, 6 and 7) but since they don't they are inaccessible by keyboard. The result is that focus follows the artificial order forced by tabindex, so it skips from #email straight to #answer.
This is another case where the standard accessibility rule of not using tabindex values greater than 0 applies. If none of the inputs has tabindex set, the whole form will work perfectly. Prosilver includes a skipnav link, which will take a11y users straight to the start of the registration form. After that, focus will just follow the natural order of the form's markup. It would also be more maintainable and easier to customise.
There are two additional issues.
1/ #tz_select_date does not have a label.
2/ #answer does not have a label either. There is a label in the dt preceding #answer's dd parent, but it has no for attribute, so it is non-functional and from an accessibility perspective it's just confusing clutter.
I have already fixed all of this for my own use. My suggestions are:
- Remove all instances of tabindex from ucp_register.html
- Where $CAPTCHA_TAB_INDEX is defined, set the defined value to 0.
These are minor changes that are easy to implement, and having $CAPTCHA_TAB_INDEX set to 0 will automatically deal with captcha_qa.html, etc.
Regarding the missing/broken labels, I have used this in timezone_option.html:
// co<dl>
|
<!-- IF .timezone_date -->
|
<dt>
|
<label for="tz_date">{L_SELECT_CURRENT_TIME}{L_COLON}</label> |
</dt>
|
<dd id="tz_select_date" style="display: none;"> |
<select name="tz_date" id="tz_date" class="autowidth tz_select"> |
<option value="">{L_SELECT_CURRENT_TIME}</option> |
<!-- BEGIN timezone_date -->
|
<option value="{timezone_date.VALUE}"<!-- IF timezone_date.SELECTED --> selected="selected"<!-- ENDIF -->>{timezone_date.TITLE}</option> |
<!-- END timezone_date -->
|
</select>
|
<input type="button" id="tz_select_date_suggest" class="button2" style="display: none;" timezone-preselect="<!-- IF S_TZ_PRESELECT -->true<!-- ELSE -->false<!-- ENDIF -->" data-l-suggestion="{L_TIMEZONE_DATE_SUGGESTION}" value="{L_TIMEZONE_DATE_SUGGESTION}"> |
</dd>
|
<!-- ENDIF -->
|
<dt>
|
<label for="timezone">{L_BOARD_TIMEZONE}{L_COLON}</label> |
</dt>
|
<dd>
|
<select name="tz" id="timezone" class="autowidth tz_select timezone"> |
<option value="">{L_SELECT_TIMEZONE}</option> |
<!-- BEGIN timezone_select -->
|
<optgroup label="{timezone_select.LABEL}" data-tz-value="{timezone_select.VALUE}"> |
<!-- BEGIN timezone_options -->
|
<option title="{timezone_select.timezone_options.TITLE}" value="{timezone_select.timezone_options.VALUE}"<!-- IF timezone_select.timezone_options.SELECTED --> selected="selected"<!-- ENDIF -->>{timezone_select.timezone_options.LABEL}</option> |
<!-- END timezone_options -->
|
</optgroup>
|
<!-- END timezone_select -->
|
</select> <!-- INCLUDEJS timezone.js -->
|
</dd>
|
</dl>de placeholder
|
And have used this in captcha_qa.html:
// code placeholder<!-- IF S_TYPE == 1 -->
|
<div class="panel captcha-panel"> |
<div class="inner"> |
<h3 class="captcha-title">{L_CONFIRMATION}</h3> |
<fieldset class="fields2"> |
<!-- ENDIF --> <p>{L_CONFIRM_QUESTION_EXPLAIN}</p>
|
<dl>
|
<dt>
|
<label for="qa_answer">{QA_CONFIRM_QUESTION}{L_COLON}</label> |
</dt>
|
<dd class="captcha"> |
<input type="text" name="qa_answer" id="qa_answer" size="45" class="inputbox autowidth" title="{L_ANSWER}"> |
<input type="hidden" name="qa_confirm_id" id="qa_confirm_id" value="{QA_CONFIRM_ID}"> |
</dd>
|
</dl><!-- IF S_TYPE == 1 --> |
</fieldset>
|
</div>
|
</div>
|
<!-- ENDIF -->
|