Using flex box to solve trivial a11y issue
The link for Terms and conditions should get focused before the checkbox. So this is a accessibility problem right? So how can we solve it now?.
Some time back I was working on a talk about accessibility. And I was working with my colleague Swapneel at Thoughtworks.
It was a simple use case that combines user experience and accessibilty (using form via keyboard)
Brief about the use case
Many of us sign up/sign in at least once a week and I personally am habitual of filling in the HTML form just by using keyboard only. And almost every sign up prompts you for accepting their terms and condition. And in almost every case it looks like this
So if you try to fill navigate and fill the form with just keyboard (using tab key to navigate between inputs/buttons/checkboxes)
Following gif shows how the tabindex is working on each tab press.
Do you see any problem in this tab indexing?
will you accept TnC without reading it? (now dont say I do although Some times I too do it) logically/ideally one will accept Tnc only after reading it. That means the link for Terms and conditions should get focused before the checkbox.
So this is a accessibility problem right? So how can we solve it now?
Possible solutions
Move checkbox after the I accept the terms and conditions text But then that breaks the reading flow on LTR languages
Add javascript to manage tabindex and focuses based on which input is focused right now some thing which I did here
Is there a simple solution? Yes indeed flex order property comes to our rescue. but How?
Lets look at HTML first
<form class="row" action="https://www.example.com" method="POST">
<div class="col-12">
<div class="col-12 form-group">
<label for="exampleInputEmail1">Email address</label>
<input type="email" class="form-control" id="exampleInputEmail1" aria-describedby="emailHelp" placeholder="Enter email">
<small id="emailHelp" class="form-text text-muted">We'll never share your email with anyone else.</small>
</div>
<div class="col-12 form-group">
<label for="exampleInputPassword1">Password</label>
<input type="password" class="form-control" id="exampleInputPassword1" placeholder="Password">
</div>
<div class="col-12 form-group form-check tncWrapper">
<input type="checkbox" id="tncCheckBox" id="exampleCheck1">
<label class="form-check-label" for="exampleCheck1">I accept the <a id="tncLink" href="https://www.example.com">terms and conditions</a></label>
</div>
<div class="col-12">
<button type="submit" class="btn btn-primary">Submit</button>
</div>
</div>
</form>
Now we will move the checkbox after the I accept the terms and conditions text, add some css and ta dah!! the magic of flex begins.
we will need to add some css in order to make keep the order of elements same on UI but different in code so the the only change we do in HTML is like below
<div class="col-12 form-group form-check tncWrapper">
<label class="form-check-label" for="exampleCheck1">I accept the <a id="tncLink" href="https://www.example.com">terms and conditions</a></label>
<input type="checkbox" id="tncCheckBox" id="exampleCheck1">
</div>
and add the following css
.tncWrapper {
display: flex;
}
#tncCheckBox {
order: -1;
}
With this we are asking the browser to render the checkbox before the I accept the terms and conditions text. But in HTML the checkbox appears after the text. And since screenreader/keyboard respect HTML and not what is being displayed/rendered in viewport we are done? Check it out here
Try it here
So how did it work?
Since the all accessibility tools like screenreader/keyboard respect the HTML i.e DOM order and not the view port/render order, Focus first moves to the link and then to checkbox which is coded in HTML. But for users its shown as other way around just from experience point of view.
Please comment down below if you have any suggestions/queries.