DEV Community

Cover image for An Accessible Dark Mode Toggle in React

An Accessible Dark Mode Toggle in React

Abbey Perini on November 06, 2021

Accessibility Auditing My Portfolio Site - Part 3 Read Part 1 - The Audit and Part 2 - Quick Fixes. When I made my dark mode toggle using @dailyd...
Collapse
 
grahamthedev profile image
GrahamTheDev • Edited

Great improvements, there are still a couple of things to address though I am afraid!

1. Keyboard controls to activate dark mode

The first one is that because you are using a <input type="checkbox" you need to account for Enter and Space. At the moment pressing Space results in some strange reload / flash behaviour.

Now I am way out of touch on react but with vanilla JS you can just use a click event handler rather than messing with listening for specific keys and it will handle it all for you! That is the great thing about native elements!

If you can't just use a click handler then add the keycode for space as well and that would be problem solved I would imagine!

2. Focus indicator

I like the animated focus indicator but there is a delay before it shows. You may need to speed up the animation a bit or change it to ease-out just for the outline property.

3. The label

There is no need for an aria-label as you have a properly associated <label>.

Also "dark mode toggle" isn't quite the correct wording as you should make the text relevant to the current state (if the input is checked I need to know what that means). Something like "dark mode on" makes more sense as when the control is in the checked or toggled on state you know that dark mode is activated (dark mode on true effectively), when it is not checked you know it is not activated.

Finally you are hiding the text by using the same colour for the text as for the background. A better way is to use a visually hidden class to hide the text by wrapping it in a <span>.

This is important as if someone uses a custom style sheet (known as a user style sheet) to override your colours the text will show.

Example of hiding text visually but making it screen reader accessible

<div class="container--toggle">
  <input role="switch" aria-checked="true" type="checkbox" id="toggle" class="toggle--checkbox" readonly="">
  <label for="toggle" class="toggle--label">
    <span class="toggle--label-background"></span>

   <!-- I wrapped the text in a span with the visually hidden class -->
    <span class="visually-hidden">dark mode toggle</span>

  </label>
</div>

<style>
/* This class is well tested and robust, don't use standard .sr-only classes as they do have problems in older screen readers and browser combinations */
.visually-hidden { 
    border: 0;
    padding: 0;
    margin: 0;
    position: absolute !important;
    height: 1px; 
    width: 1px;
    overflow: hidden;
    clip: rect(1px 1px 1px 1px); /* IE6, IE7 - a 0 height clip, off to the bottom right of the visible 1px box */
    clip: rect(1px, 1px, 1px, 1px); /*maybe deprecated but we need to support legacy browsers */
    clip-path: inset(50%); /*modern browsers, clip-path works inwards from each corner*/
    white-space: nowrap; /* added line to stop words getting smushed together (as they go onto seperate lines and some screen readers do not understand line feeds as a space */
}
</style>
Enter fullscreen mode Exit fullscreen mode

4. Going that extra mile!

One last thing I would suggest if you can make it work in the design, make the label visible

One thing that often gets forgotten is people with cognitive impairments.

While most people would recognise your toggle switch as a dark and light mode toggle, someone with an association impairment (where abstract graphical representations of real world objects do not get comprehended as an equivalent item - e.g. a triangle with a cross on top for a church vs a picture of a church) may not understand graphics and know what that control is for.

So this point counteracts the above point of hiding the label visually, but instead suggests using the best practice of an always visible label on every control.

This would be my suggestion, place the label just above or to the left of the toggle switch.

Keep going!

You have made some massive improvements already and I am thoroughly enjoying this series.

If you ever need help just @ me!

Great article, have a โค๐Ÿฆ„!

Collapse
 
abbeyperini profile image
Abbey Perini • Edited

Hey InHu,

  1. You can see in 3 codeblocks that I am using React's onClick handler, but I'll take a look at space!

  2. I left the animation because I liked it. IIRC, the contrast is sufficient down to small text, but I'll consider speeding it up.

  3. Ah - I added the aria-label when I was testing before I figured out which element to focus, but I did mention the warning I received about that from an automated tool and testing it in the article. The screenreader I was using did indicate "dark mode toggle, on" or "dark mode toggle, off" with the switch role and label for me, so I'll add both of these to my list to check with multiple screenreaders. I am aware of the visually hidden class, so I'll that to my Github issue for when I figure out the design for my link hover. It doesn't seem like custom/user style sheets are common enough to be a concern.

  4. Personally, I would characterize writing almost 5,000 words about accessibility in 6 days as going the extra mile. I am not focused on my site being 100% perfect from this, my first comprehensive audit. I do have at least 2 more blogs planned on the subject. Can you provide more information about an association impairment? I'm not familiar. Also, why not a visual label on hover like is recommended for the external link icon for visual users who may not know what it means? That seems like it would be much better for design, and a second use for the Github issue I linked, so I will add another note to that.

Please consider asking if a person wants feedback like this before giving it. Not everyone would be in a place to respond like this.

Collapse
 
grahamthedev profile image
GrahamTheDev

I am sorry if this came across in any way as negative, it certainly was not intended to be and was actually meant to help you further your accessibility journey!

I will refrain from saying anything further on your articles and apologise once again that this was taken as anything other than a positive comment.

I look forward to the next instalment(s), once again great article.

Thread Thread
 
abbeyperini profile image
Abbey Perini

Hey InHu,

I'm not sure what implied I was offended. I responded to your points and asked direct questions.

I'm used to getting a lot of unsolicited feedback and love learning more about accessibility. However, that level of feedback would be intimidating for a lot of people, especially beginners to accessibility, who it would seem you want to help.

Thread Thread
 
grahamthedev profile image
GrahamTheDev • Edited

I will chalk it up to a misunderstanding and phrasing issues between us both then! ๐Ÿ‘ That is the problem with the written word!

So to answer your questions:-

point 1

Yeah that might not have been clear, I was referring to vanilla JS click handler which interprets Enter and Space as a click on a form control for you.

I am guessing React does actually treat onClick as just a mouse click or a tap on touch devices.

Looks like you found a solve for this one already though so it is all good ๐Ÿ‘

Point 2

Nothing wrong with the animation, just how long it takes to show initially.

There is a perceivable delay between tabbing to the element and the outline starting to become visible, so I was just suggesting to see if you can address that if possible.

There are no other issues with the focus indicator as far as I can see!

Point 3

All good here, custom style sheets aren't that common, but they are used in maybe 3-5% (one of those made up statistics...but I did base it on experience ๐Ÿคฃ) of accessibility requirements in the sense that people use a lot of plugins and browser extensions to manipulate the page to their preferences.

You are right, it isn't going to affect a large number of people, but the principle of visually hidden text vs same colour text (same colour text is really not a good idea as it can be selected by mistake and can take up space in the layout in other scenarios etc.) is a very good principle to learn for a lot of things and will get you out of a jam when fixing accessibility issues a lot of the time, so I thought it would make great practice.

Point 4

Association impairments are rare, but certain Visual Processing Impairments (the term to search for would be "Visual Processing Disorders") can have this effect (I wish I could remember the exact condition name, but it is eluding me).

I also worked with a young lad with autism and he said that this was something he sometimes struggled with (in fact he was where I got the church example from!), but yet again I would like to point out this is not common.

The "extra mile" part was a poorly phrased way of saying "If you don't mind changing the design slightly, a visible label is always preferable and should be added".

This yet again is a general principle that is really useful to remember as visible labels on forms help in loads of ways.

As for social icons and should you add a label on hover - ideally yes and on focus too.

But bear in mind that this point is that last 1% reaching for perfection, that was why I put "extra mile" as it really is covering every last item and the sort of thing that you would see on a WCAG AAA rated site (of which there are very very few!)

You could ignore this point, just remember visible labels are always better and that will serve you well when making decisions on labelling controls.

Wrapping up

All of the above are just good practices to try and learn early on.

They are things you will come across often (keyboard interactivity problems (common), animations that need adjusting (less common), text just for Assistive Tech (very common) and permanently visible labels (extremely common!).

Although it may seem like a lot of stuff to learn just for a toggle, the principles are some of the core things you will use often fixing accessibility so they are worth practicing and getting used to as it will make the rest of the work a lot easier.

Bonus thing to look at when you have capacity!

Look into prefers-color-scheme: light when you have the chance so the site goes into light mode if someone has set that preference in their browser / OS.

Everyone always talks about it for prefers-color-scheme: dark to switch on dark mode, but as your site starts in dark mode you want to approach it from the opposite angle.

This is really minor to be clear, but a great addition once you have done everything else and just something I thought I would throw in as something interesting!

Hope that all helps, any questions just ask! โค

p.s. the fact you have written over 5000 words on accessibility is one of the reasons I reached out in the first place, I think it is fantastic! I also like the approach of telling it as a story of your journey and thought process, rather than as a guide / how to.

p.p.s. There is an article pinned in my profile "101 Digital Accessibility (a11y) tips and tricks" (4th one down), you may find it is a useful reference piece (and it is a reference piece...certainly not something to sit and read in one sitting as you will see if you read it ๐Ÿคฃ).

Thread Thread
 
grahamthedev profile image
GrahamTheDev • Edited

Thought you replied to this but it seems to have disappeared?

Anyway, I will just say the door is open if you do need anything, but I won't write an essay next time as we seem to have gotten off on the wrong foot because of it! ๐Ÿคฃ

Followed you on Twitter so I don't miss the next article! โค

Collapse
 
dailydevtips1 profile image
Chris Bongers

Nice!

Can't believe how much better you even made it!
Really need to step up my a11y game ๐Ÿ‘€

Collapse
 
abbeyperini profile image
Abbey Perini

Thank you! It's such a vast topic, and I was surprised to find out how many screenreader users don't have vision impairment!

Collapse
 
daepher profile image
Daepher

Nice ๐Ÿ”ฅ

Dark theming + Accessibility = the future. Actually, the present. Those things are already the standard for any project on the web.

Great article!

Collapse
 
abbeyperini profile image
Abbey Perini

Thank you!