Design Systems Carnival! One Accessible Component, Many Pretty Masks

Rate this content
Bookmark

Design System components are like guests at a Venetian Carnival, enjoying the festivities. One guest — the disclosure widget — wears three distinct masks, elevating a Carnival to a Masquerade Ball. Or… is it? What kind of Carnival are you attending if those masks get mixed? In this talk, you’ll learn the secret to creating a reusable — and accessible — component that can masquerade as many and give your component library access to the most exclusive of Carnival attractions.

27 min
13 Nov, 2023

Video Summary and Transcription

The Talk discusses the concept of design system Carnival and its relation to masks. It emphasizes the importance of accessibility in design systems and provides guidelines for implementing the Disclosure So Hide pattern. The Talk also covers topics like focus management, mouse interactions, and extending the disclosure widget. It warns against mixing different roles and complexity in design systems, using the example of a carousel. Overall, the Talk highlights the challenges and considerations in creating effective design systems.

Available in Español

1. Introduction to Design System Carnival

Short description:

Welcome, everyone. I am Kathleen McMahon, and I'm here today to talk about design system Carnival. My presentation will be posted on notice. That is https://notist.org. Including links to resources. After my talk. Some time. I'll also post the full URL on Twitter. I refuse to call it X. On Twitter. Some time after my presentation. You can follow me. At resource 11 on Twitter, Instagram, GitHub, Mastodon, Blue Sky. Wherever you can find me. Resource 11.

Welcome, everyone. I am Kathleen McMahon, and I'm here today to talk about design system Carnival. One accessible component. Many pretty masks.

And before we begin, let's get some details out of the way. Let's make sure my clicker is working. It is not. Rad. Go! Now, it is success. My presentation will be posted on notice. That is https://notist.org. Including links to resources. After my talk. Some time.

And my nose is running. Why is my nose running? I'll also post the full URL on Twitter. I refuse to call it X. On Twitter. Some time after my presentation. You can follow me. At resource 11 on Twitter, Instagram, GitHub, Mastodon, Blue Sky. Wherever you can find me. Resource 11.

And who am I again? Let me back up and introduce myself a little bit better. I am an engineer, I am a designer and I am a speaker. I am occasional cyclocross racer. In costume, of course. Very bad racer. I love lights. Going to the beach, collecting sand dollars.

2. Design System Carnival and Masks

Short description:

It's literally the where's Waldo of the ocean. I have worked on a few design systems including a O'Reilly media, Watch Darkly, Most Recently, Most Recently, Northwestern Mutual, and I love design systems. They are always the hotness. And design systems are like herding kittens. Always fun. A lot of moving parts. And I think design systems are like a carnival. And what do I mean by that? So, when I visited Venice last fall, I was fascinated by the masks. I love their beauty. And their variety. And they were everywhere in Venice. And I learned that masks have a rich history of providing access and helping a person to blend in to hide their gender, their identity, their social class.

It's literally the where's Waldo of the ocean. Love my cats Thor and Otis. And I collect a ridiculous amount of crystals. Thanks, COVID. Hobbies. And I photograph them. But Otis has many opinions. He interferes. And he has opinions on where I should put my attentions. Thanks, Otis. And now Thor has learned to do the same with my sand dollar collection. He's very satisfied with himself. But who could resist them? And this is how me as a neuro spicy sparkly individual shakes off my anxiety. So yay for being neuro spicy.

I have worked on a few design systems including a O'Reilly media, Watch Darkly, Most Recently, Most Recently, Northwestern Mutual, and I love design systems. They are always the hotness. That T-Rex always gets me every time. Who doesn't love a T-Rex, right? And design systems are like herding kittens. Always fun. A lot of moving parts. And I think design systems are like a carnival. And what do I mean by that? So, when I visited Venice last fall, I was fascinated by the masks. I love their beauty. And their variety. And they were everywhere in Venice. Everywhere you look. In the shops. The souvenirs. And I even made my own mask. And I learned that masks have a rich history of providing access and helping a person to blend in to hide their gender, their identity, their social class.

3. Design System Carnival and Accessibility

Short description:

Masks like the bauta, maretta, gagna, and harlequin provide access and freedom. Accessibility is often handled last, leaving users behind. The WebAimillion report shows concerning results, with a significant increase in ARIA attributes and detected errors. The ARIA authoring practices guide provides guidelines and examples, including the disclosure widget for pop-ups, toggle tips, and toggle searches.

And some of the well-known masks are the bauta, the maretta, the gagna, and the harlequin. And wearing these masks gives you access and to access places with more freedom. Like this parade of gondolas during the Venice's carnival.

Similar to a design system, when well-crafted, masks can create consistency of experience. So is this experience consistent for everyone, though? Let's talk accessibility. Our users have different needs at different times. From vision, hearing, motor skills, cognitive, sensory, language, low bandwidth needs. Our users have different needs and so often, accessibility is what is handled last. So we don't want to leave our users behind.

So what does this mean about accessible design components in general? Well, there is this report called the WebAimillion. And it's been released for the past five years now. And if you've read the results, they're a bit concerning. It's an accessibility analysis of the top one million homepages. And I'm going to focus only on the ARIA attributes present on the homepage. There has been up to a 29% increase in added ARIA attributes in the past year alone. And in the past five years, the amount of ARIA attributes has nearly quadrupled since 2019. That means over 68% more detected errors on the homepages than those without additional ARIA attributes present. That means that our developers are meaning well, but they are making the web worse in the spirit of good intentions.

So what can we do about this? The ARIA authoring practices guide page, or APG for short, has created these resources which are amazing for us and they are guidelines for us to follow. They are practices, design patterns, and examples, like the disclosure widget, and if built correctly, can have a few uses in your design system. It can be used for things like pop-ups, toggle tips, and toggle searches. Now I'm going to make a disclosure on my disclosure. So my talks are usually deep dives on how to build a piece of accessible component in every minute detail, but our talk is 20 minutes. And you all want to get to Q&As and to get to that barcade. So I'm going to keep it high level because this could literally be a 45-minute talk and I don't want to do that to you. I want to be kind. So I'm going to go a bit faster. But I share code examples with all my talks, with all my notes, and so I will provide all that in links with my talks afterwards so you won't miss anything. You'll have all of that in this afterwards, after the fact, so not to worry. So the anatomy of a disclosure widget is a button that opens and closes a container and returns focus to that button.

4. Implementing the Disclosure So Hide Pattern

Short description:

The WAI site or the APG site has a pattern called the Disclosure So Hide pattern. It provides guidelines for implementing keyboard interactions, ARIA support, and state management. By using the appropriate attributes and hooks in React, you can create a disclosure widget that allows users to open and close containers with ease. Additionally, you can enhance the widget with features like focus management, ensuring a seamless user experience.

And the WAI site, or the APG site, has a pattern for that. It's called the Disclosure So Hide pattern. It's documented. And you have to have these three primary keyboard interactions to solve that criteria. You have to support, say, space bar and enter key presses, escape key presses, mouse clicks.

And to do that in React, you start with JSX button element, which, under the hood, renders an HTML button element, which, by default, supports mouse clicks, enter key presses, and space bar key presses for free. Magic. Awesome. So, once you have that, that's when you add just enough ARIA support to let screen readers know when that widget is going to be opened and closed. And in the case of if you have many widgets on the page, which container on that page is being opened and closed?

So on our button, we are going to add the ARIA controls attribute to tell assistive technology which element the button is controlling. In this case, it is the container's ID. And then we are going to add ARIA expanded to tell whether the widget is expanded or not. It's Boolean. And ARIA label in cases where we need a more accurate button label, especially if we are doing icon buttons. And then we are going to add state and click handlers to toggle the container open and closed. So when we do that, we are going to use the use date hook. And define set as open and initialize use date to false. And optionally, we are going to set a default expanded prop to use date for those cases when we have to have our widget open by default. For example, if you are working at a bank and you have to have a terms of service, widget open by default. That is something that banks have to do. So it is nice to have that prop in your component.

Then, when you have that state defined, you can pop it into a toggle open function and toggle that set is open to false with that toggle open function. Pop that function into your on click handler. And then in your buttons re-expanded prop, the re-expanded prop will communicate whether it is open to a false depending on that is open prop. Then, in your div, you can pop that is open prop with the children and only render the children if that is open prop is true. Now you have the basics of disclosure widget. Then you can add a little bit of enhancements, like if you want to take it a little bit further with UX, like focus management. And this is like the advance. The enhanced pattern for disclosure widgets. For example, when you use the escape key, when you close the widget with the escape key, it will return focus right back to that button.

5. Implementing Focus and Mouse Click Management

Short description:

To enable focus management, create a button ref, initialize useRef to null, and listen for ESC key presses. Test with assistive technology users and normalize CSS focus states. Set a consistent three-to-one contrast ratio for interactive controls. Customize other styles as needed. Implement mouse click management with a content ref and a click outside handler.

So you can create, use the ref, create a button ref, initialize useRef to null, and then create onKeyUp handler, listen for esc key presses of the key code of 27 and whether the state is open. And if it's open, set toggle is open to false. And then set the current ref to focus. And then on the wrapper div, have your key up handler function, put that handler function to the synthetic event wrapper div and pass that button ref to the button.

And going back for a second. Now your widget is set up for focus management. Which is cool. Now this is an extended pattern which is awesome. But I'm going to make a caveat. Always test this with assistive technology users. Because you want to make sure that everyone who's using assistive technology is having the experience that you expect. So don't leave out those assistive technology users when you're doing this.

Now, before we go on, make sure you're normalizing your CSS focus states. Don't hide them. You can do this star global, normalize your focus states by doing star, the pseudo focus state like this and put the outline to zero. But if you do that, replace it with something else. And this way you could have a just a generic, nice, consistent style throughout everything in your components. And then what you can do, and here you can set a consistent three-to-one contrast ratio because that is for focus states, that is for interactive controls. It has to be a minimum of three to one for interactive controls, border to background. Or three to one or greater. And then for any of your other styles, then you can customize. For your buttons, I want something different. But at least you have it normalized for everything about your site. You have a normalized focus state and then you can customize on one-offs. So it's a really nice way to get everything consistent.

Once you have that, you can do mouse click management. And then you can do another ref for your content ref. Customize that to null and pass that into your wrapper div. And then you have a click outside handler. What this is doing is listening for if you are clicking outside your target.

6. Implementing Mouse Interactions and Icons

Short description:

To manage mouse interactions, use the useRef hook and event listeners for mouse up and key up. Implement a cleanup function to remove stray event listeners. This can be used to create toggle tips, which are different from tooltips. Icons can be informative or decorative. Use the Font Awesome icon react component to render SVG icons and pair them with ARIA labels for accessibility.

So if that ref, if the ref contains the target, so if you're clicking inside the target, the window, the div will stay open. But if you click outside the target, set is open to false. Close your widget. This is nice if you have many widgets on the page. This will close that widget. You won't have all these widgets stuck open on the page. So this is nice for mouse management.

And when you have that handle, you can use the use effect hook and listen for if this is open, you add an event listener from mouse up and key up and pass in that handler for a callback. And so if it's open, pass in that event listener. Otherwise, remove the event listener. And then do a cleanup function to remove any stray event listeners from running. And then to prevent re-renders, pass in that is open variable in there to the last array to make sure that you're preventing re-renders. Now you have a pretty beefy disclosure widget.

And that's where people are gonna start getting a little clever, like oh, this is cool. We can use this to make toggle tips, which are not tooltips. They're different. Because toggle tips contain interactive content and they're supported by touch devices, non-mouse pointers and eye trackers where tooltips are not. And what's nice about this is people are gonna use this, and I know you're gonna go back and do this instead. I know you all are gonna do this. So if you're gonna do this, we're gonna talk about icons.

So with icons, they can be either informative or decorative. So with informative icons, they need to have descriptive text paired with them, and decorative icons need to be hidden from assistive technology because they don't have any value other than decoration. So in order to do this, we will add in a new component to the mix and that will be the for me I use the Font Awesome icon react component because it's great because under the hood they use SVGs and they prep them in a way that make them decorative by default. And they prep the SVGs to make them decorative and then you can pair them with ARIA labels to make them informative as you need. So in here, I only render them if the icon prop is passed in at the button level. And if the icon is passed in, you can render the Font Awesome icon, pass in the icon, style it if you want and then add it if you want a large or a small icon. So it's pretty cool. And then you can pair that icon with a visible button text if you want. Or you can pair it with an ARIA label and pass it in... Woo! Wow! All right.

7. Implementing the Disclosure Widget

Short description:

Pass in a button with custom classes and ARIA label. Extend the widget with a disclosure containing a search form. Use targeted focus management to set focus on open. Prevent re-renders by optimizing the use effect. This extends the functionality of the widget.

Pass it in with a button... And also make sure if it's an icon only button, you're making sure you're adding an ARIA label in there. And you can also have custom classes to override the styles. And what's also nice in there is in your disclosure widget for when you're extending this widget, you can pass in things like a div and some other... A paragraph in there. And pass in an aria label, an icon, and... Whether it's an icon only button. And... Some more classes. And boom! Toggled it. And it's accessible.

And then you can do the same thing with that same pattern and make a disclosure with a toggle search, with an embedded search form. You take the same disclosure widget, pop in a form, as children, and you can use targeted focus management. So what we're gonna do here is passing in some button text and some icon and putting in the on submit and preventing the default action, and then adding in some search and value... You know, the labels and the names and the type of... It's a search... I gotta read my stuff because I'm trying to keep everything on time. Since everything is embedded in the form, we are getting our button attribute for free. We are gonna do... I'm just gonna talk really quickly about targeted focus management. We are doing first item reference, the targeted focus management. So basically when you open the widget, you can set focus right to the first... My brain just exited ADHD. Come back! When you open the widget, I'm gonna send it right to the input. So you basically have this first item ref. You're also gonna pass that input ref right to that first item ref and how you do this in your use effect, there's a nested if. If it's open and if you have a first item ref, focus it and put that first item ref as the second item in the array of your array at the bottom. So you prevent re-renders. And that is how you can have targeted focus management for your disclosure widget. And this is where you're like, oh, this is extending things.

8. Extending the Disclosure Widget

Short description:

I have this really cool disclosure widget that can be extended to include hamburger navigation and restyled to look like links. It can also incorporate an unordered list with links and be used as a toggle menu link.

This is really cool. I have this really cool disclosure widget. And that's when you have this really cool thing and it starts getting tricky because this is where a designer starts handing you things like hamburger navigation. You're like, oh, I can add this to our disclosure widget. And this looks like a hamburger nav, but these look like buttons, but maybe they're links. So let's like restyle them to look like links to communicate the intent. And then I could add it into this widget, like pop in an unordered list with some links into this disclosure widget. Awesome! Cool. Map in some links. That could be cool. I could make a toggle menu link out of this disclosure widget. Kind of nice. Let's start extending this pattern a little more.

9. Adding Buttons and Roving Focus

Short description:

Let's add buttons and implement roving focus to the disclosure widget. We can create a custom tag instead of a list item and add any HTML element we want. This is super efficient and allows for concise code. No big deal.

Oh, maybe we could use some buttons here. No problem. This is a really powerful pattern. Let's add some buttons. No problem. Links are buttons. No big deal. Let's do buttons. Cool. Map it with keys, buttons. Nice.

How about we do some roving focus? So when you have buttons and things, why don't we add some keyboard support if we go up and down with the arrows? We can add some roving focus to this disclosure widget. That could be really fun. Let's add a handler with callbacks and states and effects and add a roving focus hook here. That could be fun. Let's add that to our disclosure widget. So we're going to add this, and we're going to add this roving focus function to see if we're looking for key codes and with length. And we're going to add this to our widget with a callback. And that's kind of nice.

But then what about rather than list, what if we make a custom tag? Instead of a list item and a button or a link, I can just create a custom tag. A constant tag equals tag, and I can pass in any tag I want, link, button, P tag, anything. This is super efficient. I can pass in any HTML element I want here. I am saving time now. This is awesome. I can do all this stuff, pass in, spread in my props, and then I can add in this menu item. This is really nice. This is so concise now. So tagpalooza, and I have some new roles, another ARIA role in here. No big deal.

10. Mixing Roles and Complexity

Short description:

And then we will have some separation of concerns in here with our roaming focus, our unordered lists, and we have list item component now, and now we have our menu buttons, and now we have a list item component, we have the fancy tag. But is this a good idea? Because what pattern have we gone from? We've gone from a disclosure widget to a menu and a menu bar. It's just important to keep your users separate, otherwise you are beginning to make unwise decisions like creating dishes with jello and shellfish and things can go wrong very quickly. But it's very important to remember do not mix the masks, because if you mix the masks, things can start to go wrong. Chaos can start to happen and people can get very chaotic. And if you get even more complex, they can go even worse. Because when you get too complex, eventually you end up with a carousel in your design system. In your design system. Oh my God.

And then we will have some separation of concerns in here with our roaming focus, our unordered lists, and we have list item component now, and now we have our menu buttons, and now we have a list item component, we have the fancy tag. And then maybe we should have some ternary magic. Maybe we can add a list. Maybe we can add this link list or button list. Or maybe we can do the roaming focus. Or maybe we can do this other thing. Look how big this disclosure widget is starting to get. It's getting pretty big, right? I mean, if it's open, if it's a list, you can do just the widget, or we can do, like, the children, so we can get really fancy. A list or children. But is this a good idea? Or is it not a good idea? Because what pattern have we gone from? We've gone from a disclosure widget to a menu and a menu bar. We have changed ARIA roles here by getting all clever and starting adding tags and roles and menu lists. So we just over-complexified our life. And by doing that, we have confused our screen reader users because we're just looking at something visually and just shoving things into this one component. So it's not a good idea to start mixing these roles. And you just started creating this mega menu pattern and then you might start adding in check box and links and even a menu has a list item role and a check box has a radio list role, I believe. So it's just getting really tough. So whoa, what are we doing? It's just important to keep your users separate, otherwise you are beginning to make unwise decisions like creating dishes with jello and shellfish and things can go wrong very quickly. I literally have had this slide in every single talk I've done since 2019, by the way, I'm very proud. But it's very important to remember do not mix the masks, because if you mix the masks, things can start to go wrong. Chaos can start to happen and people can get very chaotic. And I can just sit there. I think I have little lights. I don't know if my lights are going to work. I can make it work. I'm going to find my lights. My lights? My lights are working. But, if you get even more complex, they can go even worse. Because when you get too complex, eventually you end up with a carousel in your design system. In your design system. Oh my God.

11. The Dangers of Mixing Masks

Short description:

I have a carousel. I don't want a carousel in my design system but I love my carousel. This is my favorite carousel. So do not mix your masks, if you can help it. Design Systems are always the hotness.

I have a carousel. I don't want a carousel in my design system but I love my carousel. This is my favorite carousel. Oh my gosh. Nice clip. Nice clip. I'll take it. Nice clip. Nice and some dinosaurs, everyone. This is epic. The dinosaur is epic. God, it's amazing. It's amazing. See, I ended up with a carousel. Let's go wrong.

So I do have to say though, the Open UI W3C community is working on a solution, for example, on disclosure widgets, and so there will be a solution for native components coming for disclosure widgets so we won't have to rebuild this soon. So I'm just very happy to say that's coming. But I want to say, avoid chaotic carnivals like the one you just saw, if you can, and also like the one on the screen here, which is the Via Reggio Carnival, which has some extremely large floats in Italy, and otherwise you'll have a completely different experience than you wanted. So do not mix your masks, if you can help it.

So to wrap up, Design Systems, our carnival, our users are diverse... Don't mix your masks, don't mix your masks! or you'll make bad choices, and you may end up at a completely different carnival than you expected. And an experience that you did not want. And Design Systems are always the hotness.

Check out more articles and videos

We constantly think of articles and videos that might spark Git people interest / skill us up or help building a stellar career

TestJS Summit 2021TestJS Summit 2021
30 min
Configuring Axe Accessibility Tests
Top Content
Axe-core is a popular accessibility testing engine that is used Google, Microsoft, and hundreds of other companies to ensure that their websites are accessible. Axe-core can even integrate into many popular testing frameworks, tools, and IDEs. In this advanced session, we'll be learning how to configure axe and its integrations to fine tune how it runs and checks your pages and code for accessibility violations.
JSNation 2023JSNation 2023
10 min
Dialog Dilemmas and Modal Mischief: A Deep Dive Into Pop-Ups
Our design systems commonly feature components that show on top of other content: tooltips, date pickers, menus and teaching UI, to name just a few. Proposed updates to the web platform are about to make building these a whole lot easier. You might not even need JavaScript. In this talk, you’ll learn all about the upcoming ‘popover’ attribute, modality and the top layer.
JSNation 2022JSNation 2022
24 min
a11y and TDD: A Perfect Match
Accessibility has been web development's ugly duckling for quite some time now. I often get asked, "when should you test for a11y in your apps?" My answer is simple, "right from the start!". Regardless of the framework considered - React, Svelte, Vue, YourOwn™️ - as developers we are in a privileged position to help the ugly duckling grow into a beautiful swan. How? By diving deep into the pond and harnessing the power of Javascript APIs to build the right components for your web apps. And how can do you know you are building them right? By pairing Test Driven Development with the Testing Library family. Ready to grow your web apps into swans?
React Advanced Conference 2021React Advanced Conference 2021
32 min
How to do Good Without Doing Anything
There’s no arguing that building accessible websites is a force for good. But ensuring that our React websites and apps work for everyone can be time-consuming and isn’t always easy to get right. Luckily, investing a little bit of time on your accessibility workflow and setting up a series of automated tools will end up saving you tons of time and energy in the long run.In this talk I will demonstrate how you can leverage automated tools, clearly documented code standards and a well-defined development process in order to make building and testing accessible React apps a breeze. I will discuss the ways that I automate certain aspects of my development workflows to catch accessibility errors, define and set up tests and go through the entire lifecycle of accessibility feature development using a real-world example.
JSNation 2023JSNation 2023
30 min
Accessible Component System Through Customization
Most current UI libraries provide great user experience with a vast of components. But when it comes to heavy customization, and non-standard scenarios, especially for E-Commerce, they become hard to manage, scale or even slow down performance.
How to create a UI library that provides users the most possible freedom in customizing components, while keeping our performance and scalability to the fullest? How much accessible we can provide out of the box to our users? How much customization freedom is enough?
That's what my talk's about.

Workshops on related topic

React Summit 2023React Summit 2023
109 min
Web Accessibility for Ninjas: A Practical Approach for Creating Accessible Web Applications
Workshop
In this hands-on workshop, we’ll equip you with the tools and techniques you need to create accessible web applications. We’ll explore the principles of inclusive design and learn how to test our websites using assistive technology to ensure that they work for everyone.
We’ll cover topics such as semantic markup, ARIA roles, accessible forms, and navigation, and then dive into coding exercises where you’ll get to apply what you’ve learned. We’ll use automated testing tools to validate our work and ensure that we meet accessibility standards.
By the end of this workshop, you’ll be equipped with the knowledge and skills to create accessible websites that work for everyone, and you’ll have hands-on experience using the latest techniques and tools for inclusive design and testing. Join us for this awesome coding workshop and become a ninja in web accessibility and inclusive design!
TestJS Summit 2021TestJS Summit 2021
85 min
Automated accessibility testing with jest-axe and Lighthouse CI
Workshop
Do your automated tests include a11y checks? This workshop will cover how to get started with jest-axe to detect code-based accessibility violations, and Lighthouse CI to validate the accessibility of fully rendered pages. No amount of automated tests can replace manual accessibility testing, but these checks will make sure that your manual testers aren't doing more work than they need to.
React Summit 2022React Summit 2022
161 min
Web Accessibility in JavaScript Apps
Workshop
Often we see JavaScript damaging the accessibility of a website. In this workshop, you’ll learn how to avoid common mistakes and how to use JS in your favor to actually enhance the accessibility of your web apps!
In this workshop we’ll explore multiple real-world examples with accessibility no-nos, and you'll learn how to make them work for people using a mouse or a keyboard. You’ll also learn how screen readers are used, and I'll show you that there's no reason to be afraid of using one!
Join me and let me show you how accessibility doesn't limit your solutions or skills. On the contrary, it will make them more inclusive!
By the end, you will:- Understand WCAG principles and how they're organized- Know common cases where JavaScript is essential to accessibility- Create inclusive links, buttons and toggleble elements- Use live regions for errors and loading states- Integrate accessibility into your team workflow right away- Realize that creating accessible websites isn’t as hard as it sounds ;)
React Summit Remote Edition 2021React Summit Remote Edition 2021
91 min
Creating Accessible React Native Apps
Workshop
React Native is a framework used to create native iOS and Android apps in a way web developers may already be familiar with. But how do you ensure your React Native apps are inclusive and usable everyone? Scott will share tips on how to test and build React Native apps with accessibility baked-in!