Skip to content

Tag: technology

A11y 101: 2.2.2 Pause, Stop, Hide

It was Christmas Day in 2012 that I had my first major incident. You see, for as long as I could remember I suffered from migraines. I recall having to takes days off school when I was a freshman. But they started before that. At this moment in time, I was getting 20+ migraines a month. I had migraines that would last days. I had some last hours. Those were the worst. I’d start to feel better to only have another come on before the end of the day. Along with the migraines would come anxiety, nausea, dizziness, brain fog, aphasia. But that day was different.

1 Comment

A11y 101: 2.2.1 Timing Adjustable

You know the feeling. You’ve just spent the last twenty minutes filling out a form on a website. Suddenly, it asks for a specific piece of information. You need to dig for this information. You spend the next 7 minutes digging in your desk, files, computer, until you find it. Flip back to your form, and you are logged out.

If you are lucky, the form will allow you sign back in and continue from there. There’s a good chance you may need to start over. For you it is frustrating and takes time. But what if you can’t complete the form in the time given? Maybe it’s because you can’t answer the questions quickly enough.

1 Comment

A11y 101: 2.1.4 Character Key Shortcuts

Hopefully those of you working towards EAA are breathing a little easier today. While some of you were pushing last minute updates, I attended my local Pride celebration.

Well organized and attended, it reminded me why I do this work. People from 1-99+. People with visible disabilities. People with disabilities only visible because they made it so by wearing a device to control the disability (hearings aids off, headphones, walkers instead of canes). This wasn’t a celebration of LGBTQ+, this was a celebration of people being people.

1 Comment

A11y 101: 2.1.2 No Keyboard Trap

Admiral Ackbar is letting us know something important. When we navigate by keyboard, we need to make certain of one thing. Make sure that a user doesn’t get trapped with no where to go.

This seems really simple, but it gets complicated quickly. And I know what seems simple to one person is traumatically difficult for another. Let’s talk about what a trap is, some examples, and ways to prevent them.

What is a keyboard trap?

A keyboard trap is any control that receives focus, but does not release it. Usually, the keyboard is trapped from moving in any direction. Sometimes it may be trapped in one direction, generally forward.

I’ve encountered some that prevent moving forward, but allow moving backward. Usually this presents a workaround, but not always. Even if there is a word around, it is still a violation.

Often developers will put a “forward” action on an input when the content meets a certain regex or pattern. This is difficult because the input is saying, “If I have 5 numbers, tab to the next control.” This becomes a keyboard trap as the keyboard only user cannot tab back into the field to correct it.

More common though is a disclosure control that isn’t following the <h3><button>Title</button><h3> pattern. Often the button is somewhere else or outside the heading. When the control is in focus, nothing happens.

How do we test?

If you do not need a screen reader to understand the screen, turn it off. If you require a screen reader, put it in forms mode. Forms mode will only respond to Tabbing and form control with the default keys. We don’t want interference from the AT.

Tab. Again. Shift tab. Keep using tab to navigate through the page, and do it in reverse. If you get stuck, try using the Escape key. Did that get you out? if yes, did it push you backwards or forwards?

If you find you can escape the trap, try repeating the situation in both directions multiple times. If you got out, this belongs in usability advice. If you can’t get out or can’t move in both directions, you have a violation.

What is the cause?

In most cases of keyboard traps, the cause is going to be JavaScript. Typically there is a function tied to the field being focused or activated. This can cause a race condition freezing the browser. More likely, there is function that prevents tabbing out, or the function tied to moving out is not firing.

Take the object where the keyboard trap is happening. Reproduce it locally, then start stripping back all that is tied to it. For example, if you are using custom dropdown, remove all the custom code. Begin with the base HTML <select> and <option> elements.

Is there still a keyboard trap? If you extracted all JS hooks and custom HTML, there should be no trap. Once we establish that the basic HTML works, let’s expose the custom HTML.

Hide any classes tied to JS functions. Remove data attributes. Get the JS out of the way. And try it again. Is it stuck now? Then it is time to examine out HTML again. No, then we slowly start adding in JS one item at a time until we find out trap.

Time to fix it

I cannot really tell you how long to remediate this would be. Everyone’s architecture is different and will cause different problems in different ways. But finding the trap’s location might take a day. Determining the cause could also take time, even for the most skilled developer. I recall early on spending 10 hours searching for an error in my code. It turned out to be the dreaded missing semicolon. It happens to all of us. Its about how do we fix it once we know of it.

Have questions? Come talk to me on LinkedIn or BlueSky!

2 Comments

A11y 101: 1.4.13 Content on Hover or Focus

I’ll be honest, I often question if I’m evaluating this one right. Let’s look at what the text of 1.4.13:

Where receiving and then removing pointer hover or keyboard focus triggers additional content to become visible and then hidden, the following are true:

  • Dismissible: A mechanism is available to dismiss the additional content without moving pointer hover or keyboard focus, unless the additional content communicates an input error or does not obscure or replace other content;
  • Hoverable: If pointer hover can trigger the additional content, then the pointer can be moved over the additional content without the additional content disappearing;
  • Persistent: The additional content remains visible until the hover or focus trigger is removed, the user dismisses it, or its information is no longer valid.

Exception: The visual presentation of the additional content is controlled by the user agent and is not modified by the author.

Breaking this down, what does it mean?

I use my mouse or keyboard to focus on a control. When new content is exposed, I need to follow these rules.

Dismissable

I need to allow the user to dismiss this without moving the mouse or keyboard focus. OK, that is clear, but how do we do it? I can’t move the mouse, and I can’t move keyboard focus, then I need another action I can take. This is why we always implement the Escape key to close these exposed layers.

But here’s the trick…

If you hit ESC while one dialog is open, it will close. If you hit ESC while 2 or three are open, they will all close. For single page applications, or modal “sheets,” if users are several levels deep, they go back to the beginning when they hit ESC. You need to keep control of propagation as well as a track of which dialog opened which. As the user hits ESC, we need to stop propagation after closing the dialog. We also need to return focus to the control that opened it.

Hoverable

If I opened the new content with mouse, I also need to move around inside the new content. This does mean that when we are opening it, we are waiting for an exit event before we close it.

Now, that exit event could be a variety of things. Hitting ESC. Mousing over another control that exposes content. Clicking outside the container. The choices are many, but that it is clear how to do it is crucial.

Persistent

The best practice is to use an event tied to a button. This allows the keyboard user to activate the button to open it and close it. This also benefits users who rely on voice control. The mouse user can also open by clicking, or you can add hover to open the area. But mousing out on it’s own won’t close it. That needs another event that is clear the user is done with this object.

For me this is where I always got confused. What does it mean to be persistent? For how long? What if I click somewhere else on the page? Do I have to close the dialog before moving to some other control?

Persistent means once opened, it stays open until you close it. To close it you can do any of the following:

  • Escape key
  • Close button
  • Hover over another active control that exposes content
  • Click event elsewhere on the page
  • Activating a control inside the exposed content

Best practice: Use at least one in addition to the ESC key.

Have more questions? Want to discuss this? Find me on LinkedIn and BlueSky!

1 Comment

A11y 101: How to test manually

Too often, I see companies touting their high accessibility scores. They use tools like aXe Core, Lighthouse, Access Engine, or other free automated tools to derive them. But this only tells a part of the story, and it doesn’t even tell half of it. Let’s explore what is needed, why, and how we go about continuing the testing.

Important Disclosure

I work at Level Access. We have our own toolset that we use internally. While I work there, I try to remain agnostic in talking about tools and techniques.

Tools

Like any project, we need a few tools to help us do the job we’ll need.

  • Computing Device – This can be a Windows, Mac, iPhone, Android device, tablet, or even Linux. We can’t test websites without accessing them.
  • Screen reader – This will be device dependent. The Apple products have VoiceOver. Android has Talkback. For Windows, there is Narrator built in, JAWS, and NVDA. I recommend NVDA as it doesn’t lie and is free open source software. I also caution on relying on Narrator. It’s initial use was just to get someone to the point where they can download a “real” screen reader. Microsoft has continued to update it. It is acting more like a screen reader now. However, there’s still work to be done.
  • Browser – Unless you are working with VoiceOver, the recommended browser to use is Chrome. It has the largest market share and is at the tech edge of production browsers.
  • Spreadsheet – to log findings. Include columns for at least:
    • Finding description
    • Finding recommendation
    • Page found on (URL)
    • Guideline
    • Screenshot (I like to use ScreenCast for storing these images.)
    • Steps to reproduce
  • WCAG’s Quickref for the level I am testing against. I test to 2.2 A and AA as my standard.
  • Mouse
  • Keyboard (Doing a mobile audit? Use a Bluetooth keyboard without the screen reader.)
  • Automated tooling – It does help to run automatics at the beginning of an audit. It will reduce the time you spend documenting issues.
  • Contrast checker
  • Scope document
  • Objective of the audit

Setup

We’ve gathered our tools and we are ready to begin testing…or are we? The last two items I mention in the Tools section are a scope and objective. We need to know the objective of the audit. Is it to update their backlog with any accessibility issues? Is it because they need a VPAT? I ask these questions because it influences how I scope.

Scoping is an art to itself. I’ll give a brief overview here. The first part of scoping is understanding the objective and the primary flows.

Look at each primary flow. Are there shared experiences? Yes, we probably only need to test one. Do they use the same header or footer? That can be one unit to test as it is global. Identify patterns used the site and capture them. If pages use templates, say a product details page, capture one of each to test. A thorough audit will likely involve more than 10 pages or units to test. Most of my clients come in around 15-20.

If there is a need for a VPAT, we will add a few more pages. We want to make sure we capture a sample of everything. In the first audit style we may not look at the About Us, Contact, Terms & Conditions, etc. But with a VPAT to be authored, I would be reviewing these as well.

Setup your spreadsheet. I like to make pivot tables and drop downs for key sections. Like which guideline is involved, what disabilities are affected, anything where you will be repeating things from a limited collection.

Step 1 – Mouse

If your vision requires a screen reader, use it instead of the mouse.

Time to start testing. You have your scope. The key here is getting to know the site layout and functionality. Go through every single page in your scope with the mouse and only the mouse. Figure out what items are active controls and how they respond to the mouse.

Step 2 – Automatics

Now that I have familiarized myself with site, I run my automatic testing tools. Depending on the tool you use and how you have it configured, you’ll have a few ways to do this. Some tools look at one page and report findings back in the Chrome Developer tools. If they allow you to export them to a spreadsheet, collect that. You have one for each page tested to compile later. If it doesn’t export, you will need to manually copy them to your spreadsheet.

You may want to roll your own testing bot that can push content to a database. There are several free and open source tooling that will let you run a headless browser with Node.JS to make calls to pages and return the tested output. I’m now playing around with this for a different project.

Automatic tools at best cover 40% of all WCAG criteria. If a company says their AI enhanced tool does better, you may hit 50% coverage. This is because AI doesn’t understand intent, purpose, or how people think into account.

Review every automatic to make sure there are no false positives. Every company out there is saying they get fewer or no false positives. I have yet to find a tool that can honestly say “zero false positives.”

Step 2 – Keyboard

If your vision requires a screen reader, skip this step.

Keyboard testing is based off our mouse testing. We now want to navigate the site like we did in step one without the use of the mouse. We want to ensure that only active controls receive focus. We also check that controls can be used by the keyboard fully in their design. Log anything that doesn’t work properly with keyboard only. Log anything that gets focus, yet is a static element. Caveat – if the link is an in-page link and the target is static a tabindex of -1 is allowable. Repeat this until the page is completely reviewed.

Now you may want to move onto another screen, and that’s fine. Many folks like to go through a project with one tool, then the next. I test my projects by page or screen. So I go through all the steps on a screen, then mark the screen done. You do this as it best works for you.

Step 3 – Screen reader

Pick your screen reader. Remember, these are often device dependent. Repeat Step 2 with the screen reader on. Now, we are determining if the active controls have proper accessible names. Do the names include the visual text? Will they work with the screen reader?

Advice

Step 4 – Color contrast

Pick your picker! Until you are capable of computing contrast ratios with your own eyes, you will need a color contrast testing tool. There are dozens out there. My favorite is Level Access’s Accessible Color Picker. Before that it was Colour Contrast Analyzer.

Which one matters less than if it is giving you accurate ratios.

Advice

Step 5 – Reading level

You need to know the audience of the site or product you are testing. For instance, the targeted audience of this blog is people interested or involved in accessibility work. I have some basic posts, and some more advanced. My language is always meant to be as simple as possible. However, there are specific things I expect others in the domain to understand. One of these is the term WCAG.

Why do we need to know the audience? Because we need to check if the writing on the site is hitting the right audience.

For instance, providing a legal interpretation of a document. If the audience is other lawyers, you use one style. You include as much jargon and as many shortcuts as possible, because you expect them to know the domain.

If the audience is the general layperson, we need to write as if speaking to 13-year-olds. Our language should be clear and simple.

Over a decade ago, I wrote about this for the A11yProject.com. The post is still up and accurate. I’ll relist the resources for testing before the next step.

AI has many great features. One is its ability to identify when text should be simpler. I use it all the time to help clarify my writing. You may be able to use AI-based tools for this. It depends on your access to the admin portion or source code.

Resources:

Step 6 – WCAG SC

When it seems that I have completed my testing, I bring out the WCAG Quickref again. One by one, I read each guideline’s purpose and understanding. For each one, I’ll think through if I might have missed this in my testing. I check each page in scope and log anything I forgot to log earlier.

Follow Up

Now what do you do? Well, this depends on your contract. Good things to do with your client are review the list. Pull out 5-10 of the most important issues. Explain why you pulled them, their impact to users, and how to fix them. Leave them with a priority list of fixes. You could complete a VPAT and issue an ACR. You can work with their team on remediation efforts.

You don’t want to leave the client hanging. Don’t just log 100 or more bugs and walk away. Because next year when they update the product, they’ll need more testing. When they roll out a new product, they will need more testing. Help the client improve through training, fixing, or guiding them.

Don’t do this for free either. When I was independent, I would charge for the evaluation based on scope, not hours. But I’d also put in a recurring monthly support charge. This included 5 – 10 hours monthly paid up front. It is a retainer I take regardless if they use that support. If the time used in a month exceeds the retainer, that gets added to the next invoice. But now we’re entering business practices and that is a different blog post.

Happy Global Accessibility Awareness Day (GAAD)! Have questions or want to discuss this, hit me up on LinkedIn and BlueSky.

A little bonus – Level Access has a lot going on today if you’d like to check out training.

1 Comment

K.I.S.S. ARIA

Keep It Silly Simple

I sat down to review some code with my colleagues. It was clear that each of these solutions was heavily over-engineered. Each used custom web components, React, Angular, or other framework, and even basic HTML with aria added. All of them should get slimmed down and work to reduce or remove ARIA.

Comments closed

A11y 101: 1.4.10 Reflow

We live in a time where our digital device screen sizes vary. We have 1 inch watch screens, phones, tablets, and even TVs with 100 inch screens. We never know what the end use will be using for a device. Reflow is needed to adapt to many of these screens. However, the core of what reflow is about has little to do with screen size. Let’s look at what we really need to know about 1.4.10 Reflow.

320 by 256

Looking at the WCAG Quickref, we see the following:

Content can be presented without loss of information or functionality, and without requiring scrolling in two dimensions for:

  • Vertical scrolling content at a width equivalent to 320 CSS pixels;
  • Horizontal scrolling content at a height equivalent to 256 CSS pixels;

Except for parts of the content which require two-dimensional layout for usage or meaning.

Reflow talks about having no loss of functionality without having to scroll in two directions on screens as small as 256 pixels wide. It tells us that when the screen is at 256 pixels wide we can have horizontal scrolling, but not vertical. At 320, we can have vertical but not horizontal scrolling.

As a matter of good web principle, it is better to design vertically than horizontally in the majority of cases. For news, reading, and shopping it is easier to consume the content and it is the expected method of scrolling.

But what does it mean if not mobile?

Remember, we are talking about web content accessibility guidelines. For whatever reason, every time I discuss reflow with developers they automatically think it is for mobile devices. And yes, it benefits everyone on any device when implemented correctly. But so does just about everything listed under WCAG (Not all screen reader techniques benefit the able-bodied). And there is a key word that gets left out during those conversations.

Accessibility

This guideline is about making websites more accessible. Reflow wants to ensure that the site does not hide any functionality when any user is on the site. It should not obstruct, obscure, or remove functionality. This includes when that user adjusts their monitor to a different resolution.

A huge number of people on this planet have issues with vision. For most of them, a pair of glasses will correct it. We’re told by our doctors that 20/20 is the most accurate a human can expect. When a person’s vision reaches 20/200 after correction, they are considered legally blind. They have some vision though and decide to increase the resolution on their screen to read it easier. Likely they may not be aware of screen readers yet. Our volunteer here increases his screen resolution to 300% at which he can read it.

When discussing this addition to the guidelines, 1280×1024 was the most dominant screen size for desktops and laptops. There was also thinking that most disabled people are on fixed income and can’t afford current tech. This lead to thinking the disabled to be on older devices.

If we were to increase our zoom from 100% to 400% starting at 1280×1024, the page is rendered at 320×256. If something requires two way scrolling at this point, you need to revisit the reflow rules. We do not want to remove functionality, but it is ok if functionality goes into a menu or disclosure. We want to stack content in the scroll direction.

There are pieces of content that can have horizontal scrolling including carousels and tables. With carousels, ensure the controls are on the screen, but the contents can overflow. You can swipe, but provide buttons for fallback. For tables, ensure the header column is always visible with at least one other full column.

How to test

I’m not writing to a generic audience here. I hope you have deduced a method for testing, but I won’t leave you hanging. Testing is simple, set you browser viewport to 1280 by 1024. Load the page, then use Control/Command and the plus (+) key until you reach 400% zoom. Review the content to ensure nothing is removed. Make sure content is stacked or hidden by disclosures. Ensure there is no horizontal scrolling. You can flip the dimensions for horizontal scrolling sites.

Alternatively, open your developer tools in mobile emulation. You can leave zoom at 100%. Change the viewport to 320×256.

Have some thoughts or more questions on Reflow? Find me on LinkedIn or Bluesky to keep the conversation going.

3 Comments

A11y 101: 1.3.1 Info and Relationships

Whenever I come across a a violation of 1.3.1, I have a primal need to look deeper. I investigate because I believe if something falls under this success criterion, it is most likely improperly classified. It is extremely important that we understand the relevant context, information and relationships of content. Frequently, I observe that this particular success criterion is misused. It often serves as a catch-all for “Where does this go?”

So then what does go here?

Per WCAG, 1.3.1 Info and Relationships is:

Information, structure, and relationships conveyed through presentation can be programmatically determined or are available in text.

Cool. We used the original words to define it. I didn’t like third grade English when I was in third grade.

Let’s look at the intent:

The intent of this Success Criterion is to ensure that information and relationships that are implied by visual or auditory formatting are preserved when the presentation format changes. For example, the presentation format changes when the content is read by a screen reader or when a user style sheet is substituted for the style sheet provided by the author.

Now this is better. We’re given a breakdown and example. The intent is to ensure that what is visually indicated as structural, explanatory, and informational is available to everyone. This includes people using different presentation formats.

Structural

When talking about structure, it is crucial to distinguish between visual structure and code structure. We need to consider both.

When we look at our mock-up of a page, we want to absorb it visually. Is the most important item in the page grabbing the eye? Does the way it is designed lead you to the next thing you want to say or a primary CTA

(Call to Action)? Take it all in, then we start deciding what HTML elements best represent all those pieces of the page. We begin to think of how we order them. Should it be in a landmark like header, aside, footer, main, or nav? Or is does it need a textual element like headings, anchors, paragraphs, lists, or quotes?

Information

We need to ensure that any information expressed visually is communicated non-visually. If a button is disabled, how do we inform a screen reader user it is disabled? How does a screen reader user know if a Menu is opened? This is the information we should be looking for. In many cases ARIA attributes will be the answers to provide this information.

Relationships

Under relationships we find little programmatic lines connecting the page together. We might specify via aria-label that the first navigation is the “Primary navigation.” Forms point to a more direct relationship in how we set up labels, inputs, and error messages. Using the label’s “for” attribute we build a relationship of the name and input. Aria-describedby with the ID of an error message is another bridge creating a relationship.

Here’s my problem

Much of the time these are not errors of information or relationships. They’re a failure of properly using HTML or ARIA. Sometimes both.

In my example of using the landmarks to construct the basic layout, it isn’t a violation. But we didn’t provide an accessible name. That’s a violation of 4.1.2, so why dump it here?

My disabled button? Case of missing aria-disabled, a 4.1.2 issue.

Headings used out of order? Not a WCAG SC.

Headings not sized to their importance? Now you have a 1.3.1 violation! The visual size provides a hierarchy of importance. On the code side we do this with heading elements H1 – H6.

The Fix

Info and relationships are important on the web. They provide context and details that may not be picked up right away. Anything we do on this account visually needs to be conveyed programmatically too. But that doesn’t mean everything that falls into this bucket belongs. Dumping things in here can harm your clients. You might not provide them enough context to resolve their issues.

Look deeper at the issue. Is it a matter of a screen reader not announcing something? Look at the code, is it missing ARIA? Does it apply to another criteria? Make sure you flag it the right way. And don’t flag it twice, once here and once under the other SC. If it fits under another SC, then fixing it under that criteria will fix it for 1.3.1 as well.

Have a thought, feedback or concern about this article, let’s discuss it on BlueSky or LinkedIn.

Comments closed