accessibility – CSS-Tricks https://css-tricks.com Tips, Tricks, and Techniques on using Cascading Style Sheets. Wed, 14 Dec 2022 14:08:21 +0000 en-US hourly 1 https://wordpress.org/?v=6.1.1 https://i0.wp.com/css-tricks.com/wp-content/uploads/2021/07/star.png?fit=32%2C32&ssl=1 accessibility – CSS-Tricks https://css-tricks.com 32 32 45537868 Unchain My Inaccessibly-Labelled Heart https://css-tricks.com/unchain-my-inaccessibly-labelled-heart/ https://css-tricks.com/unchain-my-inaccessibly-labelled-heart/#comments Wed, 14 Dec 2022 14:08:20 +0000 https://css-tricks.com/?p=375952 Suzy Naschansky from the HTMHell Advent Calendar:

<h2 id="article1-heading"All About Dragons</h2<pI like dragons. Blah blah blah blah blah.</p<p<a id="article1-read-more" aria-labelledby="article1-read-more article1-heading"Read more</a</p

See that aria-labelledby attribute? It chains two IDs from the …


Unchain My Inaccessibly-Labelled Heart originally published on CSS-Tricks, which is part of the DigitalOcean family. You should get the newsletter.

]]>
Suzy Naschansky from the HTMHell Advent Calendar:

<h2 id="article1-heading">All About Dragons</h2>  
<p>I like dragons. Blah blah blah blah blah.</p>  
<p>
  <a id="article1-read-more" aria-labelledby="article1-read-more article1-heading">Read more</a>  
</p>  

See that aria-labelledby attribute? It chains two IDs from the markup, one for the heading (#article1-heading) and one for the link (#article1-read-more). What happens there is a screenreader will replace the existing semantic label between the link tags and use the content from both elements and announce them together as a single string of text:

Read more All About Dragons

I’m always sheepish when realizing there’s something I think I should know but don’t. This is definitely one of those cases and I’m thankful as all heck that Suzy shared it.

I was actually in a situation just recently where I could’ve should’ve done this. I always try to avoid a bunch of “Read more” links on the same page but coming up with different flavors of the same thing is tough when you’re working with something like a loop of 15 posts (even though there are resources to help). And if we need to keep labels short for aesthetic reasons — design requirements and whatnot — it’s even more challenging. The aria-labelledby attribute gives me exactly what I want: consistent visual labels and more contextual announcements for assistive tech.

And this is only a thing when the text you want to use for the accessible label already exists on the page. Otherwise, you’d want to go with aria-label and with the caveat that it’s purely for interactive elements that are unable to label things accessibly with semantic HTML.

If you are working in a CMS like WordPress (which I am), you might need to do a little extra work. Like when I drop a Button block on the page, these are the options I have to work with:

Some nice options in there, but nothing to do with accessible labelling. If you’re wondering what’s buried in that Advanced panel:

Close, but no cigar.

Instead, you’ll need to edit the button in HTML mode:

But before doing that, you gotta add an ID to the heading you want to use. The Heading block has the same Advanced panel setting for adding an anchor, which’ll inject an ID on the element:

Then you can go edit the Button block in HTML mode and add the accessible-labels ID as well as an ID for the button itself. This is an example of the edited markup:

<div class="wp-block-buttons">
  <!-- wp:button -->
  <div class="wp-block-button">
    <a id="read-more-button" aria-labelledby="read-more-button heading-accessible-labels" class="wp-block-button__link wp-element-button" href="https://webaim.org/projects/million/">
      Read Report
    </a>
  </div>
  <!-- /wp:button -->
</div>

Great! But WordPress just ain’t cool with that:

You can try to resolve the issue:

Le sigh. The Button block has to be converted to a Custom HTML block. Kinda defeats the whole visual editing thing that WordPress is so good at. I did a super quick search for a plugin that might add ARIA labelling options to certain blocks, but came up short. Seems like a ripe opportunity to make one or submit PRs for the blocks that could use those options.


Unchain My Inaccessibly-Labelled Heart originally published on CSS-Tricks, which is part of the DigitalOcean family. You should get the newsletter.

]]>
https://css-tricks.com/unchain-my-inaccessibly-labelled-heart/feed/ 2 375952
Setting up a screen reader testing environment on your computer https://css-tricks.com/setting-up-a-screen-reader-testing-environment-on-your-computer/ https://css-tricks.com/setting-up-a-screen-reader-testing-environment-on-your-computer/#respond Mon, 12 Dec 2022 20:56:58 +0000 https://css-tricks.com/?p=375722 Sara Soueidan with everything you need, from what screen reading options are out there all the way to setting up virtual machines for them, installing them, and confguring keyboard options. It’s truly a one-stop reference that pulls together disparate …


Setting up a screen reader testing environment on your computer originally published on CSS-Tricks, which is part of the DigitalOcean family. You should get the newsletter.

]]>
Sara Soueidan with everything you need, from what screen reading options are out there all the way to setting up virtual machines for them, installing them, and confguring keyboard options. It’s truly a one-stop reference that pulls together disparate tips for getting the most out of your screen reading accessibility testing.

Thanks, Sara, for putting together this guide, and especially doing so while making no judgments or assumptions about what someone may or may not know about accessibility testing. The guide is just one part of Sara’s forthcoming Practical Accessibility course, which is available for pre-order.

To Shared LinkPermalink on CSS-Tricks


Setting up a screen reader testing environment on your computer originally published on CSS-Tricks, which is part of the DigitalOcean family. You should get the newsletter.

]]>
https://css-tricks.com/setting-up-a-screen-reader-testing-environment-on-your-computer/feed/ 0 375722
A Brief Introduction to JAWS, NVDA, and VoiceOver https://css-tricks.com/comparing-jaws-nvda-and-voiceover/ https://css-tricks.com/comparing-jaws-nvda-and-voiceover/#comments Thu, 01 Sep 2022 17:47:16 +0000 https://css-tricks.com/?p=372855 A screen reader is an important accessibility tool for people with no or limited vision. People who are blind or those with low vision can use a screen reader to navigate the computer. Screen readers will read contents on the …


A Brief Introduction to JAWS, NVDA, and VoiceOver originally published on CSS-Tricks, which is part of the DigitalOcean family. You should get the newsletter.

]]>
A screen reader is an important accessibility tool for people with no or limited vision. People who are blind or those with low vision can use a screen reader to navigate the computer. Screen readers will read contents on the screen and explain to the user what is on the page. Screen readers allow people to use the computer for daily tasks.

There are many screen reader software available for people through their operating system or through open source projects.

A 2021 research by WebAim found that from 1568 responders, more than 53.7 percent of people surveyed used JAWS on Windows, more than 30.7 percent of people used NVDA on Windows and little over 6.5 percent of people used VoiceOver on macOS.

JAWS and NVDA for Windows and VoiceOver for macOS are the most popular screen readers people use.

First, I should clarify that this article will be written from my point of view. To give background, I have been a front-end developer at a non-profit for people with learning differences for over three years. I, along with my colleagues, seek to make our projects more accessible every day. I am not visually impaired and do not use these tools on a regular basis. For work, I have a Mac machine and test accessibility using VoiceOver.

Here is my planned testing methodology:

  1. Navigate the page by heading, until “Accessibility APIs” section.
  2. In the “Accessibility APIs” section, read the content and the unordered list inside.
  3. TAB to hear focusable items in the unordered list.
  4. Jump to the Search field.
  5. TAB to hear a few items in the navigation section

To find similarities and differences between them, I decided to test a set of steps with each screen reader on a Wikipedia page about screen readers. I will browse the web with Chrome for my tests. Testing all screen readers on the same page and browser will reduce the amount of variables and keep the tests consistent.

JAWS

JAWS is an acronym for Job Access With Speech and is the most widely used screen reader in the world. It is only available on Windows. Depending on the plan and features, JAWS can be purchased anywhere from $90 yearly license all the way to $1605 for perpetual license.

JAWS has predefined keyboard commands to navigate the web. Full list of keyboard commands can be found on their website.

Demonstration

JAWS Demo

In the beginning of the demo, I am clicking on H key on my keyboard to go to the next heading. JAWS is moving down the page, reading me the headings along with their level.

Later in the video, I am clicking on number 2 and number 3 on my keyboard to have JAWS read Heading Levels 2s then later Heading Levels 3s. This is a great feature because we can move down the page and sections by heading level and get a better sense of the page layout.

When I reach the “Accessible APIs” section, I press the DOWN ARROW key until the third item in the unordered list.

Later in the demo, I am clicking on the TAB key for JAWS to read to me the next focusable item on the page, which is inside this list. I click TAB until I reach a focusable element in another section.

Then I press F key to focus on the search field, which JAWS reads to me.

Then I click on TAB and JAWS focuses on the navigation elements that are on the side of the page.

Pros & Cons

Pros:

  • JAWS is more customizable than other screen readers.
  • There are more options to navigate through the page.
  • JAWS is industry standard.
  • Widely used, which means there are lots of user to user support.

Cons:

  • JAWS is more complicated to use than NVDA or VoiceOver.
  • Some commands are not intuitive.
  • There are a lot more commands for the user to learn.
  • More learning curve for users.
  • JAWS is also not available on the Mac, which limits its users.
  • Costs anywhere between $90 – $1605 for the user.
  • JAWS has different key commands for desktop and laptop which may make it harder for users to transfer knowledge and may cause confusion.

NVDA

NVDA, or NonVisual Digital Access, is available on Windows only. Users need to download the software from NVDA’s website, NVAccess. This software is free to download but does not come already installed on Windows machines. NVDA is the second most popular screen reader in the world according to WebAim’s 2021 survey.

Like other screen readers, NVDA has defined keyboard commands to navigate the web. NVDA’s full keyboard commands can be found on their website.

Demonstration

NVDA Demo

In the demo I am clicking on H key on the keyboard to go to the next heading. First, NVDA reads me Heading Level 1, which is “Screen reader”. Then NVDA goes to read Heading Level 2s and 3s.

When I reach “References” I begin to click on TAB on my keyboard for NVDA to focus on next focusable items.

After focusing on a few items on the list, I click ENTER and go to the New York Times page.

Pros & Cons

Pros:

  • Overall, I found NVDA was able to provide me with information on the screen.
  • The out-of-the-box keyboard commands were easy to use and easy to learn.
  • NVDA is open source, which means the community can update and fix.
  • NVDA is free, which makes it an affordable option to Windows users.

Cons:

  • NVDA is not available on the Mac, which limits its users.

VoiceOver

VoiceOver is the screen reader used in Mac. VoiceOver is only available on Mac not available in Windows. VoiceOver is free and is already installed on the computer, which removes barriers because this is part of the computer setup and the user does not have to download or purchase any additional software.

VoiceOver has defined keyboard commands to navigate the web. VoiceOver’s full keyboard commands can be found on their website.

Demonstration

VoiceOver Demo

In the demo, I am on a Wikipedia page and I am clicking on the VoiceOver Command (which is Control+Option) along with Command+H to navigate through the headings. VoiceOver reads the headings in order, starting from Heading Level 1, “Screen Reader”, to Heading Level 2, “Contents”, to Heading Level 3, and so on.

When I reach the “Accessibility APIs” section, I click on VoiceOver Command plus the RIGHT ARROW, to tell VoiceOver that I want it to read this section. Later I am clicking on the VoiceOver Command plus the RIGHT ARROW on my keyboard, to navigate the section.

When I get on to the third item on the unordered list, I press TAB on my keyboard to focus on the next focusable element.

I press TAB a few times, then I press VoiceOver Command plus U, to open the Form Control Menu. In the menu, I press DOWN ARROW until I hear the “Search Wikipedia” option. When I hear it, I click ENTER and the screen reader focuses on the form field. In the form field, I press TAB to navigate to the navigation section.

Pros & Cons

Pros:

  • VoiceOver is easy to use and learn.
  • VoiceOver’s commands are intuitive.
  • Free tool that comes installed in every macOS device.

Cons:

  • VoiceOver is also not available on Windows, which limits its users.
  • VoiceOver is not an app and can only be updated when Apple releases macOS update.

Key Takeaways

A screen reader is an important accessibility tool for people with no or limited vision. Screen readers allow people to use the computer for daily tasks.

There are many screen reader softwares available. In this article I compared JAWS, NVDA, and VoiceOver.

Here is a comparison chart overview of the three screen readers:

JAWSNVDAVoiceOver
Operating SystemWindowsWindowsmacOS
Price$90 – $1695FreeFree
# of users50%30%6%
Ease of Use (subjective)HardEasyEasy

I found that for basic screen reader testing, most screen readers follow a similar keystroke pattern and knowledge from one screen reader can be used for others.

All screen readers have their pros and cons. Ultimately, it’s up to user preference and also the operating system they use to determine which screen reader software is best for them.

Previously: “Small Tweaks That Can Make a Huge Impact on Your Website’s Accessibility” (2018), and “Why, How, and When to Use Semantic HTML and ARIA” (2019), “15 Things to Improve Your Website Accessibility” (2020), “5 Accessibility Quick Wins You Can Implement Today” (2022).


A Brief Introduction to JAWS, NVDA, and VoiceOver originally published on CSS-Tricks, which is part of the DigitalOcean family. You should get the newsletter.

]]>
https://css-tricks.com/comparing-jaws-nvda-and-voiceover/feed/ 15 https://player.vimeo.com/video/742100446 accessibility Archives - CSS-Tricks nonadult 372855
Roundup of Recent Document Outline Chatter https://css-tricks.com/roundup-of-recent-document-outline-chatter/ https://css-tricks.com/roundup-of-recent-document-outline-chatter/#comments Thu, 21 Jul 2022 14:04:34 +0000 https://css-tricks.com/?p=367048 It’s not everyday that HTML headings are the topic de jour, but my folder of saved links is accumulating articles about the recently merged removal of the document outline algorithm in the WHATWG Living Standard.

First off, you should know …


Roundup of Recent Document Outline Chatter originally published on CSS-Tricks, which is part of the DigitalOcean family. You should get the newsletter.

]]>
It’s not everyday that HTML headings are the topic de jour, but my folder of saved links is accumulating articles about the recently merged removal of the document outline algorithm in the WHATWG Living Standard.

First off, you should know that the algorithm never really existed. Sure, it was in the spec. And sure, there was a warning about using it in the spec. But no browser ever implemented it, as Bruce Lawson reminded us. We have been living in a flat document structure the whole time.

This is very old news. Adrian Roselli has been writing about the document outline myth since 2013. But it’s his 2016 post titled “There Is No Document Outline Algorithm” that comprehensively spells it out and has been updated regularly with extra nuggets of context about the conversations and struggles that got us here. This is really the best timeline of the saga. Amelia Bellamy-Royds has also delved into the roots of the dilemma in the past here on CSS-Tricks.

My mind instantly goes to all the work that’s gone into the making of a document outline algorithm that supports sectioning. Removing it from the spec is the right call for sure, but it doesn’t take away from the herculean efforts that went into it even if it is now buried in some version history. I also think about all the well-intentioned folks who have written about the algorithm erroneously over time (including on this very site!) with the expectation that it was just around the corner. There’s nearly seven years of mental and technical debt that we’ve accrued from what appear to be a lack of action.

Looking past the “news” that the algorithm is officially no more, Bruce laments that there is no generic <h> element or the like that can be sectioned to produce the correct heading level. I agree. Having an <h1> element essentially exist as an exposed <title> is constraining, particularly since pages are so rarely structured around a single article with a single top-level heading. I often find myself wincing every time I’m making some sort of card component where using <h3> might be technically correct, but feels out of order. And that’s before we even talk about the styling considerations where a lower heading level now needs to look like a distinct higher heading level.

Speaking of heading level management, Steve Faulkner (who authored the PR that plucked the algorithm from the spec) has a super practical overview of using the <hgroup> element to handle heading patterns that involve subheadings, subtitles, alternative titles, snd taglines. I’m sure you’ve seen markup like this in the wild:

<h1>Disappointingly Average</h1>
<h2>The Autobiography of Geoff Graham</h2>
<h3>by Geoff Graham</h3>

That doesn’t jive with a flat document outline that’s driven by heading levels. Each one of those headings represents a section that forms a hierarchy of information:

Disappointingly Average
└── The Autobiography of Geoff Graham
    └── by Geoff Graham

What we want instead is a group of headings. Cue the <hgroup> element:

When nested within a <hgroup> element, the <p> element’s content represents a subheading, alternative title, or tagline which are not included in the document outline.

So, we get this structure:

<hgroup>
  <h1>Disappointingly Average</h1>
  <p>The Autobiography of Geoff Graham</p>
  <p>by Geoff Graham</p>
</hgroup>

<hgroup> is role=generic at the moment, but Steve points to a proposal that could map it to role=group. If that happens, the accessibility tree will allow assistive tech to assign more semantic meaning to those paragraphs as the subtitle and tagline pieces that they are. Sounds easy but Steve notes challenges that are in the way. He also demos how this sort of pattern could be implemented today with ARIA attributes.

As long as we’re rounding things up, Matthias Ott published a few tips on creating a structured outline with headings. Check out the end for a great list of tools to check your heading outlines.


Roundup of Recent Document Outline Chatter originally published on CSS-Tricks, which is part of the DigitalOcean family. You should get the newsletter.

]]>
https://css-tricks.com/roundup-of-recent-document-outline-chatter/feed/ 2 367048
5 Accessibility Quick Wins You Can Implement Today https://css-tricks.com/5-accessibility-quick-wins-you-can-implement-today/ https://css-tricks.com/5-accessibility-quick-wins-you-can-implement-today/#comments Wed, 23 Feb 2022 15:15:33 +0000 https://css-tricks.com/?p=363532 Let’s face it: building an AA or AAA-accessible product can be quite daunting. Luckily, having an accessible product isn’t all-or-nothing. Even seemingly small improvements can have nice quality of life benefits for many people.

In that spirit, here are five …


5 Accessibility Quick Wins You Can Implement Today originally published on CSS-Tricks, which is part of the DigitalOcean family. You should get the newsletter.

]]>
Let’s face it: building an AA or AAA-accessible product can be quite daunting. Luckily, having an accessible product isn’t all-or-nothing. Even seemingly small improvements can have nice quality of life benefits for many people.

In that spirit, here are five accessibility quick wins you can implement today.

Quick Win 1: Indicate the Current Page

It’s probably safe to assume that a different style is the most common way to communicate the current page of a site or app. However, even if those styles are clear and with great contrast ratios, they’re still only a visual cue.

So what happens if a person with limited vision cannot see that separation? How will they know what page they’re on?

Creating an accessible product is to ensure its markup communicates as clearly as its design.

Adding aria-current="page" to the active navigation element is one way to ensure markup and design communicate the same information with or without assistive technologies.

<a aria-current="page" href="/">Home</a>

? Bonus

Use CSS attribute selectors to style the aria-current="page" element to keep the visual and markup cues linked.

[aria-current="page"] { 
  /* Active element styles */
}

Quick Win 2: Document Language

While some people can visit a website and determine the language or locale of its content, not all people have that luxury. Again, markup must communicate the same information as the visual design — even if that information may seem implied.

Add the lang attribute to the <html> tag to communicate not only the document’s language, but its locale. This will help assistive technologies like screen readers understand and communicate the content. Even if the app only supports one language, this can be a nice quality of life improvement for many people.

<html lang="en-US">

For apps which support multiple languages, the <html> element is likely not the only one to need its lang value defined. Use the lang attribute on specific elements whose language differs from the rest of the document, like links within a language toggle menu. In this case, pair the use of lang with the hreflang attribute to not only communicate the language of the link itself, but also of its destination.

<a lang="fi" hreflang="fi" href="/" title="Suomeksi">
  <bdi>Suomeksi</bdi>
</a>

Quick Win 3: Use prefers-reduced-motion

Whether drawing attention to actions or updates, or creating a sense of life and charm, adding motion to an app can really elevate its experience. However, some people may find that experience disorienting.

Windows and MacOS both offer a setting at the OS level for people to greatly reduce the amount of motion when using their systems. The prefers-reduced-motion setting can greatly improve the experience on a computer, but it does not extends beyond the UI of the operating system. So wouldn’t it be nice if our apps could respect that same system setting and provide a more static experience for those who prefer it?

Well, with CSS media queries, they can.

The prefers-reduced-motion media query can be used to greatly reduce or remove all motion from an app whenever the system setting is enabled.

@media (prefers-reduced-motion: reduce) {
  * {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
}

The blanket approach shown here prevents all motion, but it can leave little room for nuance. It’d be best to review the needs of those using the product, but consider these other options as well.

One approach could be to only animate one property at a time in prefers-reduced-motion settings. So consider a <Modal /> that fades and scales into view with opacity and transform. In reduced motion environments, only the opacity would transition. The scaling effect would be removed as they are more commonly problematic than fading.

Another option could be to look at the prefers-reduced-motion environment a bit more literally and remove all motion. This would do away with our scaling modals, sliding drawers, and bouncing notifications, but would still leave room for color transitions on links and buttons.

Quick Win 4: Indicate Data Sorting State

A common theme across all of these tips is to ensure that an app’s visual design and markup communicate the same things. So, when the design uses an arrow to indicate the sort direction of a table column, how can that also be communicated in the markup?

Setting the aria-sort attribute to ascending /descending on the header of the actively-sorted column allows the markup to communicate the same content structure as a visual indicator in the UI.

This will help ensure that people using assistive technologies and those who aren’t can understand the content in the same way.

<thead>
  <tr>
    <th>First Name</th>
    <th aria-sort="ascending">Last Name</th>
  </tr>
</thead>

Quick Win 5: Lazy Loading Lists

Whether scrolling through an endless stream of tweets or through an impossible-to-decide list of products, the web has fully embraced lazy loading long lists of data (and alliteration, apparently).

This is when the aria-setsize and aria-posinset attributes become very valuable. While a person’s progression through the list can be communicated visually in many different ways, these attributes are used to communicate that same progression to many assistive technologies.

As developers, we likely have access to the length of an entire list as well as the index of the current items being displayed. With that, the aria-setsize attribute would define the total length of the list, while the aria-posinset attribute would define an item’s specific position (or index) within that list.

If the total length of the list is not known, then aria-setsize should be set to -1.

With these attributes, assistive technologies can better interpret a list and a person can better understand their position within it.

<h2 id="top-artists-title">Top Artists of 2021</h2>
<ul role="listbox" aria-labelledby="top-artists-title">
  <li role="option" aria-setsize="20" aria-posinset="5">Bloodbound</li>
  <li role="option" aria-setsize="20" aria-posinset="6">Manimal</li>
  <li role="option" aria-setsize="20" aria-posinset="7">Powerwolf</li>
</ul>

Take a listen to how these attributes are announced using MacOS VoiceOver.

? Bonus Win: Axe-DevTools Extension

Implementing those five accessibility quick wins is a great start, but that’s exactly what it is —a start. There’s a sprawling landscape of assistive technologies and sets of abilities a person can posses, and navigating it all alone can feel overwhelming.

Fortunately, there are plenty of tools to help with auditing a product’s accessibility that make the journey much more manageable. My personal favorite — my trusty accessibility compass — is the Axe-DevTools browser extension.

Running the Axe-DevTools accessibility scanner can return tons of valuable information. Not only will it display all issues and warnings found on the page, but it groups them by approximate severity. It can also highlight the element on the page or in the Elements tab and provide links to learn more about the specific issue.

However, most importantly, it will offer clear and concise approaches to fix the specific issue.

A screenshot of an Axe-DevTools accessibility report. Using the extension can lead to accessibility quick wins.

Wrapping Up

A product isn’t made accessible overnight; nor is a product’s accessibility work ever really complete. Like anything else on the web, accessibility evolves and requires maintenance. However, even seemingly small additions can have an impact on a product’s accessibility and a person’s overall experience.

After stepping into a new codebase, these are often some of the first few things I look into — some “low-hanging fruit” of accessibility, if you will.

Reaching AAA or even AA conformance can feel like scaling an 8,000 meter peak. These steps won’t carry you to the summit, but an expedition is never completed in a single stride.

Resources


5 Accessibility Quick Wins You Can Implement Today originally published on CSS-Tricks, which is part of the DigitalOcean family. You should get the newsletter.

]]>
https://css-tricks.com/5-accessibility-quick-wins-you-can-implement-today/feed/ 4 https://player.vimeo.com/video/672659433 aria-setsize-demo nonadult 363532
Why Don’t Developers Take Accessibility Seriously? https://css-tricks.com/why-dont-developers-take-accessibility-seriously/ https://css-tricks.com/why-dont-developers-take-accessibility-seriously/#comments Mon, 24 Jan 2022 14:49:18 +0000 https://css-tricks.com/?p=360811 You know that joke, “Two front-end developers walk into a bar and find they have nothing in common”? It’s funny, yet frustrating, because it’s true.

This article will present three different perspectives on accessibility in web design and development. Three …


Why Don’t Developers Take Accessibility Seriously? originally published on CSS-Tricks, which is part of the DigitalOcean family. You should get the newsletter.

]]>
You know that joke, “Two front-end developers walk into a bar and find they have nothing in common”? It’s funny, yet frustrating, because it’s true.

This article will present three different perspectives on accessibility in web design and development. Three perspectives that could help us bridge the great divide between users and designers/developers. It might help us find the common ground to building a better web and a better future.

The corner of a white and blue building in focus, with white on the left and blue on the right representing the divide between developers when it comes to accessibility practices.
Photo by Alexander Naglestad on Unsplash

Act 1

“I just don’t know how developers don’t think about accessibility.”

Someone once said that to me. Let’s stop and think about it for a minute. Maybe there’s a perspective to be had.

Think about how many things you have to know as a developer to successfully build a website. In any given day, for any given job position in web development, there are the other details of web development that come up. Meaning, it’s more than “just” knowing HTML, CSS, ARIA, and JavaScript. Developers will also learn other things over the course of their careers, based on what they need to do.

This could be package management, workspaces, code generators, collaboration tools, asset loading, asset management, CDN optimizations, bundle optimizations, unit tests, integration tests, visual regression tests, browser integration tests, code reviews, linting, formatting, communication through examples, changelogs, documentation, semantic versioning, security, app deployment, package releases, rollbacks, incremental improvements, incremental testing, continuous deployments, merge management, user experience, user interaction design, typography scales, aspect ratios for responsive design, data management, and… well, the list could go on, but you get the idea.

As a developer, I consider myself to be pretty gosh darn smart for knowing how to do most these things! Stop and consider this: if you think about how many people are in the world, and compare that to how many people in the world can build websites, it’s proportionally a very small percentage. That’s kind of… cool. Incredible, even. On top of that, think about the last time you shipped code and how good that felt. “I figured out a hard thing and made it work! Ahhhhh! I feel amazing!”

That kind of emotional high is pretty great, isn’t it? It makes me smile just to think about it.

Now, imagine that an accessibility subject-matter expert comes along and essentially tells you that not only are you not particularly smart, but you have been doing things wrong for a long time.

Ouch. Suddenly you don’t feel very good. Wrong? Me?? What??? Your adrenaline can even kick in and you start to feel defensive. Time to stick up for yourself… right? Time to dig those heels.

The cognitive dissonance can even be really overwhelming. It feels bad to find out that not only are you not good at the thing you thought you were really good at doing, but you’ve also been saying, “Screw you, who cares about you anyway,” to a whole bunch of people who can’t use the websites you’ve helped build because you (accidentally or otherwise) ignored that they even existed, that you ignored users who needed something more than the cleverness you were delivering for all these years. Ow.

All things considered, it is quite understandable to me that a developer would want to put their fingers in their ears and pretend that none of this has happened at all, that they are still very clever and awesome. That the one “expert” telling you that you did it wrong is just one person. And one person is easy to ignore.

end scene.

Act 2

“I feel like I don’t matter at all.”

This is a common refrain I hear from people who need assistive technology to use websites, but often find them unusable for any number of reasons. Maybe they can’t read the text because the website’s design has ignored color contrast. Maybe there are nested interactive elements, so they can’t even log in to do things like pay a utility bill or buy essential items on their own. Maybe their favorite singer has finally set up an online shop but the user with assistive technology cannot even navigate the site because, while it might look interactive from a sighted-user’s perspective, all the buttons are divs and are not interactive with a keyboard… at all.

This frustration can boil over and spill out; the brunt of this frustration is often borne by the folks who are trying to deliver more inclusive products. The result is a negative feedback cycle; some tech folks opt out of listening because “it’s rude” (and completely missing the irony of that statement). Other tech folks struggle with the emotional weight that so often accompanies working in accessibility-focused design and development.

The thing is, these users have been ignored for so long that it can feel like they are screaming into a void. Isn’t anyone listening? Doesn’t anyone care? It seems like the only way to even be acknowledged is to demand the treatment that the law affords them! Even then, they often feel ignored and forgotten. Are lawsuits the only recourse?

It increasingly seems that being loud and militant is the only way to be heard, and even then it might be a long time before anything happens.

end scene.

Act 3

“I know it doesn’t pass color contrast, but I feel like it’s just so restrictive on my creativity as a designer. I don’t like the way this looks, at all.”

I’ve heard this a lot across the span of my career. To some, inclusive design is not the necessary guardrail to ensure that our websites can be used by all, but rather a dampener on their creative freedom.

If you are a designer who thinks this way, please consider this: you’re not designing for yourself. This is not like physical art; while your visual design can be artistic, it’s still on the web. It’s still for the web. Web designers have a higher challenge—their artistic vision needs to be usable by everyone. Challenge yourself to move the conversation into a different space: you just haven’t found the right design yet. It’s a false choice to think that a design can either be beautiful or accessible; don’t fall into that trap.

end scene.

Let’s re-frame the conversation

These are just three of the perspectives we could consider when it comes to digital accessibility.

We could talk about the project manager that “just wants to ship features” and says that “we can come back to accessibility later.” We could talk about the developer who jokes that “they wouldn’t use the internet if they were blind anyway,” or the one that says they will only pay attention to accessibility “once browsers make them do it.”

We could, but we don’t really need to. We know how these these conversations go, because many of us have lived these experiences. The project never gets retrofitted. The company pays once to develop the product, then pays for an accessibility audit, then pays for the re-write after the audit shows that a retrofit is going to be more costly than building something new. We know the developer who insists they should only be forced to do something if the browser otherwise disallows it, and that they are unlikely to be convinced that the inclusive architecture of their code is not only beneficial, but necessary.

So what should we be talking about, then?

We need to acknowledge that designers and developers need to be learning about accessibility much sooner in their careers. I think of it with this analogy: Imagine you’ve learned a foreign language, but you only learned that language’s slang. Your words are technically correct, but there are a lot of native speakers of that language who will never be able to understand you. JavaScript-first web developers are often technically correct from a JavaScript perspective, but they also frequently create solutions that leave out a whole lotta people in the end.

How do we correct for this? I’m going to be resolute here, as we all must be. We need to make sure that any documentation we produce includes accessible code samples. Designs must contain accessible annotations. Our conference talks must include accessibility. The cool fun toys we make to make our lives easier? They must be accessible, and there must be no excuse for anything less This becomes our new minimum-viable product for anything related to the web.

But what about the code that already exists? What about the thousands of articles already written, talks already given, libraries already produced? How do we get past that? Even as I write this article for CSS-Tricks, I think about all of the articles I’ve read and the disappointment I’ve felt when I knew the end result was inaccessible. Or the really fun code-generating tools that don’t produce accessible code. Or the popular CSS frameworks that fail to consider tab order or color contrast. Do I want all of those people to feel bad, or be punished somehow?

Nope. Not even remotely. Nothing good comes from that kind of thinking. The good comes from the places we already know—compassion and curiosity.

We approach this with compassion and curiosity, because these are sustainable ways to improve. We will never improve if we wallow in the guilt of past actions, berating ourselves or others for ignoring accessibility for all these years. Frankly, we wouldn’t get anything done if we had to somehow pay for past ignorant actions; because yes, we did ignore it. In many ways, we still do ignore it.

Real examples: the Google Developer training teaches a lot of things, but it doesn’t teach anything more than the super basic parts of accessibility. JavaScript frameworks get so caught up in the cleverness and complexity of JavaScript that they completely forget that HTML already exists. Even then, accessibility can still take a back seat. Ember existed for about eight years before adding an accessibility-focused community group (even if they have made a lot of progress since then). React had to have a completely different router solution created. Vue hasn’t even begun to publicly address accessibility in the core framework (although there are community efforts). Accessibility engineers have been begging for inert to be implemented in browsers natively, but it often is underfunded and de-prioritized.

But we are technologists and artists, so our curiosity wins when we read interesting articles about how the accessibility object model and how our code can be translated by operating systems and fed into assistive technology. That’s pretty cool. After all, writing machine code so it can talk to another machine is probably more of what we imagined we’d be doing, right?

The thing is, we can only start to be compassionate toward other people once we are able to be compassionate toward ourselves. Sure, we messed up—but we don’t have to stay ignorant. Think about that time you debugged your code for hours and hours and it ended up being a typo or a missing semicolon. Do you still beat yourself up over that? No, you developed compassion through logical thinking. Think about the junior developer that started to be discouraged, and how you motivated them to keep trying and that we all have good days and bad. That’s compassion.

Here’s the cool part: not only do we have the technology, we are literally the ones that can fix it. We can get up and try to do better tomorrow. We can make some time to read about accessibility, and keep reading about it every day until we know it just as well as we do other things. It will be hard at first, just like the first time we tried… writing tests. Writing CSS. Working with that one API that is forever burned in our memory. But with repetition and practice, we got better. It got easier.

Logically, we know we can learn hard things; we have already learned hard things, time and time again. This is the life and the career we signed up for. This is what gets us out of bed every morning. We love challenges and we love figuring them out. We are totally here for this.

What can we do? Here are some action steps.

Perhaps I have lost some readers by this point. But, if you’ve gotten this far, maybe you’re asking, “Melanie, you’ve convinced me, but what can I do right now?” I will give you two lists to empower you to take action by giving you a place to start.

Compassionately improve yourself:

  1. Start following some folks with disabilities who are on social media with the goal of learning from their experiences. Listen to what they have to say. Don’t argue with them. Don’t tone police them. Listen to what they are trying to tell you. Maybe it won’t always come out in the way you’d prefer, but listen anyway.
  2. Retro-fit your knowledge. Try to start writing your next component with HTML first, then add functionality with JavaScript. Learn what you get for free from HTML and the browser. Take some courses that are focused on accessibility for engineers. Invest in your own improvement for the sake of improving your craft.
  3. Turn on a screen reader. Learn how it works. Figure out the settings—how do you turn on a text-only version? How do you change the voice? How do you make it stop talking, or make it talk faster? How do you browse by headings? How do you get a list of links? What are the keyboard shortcuts?

Bonus Challenge: Try your hand at building some accessibility-related tooling. Check out A11y Automation Tracker, an open source project that intends to track what automation could exist, but just hasn’t been created yet.

Incrementally improve your code

There are critical blockers that stop people from using your website. Don’t stop and feel bad about them; propel yourself into action and make your code even better than it was before.

Here are some of the worst ones:

  1. Nested interactive elements. Like putting a button inside of a link. Or another button inside of a button.
  2. Missing labels on input fields (or non-associated labels)
  3. Keyboard traps stop your users in their tracks. Learn what they are and how to avoid them.
  4. Are the images on your site important for users? Do they have the alt attribute with a meaningful value?
  5. Are there empty links on your site? Did you use a link when you should have used a button?

Suggestion: Read through the checklist on The A11y Project. It’s by no means exhaustive, but it will get you started.

And you know what? A good place to start is exactly where you are. A good time to start? Today.


Featured header photo by Scott Rodgerson on Unsplash


Why Don’t Developers Take Accessibility Seriously? originally published on CSS-Tricks, which is part of the DigitalOcean family. You should get the newsletter.

]]>
https://css-tricks.com/why-dont-developers-take-accessibility-seriously/feed/ 27 360811
8 Helpful Accessibility Links for January 2022 https://css-tricks.com/8-accessibility-links-january-2022/ https://css-tricks.com/8-accessibility-links-january-2022/#respond Thu, 13 Jan 2022 20:57:41 +0000 https://css-tricks.com/?p=360939 Every now and then, I find that I’ve accumulated a bunch of links about various things I find interesting. Accessibility is one of those things! Here’s a list of related links to other articles that I’ve been saving up and …


8 Helpful Accessibility Links for January 2022 originally published on CSS-Tricks, which is part of the DigitalOcean family. You should get the newsletter.

]]>
Every now and then, I find that I’ve accumulated a bunch of links about various things I find interesting. Accessibility is one of those things! Here’s a list of related links to other articles that I’ve been saving up and think are worth sharing.

Screenshot of the Accessibility Maze homepage.

8 Helpful Accessibility Links for January 2022 originally published on CSS-Tricks, which is part of the DigitalOcean family. You should get the newsletter.

]]>
https://css-tricks.com/8-accessibility-links-january-2022/feed/ 0 360939
Empathetic Animation https://css-tricks.com/empathetic-animation/ https://css-tricks.com/empathetic-animation/#comments Wed, 29 Dec 2021 16:04:16 +0000 https://css-tricks.com/?p=358975 Animation on the web is often a contentious topic. I think, in part, it’s because bad animation is blindingly obvious, whereas well-executed animation fades seamlessly into the background. When handled well, animation can really elevate a website, whether it’s just …


Empathetic Animation originally published on CSS-Tricks, which is part of the DigitalOcean family. You should get the newsletter.

]]>
Animation on the web is often a contentious topic. I think, in part, it’s because bad animation is blindingly obvious, whereas well-executed animation fades seamlessly into the background. When handled well, animation can really elevate a website, whether it’s just adding a bit of personality or providing visual hints and lessening cognitive load. Unfortunately, it often feels like there are two camps, accessibility vs. animation. This is such a shame because we can have it all! All it requires is a little consideration.

Here’s a couple of important questions to ask when you’re creating animations.

Does this animation serve a purpose?

This sounds serious, but don’t worry — the site’s purpose is key. If you’re building a personal portfolio, go wild! However, if someone’s trying to file a tax return, whimsical loading animations aren’t likely to be well-received. On the other hand, an animated progress bar could be a nice touch while providing visual feedback on the user’s action.

Is it diverting focus from important information?

It’s all too easy to get caught up in the excitement of whizzing things around, but remember that the web is primarily an information system. When people are trying to read, animating text or looping animations that play nearby can be hugely distracting, especially for people with ADD or ADHD. Great animation aids focus; it doesn’t disrupt it.

So! Your animation’s passed the test, what next? Here are a few thoughts…

Did we allow users to opt-out?

It’s important that our animations are safe for people with motion sensitivities. Those with vestibular (inner ear) disorders can experience dizziness, headaches, or even nausea from animated content.

Luckily, we can tap into operating system settings with the prefers-reduced-motion media query. This media query detects whether the user has requested the operating system to minimize the amount of animation or motion it uses.

Screenshot of the user preferences settings in MacOS, open to Accessibility and displaying options for how to display things, including one option for reduce motion, which is checked.
The reduced motion settings in macOS.

Here’s an example:

@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
}

This snippet taps into that user setting and, if enabled, it gets rid of all your CSS animations and transitions. It’s a bit of a sledgehammer approach though — remember, the key word in this media query is reduced. Make sure functionality isn’t breaking and that users aren’t losing important context by opting out of the animation. I prefer tailoring reduced motion options for those users. Think simple opacity fades instead of zooming or panning effects.

What about JavaScript, though?

Glad you asked! We can make use of the reduced motion media query in JavaScript land, too!

let motionQuery = matchMedia('(prefers-reduced-motion)');

const handleReduceMotion = () => {
  if (motionQuery.matches) {
    // reduced motion options
  }
}

motionQuery.addListener(handleReduceMotion);
handleReduceMotion()

Tapping into system preferences isn’t bulletproof. After all, it’s there’s no guarantee that everyone affected by motion knows how to change their settings. To be extra safe, it’s possible to add a reduced motion toggle in the UI and put the power back in the user’s hands to decide. We {the collective} has a really nice implementation on their site

Here’s a straightforward example:

Scroll animations

One of my favorite things about animating on the web is hooking into user interactions. It opens up a world of creative possibilities and really allows you to engage with visitors. But it’s important to remember that not all interactions are opt-in — some (like scrolling) are inherently tied to how someone navigates around your site.

The Nielson Norman Group has done some great research on scroll interactions. One particular part really stuck out for me. They found that a lot of task-focused users couldn’t tell the difference between slow load times and scroll-triggered entrance animations. All they noticed was a frustrating delay in the interface’s response time. I can relate to this; it’s annoying when you’re trying to scan a website for some information and you have to wait for the page to slowly ease and fade into view.

If you’re using GreenSock’s ScrollTrigger plugin for your animations, you’re in luck. We’ve added a cool little property to help avoid this frustration: fastScrollEnd.

fastScrollEnd detects the users’ scroll velocity. ScrollTrigger skips the entrance animations to their end state when the user scrolls super fast, like they’re in a hurry. Check it out!

There’s also a super easy way to make your scroll animations reduced-motion-friendly with ScrollTrigger.matchMedia():


I hope these snippets and insights help. Remember, consider the purpose, lead with empathy, and use your animation powers responsibly!


Empathetic Animation originally published on CSS-Tricks, which is part of the DigitalOcean family. You should get the newsletter.

]]>
https://css-tricks.com/empathetic-animation/feed/ 3 358975
Some Articles About Accessibility I’ve Saved Recently IV https://css-tricks.com/some-articles-about-accessibility-ive-saved-recently-iv/ https://css-tricks.com/some-articles-about-accessibility-ive-saved-recently-iv/#comments Fri, 29 Oct 2021 18:28:38 +0000 https://css-tricks.com/?p=354581
  • A guide to designing accessible, WCAG-compliant focus indicators — Sara Soueidan says you can make more accessible focus outlines by doing your own, rather than leaving it to the browser — as long as you do it right. Deep dive!

  • Some Articles About Accessibility I’ve Saved Recently IV originally published on CSS-Tricks, which is part of the DigitalOcean family. You should get the newsletter.

    ]]>
  • A guide to designing accessible, WCAG-compliant focus indicators — Sara Soueidan says you can make more accessible focus outlines by doing your own, rather than leaving it to the browser — as long as you do it right. Deep dive!
  • a11y-syntax-highlighting — Eric Bailey’s repo of code syntax highlighting themes for a variety of software that are both attractive and meet WCAG color contrast guidelines (including support for Windows High Contrast mode as well).
  • Respecting Users’ Motion Preferences — Michelle Barker with a guide on when and how to honor people’s prefers-reduced-motion setting. While there is no one right way, it should be done. It’s interesting how many things might apply. Properties like transition and animation are fairly obvious, but did you think of scroll-behavior or things specifically in JavaScript (where you can also test for a preference)?
  • Accessibility testing — Jeremy Keith: “When you commission an accessibility audit, you should hope to get feedback that’s mostly in that third category—interactive widgets.” Don’t waste an accessibility expert’s time telling you about color contrast problems because you can find and fix those yourself fairly easily.
  • The effect of CSS on screen readers — Part of me wishes the effect of CSS on screen readers was “nothing” but Jozsef Polgar notes there are some things CSS does affect. A classic is setting list-style: none on lists will force them to not read as lists in VoiceOver. Jozsef points to Ben Meyer’s article covering similar ground.
  • In Quest of Search — Sara again, this time weighing in on <search>. I’ve heard mostly negative things (like, why the focus on this when there are so many bigger fish to fry, like <dialog> and inert), but Sara is all for it. I agree that we might as well have an element that gives us a free role="search" like we get with <nav> and <main>.
  • Accessible Palette: stop using HSL for color systems — Eugene Fedorenko says, “While HSL and HSV are fine choices for choosing a single color, they’re not suitable for building a color system, as they simply transform the RGB model and ignore the complexities of human perception.” It seems like everyone who has looked into next-gen color formats is a fan, but I haven’t wrapped my mind around them yet. Things like LCh, Lch(ab), HCL, LCH(uv)… There is starting to be some trickles of browser support.
  • One last time: custom styling radio buttons and checkboxes — Scott O’Hara notes that you can entirely replace these inputs with custom styling, and do it accessibly. Part of doing it right is dealing with every possible state. Worth noting: without replacing everything, you can get pretty far in styling checkboxes/radios by just changing width/height and the accent-color, as Dave and I noted here.
  • Understanding Logical Focus Order — Rachel Leggett explains it is “the idea that someone navigating your webpage with a keyboard (i.e. without a mouse) will encounter elements in an order that makes sense.” Nearly anytime you use the order property, you’re probably interferring here. But less obviously, hidden elements that remain interactive can confuse logical focus order.
  • Assistiv Labs — I didn’t realize there was a tool in the vein of CrossBrowserTesting or BrowserStack that allowed you to test in JAWS and NVDA and stuff — but there is! Just the other day I wanted to test in JAWS, so I spun up a (paid) copy of Parallels with my (paid) copy of Windows 10 and used my (40-minute test version) of JAWS to test. While it worked, it was not particularly cheap or without significant technical debt. This seems easier, although I haven’t actually tried it yet.

  • Some Articles About Accessibility I’ve Saved Recently IV originally published on CSS-Tricks, which is part of the DigitalOcean family. You should get the newsletter.

    ]]>
    https://css-tricks.com/some-articles-about-accessibility-ive-saved-recently-iv/feed/ 1 354581
    Some Articles About Accessibility I’ve Saved Recently III https://css-tricks.com/some-articles-about-accessibility-ive-saved-recently-iii/ https://css-tricks.com/some-articles-about-accessibility-ive-saved-recently-iii/#comments Thu, 26 Aug 2021 19:35:21 +0000 https://css-tricks.com/?p=350298
  • The perfect link — Rian Rietveld defines them: “When you click on them, they take you somewhere else.” Not much code in here (we’ve got that), just a lot of practical accessibility advice. For example, the alt text

  • Some Articles About Accessibility I’ve Saved Recently III originally published on CSS-Tricks, which is part of the DigitalOcean family. You should get the newsletter.

    ]]>
  • The perfect link — Rian Rietveld defines them: “When you click on them, they take you somewhere else.” Not much code in here (we’ve got that), just a lot of practical accessibility advice. For example, the alt text for a linked image can allude to the fact that it is a link. Just an image: “A cherry tree in full bloom.” Link: “Wikipedia on cherry blossoms.”
  • Google Announces Seismic Change to Docs — George Joeckel covers the unfolding news that Google Docs is going to be rendered in <canvas>, which feels like a massive WTF moment when it comes to accessibility. At one point, the vibe was that there would be a separate product for people with screen reader needs. Separate but equal isn’t a good situation. Looks like the <canvas> based rendering stuff is on hold for now, so community feedback FTW?
  • Don’t use custom CSS mouse cursors — Eric Bailey: I believe that letting CSS load a custom cursor was a mistake.
  • Web Designers Grapple With Downside to Flashy Animation: Motion Sickness — Katie Deighton covers the idea that things like preference toggles and prefers-reduced-motion exists (although not by name). Always interesting to see a topic like this makes its way to a major publication like The Wall Street Journal.
  • prefers-reduced-motion and browser defaults — Speaking of prefers-reduced-motion, Bruce Lawson on the paragraph-of-the-year: Yes, it was a meeting request from Marketing to discuss a new product page with animations that are triggered on scroll. Much as a priest grasps his crucifix when facing a vampire, I immediately reached for Intersection Observer to avoid the browser grinding to a halt when watching to see if something is scrolled into view. And, like an exoricst sprinkling holy water on a demon, I also cleansed the code with a prefers-reduced-motion media query.
  • Using CSS to Enforce Accessibility — Adrian Roselli covers this great tactic where you don’t get the proper CSS styling unless you’ve also implemented the appropriate accessibility attributes (e.g. [role="region"][aria-labelledby][tabindex] for a scrolling table). This is a powerful idea and happens to showcase the power of CSS nicely in a way that styling solutions that avoid using selectors don’t benefit from.
  • Accessibility testing with Storybook — Varun Vachhar covers how you can run Axe over your component library even as you code. Accessibility issues, like color contrast problems, are bugs. Might as well give yourself the same tooling opportunities to fix them at the same time you’d fix any other bug.
  • Making A Strong Case For Accessibility — Todd Libby covers how you can fight for accessibility at work. Attempt 1.) Ethical. Attempt 2.) Financial. Attempt 3.) Legal. 4.) Humanization. Attempt 5.) Don’t ask, just do it.
  • Your Image Is Probably Not Decorative — Eric Bailey covers that most images with an empty alt attribute (literally alt="", no space) probably should have had one, and that when and alt description isn’t available, there are other options (e.g. make it available as an inline image (spacer.gif) even if it isn’t one otherwise, <title> in SVG, etc.).
  • Writing great alt text: Emotion matters — Annnnd speaking of alt, Jake Archibald learns from a 2011 Léonie Watson article: The relevant parts of an image aren’t limited to the cold hard facts.

  • Some Articles About Accessibility I’ve Saved Recently III originally published on CSS-Tricks, which is part of the DigitalOcean family. You should get the newsletter.

    ]]>
    https://css-tricks.com/some-articles-about-accessibility-ive-saved-recently-iii/feed/ 2 350298
    A Deep Dive on Skipping to Content https://css-tricks.com/a-deep-dive-on-skipping-to-content/ https://css-tricks.com/a-deep-dive-on-skipping-to-content/#comments Tue, 03 Aug 2021 14:35:48 +0000 https://css-tricks.com/?p=345154 While most people browsing the web on a computer use a mouse, many rely on their keyboard instead. Theoretically, using a web page with the keyboard should not be a problem — press the TAB key to move the keyboard …


    A Deep Dive on Skipping to Content originally published on CSS-Tricks, which is part of the DigitalOcean family. You should get the newsletter.

    ]]>
    While most people browsing the web on a computer use a mouse, many rely on their keyboard instead. Theoretically, using a web page with the keyboard should not be a problem — press the TAB key to move the keyboard focus from one focusable element to the next then press ENTER to activate, easy! However, many (if not most) websites tend to have a menu of links at the top of the page, and it can sometimes take a lot of presses to get to the content that you want. Take the homepage of 20min for example, one of the biggest news sites here in Switzerland. You want to read the top story? That’ll be the best part of 40 key presses — not the best best use of anyone’s time.

    So, if you want keyboard users to actually use your website rather than getting bored and going somewhere else, you need to do a bit of work behind the scenes to make skipping straight to your main content quicker and easier. You can find all sorts of techniques for this scattered across the web (including here at CSS-Tricks) but most are missing a trick or two and many recommend using outdated or deprecated code. So, in this article, I’m going to take a deep dive into skipping to content and cover everything in a 2021-friendly fashion.

    Two types of keyboard users

    Although there are numerous differences in the exact type of keyboard or equivalent switch device that people use to navigate, from a coding point of view, we only need to consider two groups:

    • People who use the keyboard in conjunction with a screen reader — like NVDA or JAWS on a PC, or VoiceOver on a Mac — that reads the content of the screen out loud. These devices are often used by people with more severe visual impairments.
    • All other keyboard users.

    Our skip-to-content techniques need to cater to both these groups while not getting in the way of all the mouse users. We will use two complementary techniques to get the best result: landmarks and skip links.

    Look at a basic example

    I created an example website I’m calling Style Magic to illustrate the techniques we’re covering. We’ll start off with it in a state that works fine for a mouse user but is a bit of a pain for those using a keyboard. You can find the base site and the versions for each of the techniques in this collection over at CodePen and, because testing keyboard navigation is a little tricky on CodePen, you can also find standalone versions here.

    Try using the TAB key to navigate this example. (It’s easier on the standalone page; TAB to move from one link to the next, and SHIFT+TAB to go backwards.) You will find that it’s not too bad, but only because there aren’t many menu items.

    If you have the time and are on Windows then as I’d also encourage you to download a free copy of the NVDA screen reader and try all the examples with that too, referring to WebAIM’s overview for usage. Most of you on a Mac already have the VoiceOver screen reader available and WebAIM has a great intro to using it as well.

    Adding landmarks

    One of the things that screen reading software can do is display a list of landmarks that they find on a web page. Landmarks represent significant areas of a page, and the user can pull up that list and then jump straight to one of those landmarks.

    If you are using NVDA with a full keyboard, you hit INS+F7 to bring up the “Elements List” then ALT+d to show the landmarks. (You can find a similar list on VoiceOver by using the Web Item Rotor.) If you do that on example site, though, you will only be presented with an unhelpful empty list.

    An open dialog with a UI for viewing different types of content on the page in a screen reader, including links, headings, form fields, buttons, and landmarks. Landmarks is selected and there are no results in the window.
    A disappointingly empty list of landmarks in NVDA

    Let’s fix that first.

    Adding landmarks is incredibly easy and, if you are using HTML5, you might already have them on your website without realizing it, as they are directly linked to the HTML5 semantic elements (<header>, <main>, <footer>, and so on).

    Here’s a before and after of the HTML used to generate the header section of the site:

    <div class="bg-dark">
      <div class="content-width flex-container">
        <div class="branding"><a href="#">Style Magic</a></div>
        <div class="menu-right with-branding">
          <a href="#">Home</a>
          <!-- etc. -->
          </div>
      </div>
    </div>

    Becomes

    <div class="bg-dark">
     <header class="content-width flex-container">    
        <section class="branding"><a href="#">Style Magic</a></section>
        <nav aria-label="Main menu" class="menu-right with-branding">
          <a href="#">Home</a>
          <!-- etc. -->
        </nav>
      </header>
    </div>

    The classes used remain the same, so we don’t need to make any changes at all to the CSS.

    Here’s a full list of the changes we need to make in our example site:

    • The <div> denoting the header at the top of the page is now a <header> element.
    • The <div> containing the branding is now a <section> element.
    • The two <div>s containing menus have been replaced with <nav> elements.
    • The two new <nav> elements have been given an aria-label attribute which describes them: “Main menu” for the menu at the top of the page, and “Utility menu” for the menu at the bottom of the page.
    • The <div> containing the main content of the page is now a <main> element.
    • The <div> denoting the footer at the bottom of the page is now a <footer> element.

    You can see the full updated HTML on CodePen.

    Let’s try that landmark list trick in NVDA again (INS+F7 then ALT+d — here’s the link to the standalone page so you can test yourself):

    Open screen reader dialog window showing the landmarks on the current page, including "banner," "main," and "content info."
    Hurrah for landmarks!

    Great! We now have the banner landmark (mapped to the <header> element), Main menu; navigation (mapped to the top <nav> element, and displaying our aria-label), main (mapped to <main>) and content info (mapped to footer). From this dialog I can use TAB and the cursor keys to select the main landmark and skip straight to the content of the page, or even better, I can just press the D key when browsing the page to jump from one landmark role directly to the next. Users of the JAWS screen reader have it even easier — they can simply press Q when browsing to jump straight to the main landmark.

    As an added bonus, using semantic elements also help search engines understand and index your content better. That’s a nice little side benefit of making a site much more accessible.

    I expect you’re sitting back thinking “job done” at this point. Well, I’m afraid there’s always a “but” to consider. Google did some research way back in 2011 on the use of CTRL+f to search within a web page and found that a startling 90% of people either didn’t know it existed, or have never used it. Users with a screen reader behave in much the same way when it comes to landmarks — a large portion of them simply do not use this feature even though it’s very useful. So, we’re going to add a skip link to our site to help out both groups as well as all those keyboard users who don’t use a screen reader.

    The basic requirements for what makes a good skip link are:

    • It should be perceivable to all keyboard users (including screen reader users) when it is needed.
    • It should provide enough information to the keyboard user to explain what it does.
    • It should work on as wide a range of current browsers as possible.
    • It should not interfere with the browsing of a mouse user.

    Step 1: Improving the keyboard focus appearance

    First up, we’re going to improve the visibility of the keyboard focus across the site. You can think of the keyboard focus as the equivalent to the position of the cursor when you are editing text in a word processor. When you use the TAB key to navigate the keyboard focus moves from link to link (or form control).

    The latest web browsers do a reasonable job of showing the position of the keyboard focus but can still benefit from a helping hand. There are lots of creative ways to style the focus ring, though our goal is making it stand out more than anything.

    We can use the :focus pseudo-class for our styling (and it’s a good idea to apply the same styles to :hover as well, which we’ve already done on the example site — CodePen, live site). That’s the very least we can do, though it’s common to go further and invert the link colors on :focus throughout the page.

    Here’s some CSS for our :focus state (a copy of what we already have for :hover):

    a:focus { /* generic rule for entire page */
      border-bottom-color: #1295e6;
    }
    .menu-right a:focus,
    .branding a:focus {
      /* inverted colors for links in the header and footer */
      background-color: white;
      color: #1295e6;
    }

    Step 2: Adding the HTML and CSS

    The last change is to add the skip link itself to the HTML and CSS. It consists of two parts, the trigger (the link) and the target (the landmark). Here’s the HTML that I recommend for the trigger, placed right at the start of the page just inside the <header> element:

    <header class="content-width flex-container">
      <a href="#skip-link-target" class="text-assistive display-at-top-on-focus">Skip to main content.</a>
      <!-- etc. -->
    </header>

    And here’s the HTML for the target, placed directly before the start of the <main> content:

    <a href="#skip-link-target" class="text-assistive display-at-top-on-focus" id="skip-link-target">Start of main content.</a>
    
    <main class="content-width">
      <!-- etc. -->
    </main>

    Here’s how the HTML works:

    • The skip link trigger links to the skip link target using a standard page fragment (href="#skip-link-target") which references the id attribute of the target (id="skip-link-target"). Following the link moves the keyboard focus from the trigger to the target.
    • We link to an anchor (<a>) element rather than adding the id attribute directly to the <main> element for two reasons. First, it avoids any issues with the keyboard focus not moving correctly (which can be a problem in some browsers); secondly, it means we can provide clear feedback to the user to show that the skip link worked.
    • The text of the two links is descriptive so as to clearly explain to the user what is happening.

    We now have a functioning skip link, but there’s one problem: it’s visible to everyone. We’ll use CSS to hide it from view by default, which keeps it out of the way of mouse users, then have it appear only when it receives the keyboard focus. There are lots of ways to do this and most of them are okay, but there’s a couple of wrong ways that you should avoid:

    • Do: use clip-path to make the link invisible, or use transform: translate or position: absolute to position it off screen instead.
    • Don’t: use display: none, visibility: hidden, the hidden attribute, or set the width or height of the skip link to zero. All of these will make your skip link unusable for one or both classes of keyboard users.
    • Don’t: use clip as it is deprecated.

    Here’s the code that I recommend to hide both links. Using clip-path along with its prefixed -webkit- version hits the spot for 96.84% of users at time of writing, which (in my opinion) is fine for most websites and use cases. Should your use case require it, there are a number of other techniques available that are detailed on WebAIM.

    .text-assistive {
      -webkit-clip-path: polygon(0 0, 0 0, 0 0, 0 0);
      clip-path: polygon(0 0, 0 0, 0 0, 0 0);
      box-sizing: border-box;
      position: absolute;
      margin: 0;
      padding: 0;
    }

    And to show the links when they have focus, I recommend using a version of this CSS, with colors and sizing to match your branding:

    .text-assistive.display-at-top-on-focus {
      top: 0;
      left: 0;
      width: 100%;  
    }
    .text-assistive.display-at-top-on-focus:focus {
      -webkit-clip-path: none;
      clip-path: none;
      z-index: 999;
      height: 80px;
      line-height: 80px;
      background: white;
      font-size: 1.2rem;
      text-decoration: none;
      color: #1295e6;
      text-align: center;
    }
    #skip-link-target:focus {
      background: #084367;
      color: white;
    }

    This provides for a very visible display of the trigger and the target right at the top of the page where a user would expect to see the keyboard focus directly after loading the page. There is also a color change when you follow the link to provide clear feedback that something has happened. You can fiddle with the code yourself on CodePen (shown below) and test it with NVDA on the standalone page.

    Taking this further

    Skip links aren’t just for Christmas your main menu, they are useful whenever your web page has a long list of links. In fact, this CodePen demonstrates a good approach to skip links within the content of your pages (standalone page here) using transform: translateY() in CSS to hide and show the triggers and targets. And if you are in the “lucky” position of needing to support older browsers, then you here’s a technique for that on this CodePen (standalone page here).

    Let’s check it out!

    To finish off, here are a couple of short videos demonstrating how the skip links work for our two classes of keyboard user.

    Here’s how the finished skip link works when using the NVDA screen reader:

    Here it is again when browsing using the keyboard without a screen reader:


    We just looked at what I consider to be a modern approach for accessible skip links in 2021. We took some of the ideas from past examples while updating them to account for better CSS practices, an improved UI for keyboard users, and an improved experience for those using a screen reader, thanks to an updated approach to the HTML.


    A Deep Dive on Skipping to Content originally published on CSS-Tricks, which is part of the DigitalOcean family. You should get the newsletter.

    ]]>
    https://css-tricks.com/a-deep-dive-on-skipping-to-content/feed/ 14 345154
    Your Image Is Probably Not Decorative https://css-tricks.com/your-image-is-probably-not-decorative/ https://css-tricks.com/your-image-is-probably-not-decorative/#respond Tue, 20 Jul 2021 20:02:06 +0000 https://css-tricks.com/?p=344944 Eric doesn’t mince words, especially in the title, but also in the conclusion:

    In modern web design and development, displaying an image is a highly intentional act. Alternate descriptions allow us to explain the content of the image, and in


    Your Image Is Probably Not Decorative originally published on CSS-Tricks, which is part of the DigitalOcean family. You should get the newsletter.

    ]]>
    Eric doesn’t mince words, especially in the title, but also in the conclusion:

    In modern web design and development, displaying an image is a highly intentional act. Alternate descriptions allow us to explain the content of the image, and in doing so, communicate why it is worth including.

    Just because an image displays something fanciful doesn’t mean it isn’t worth describing. Announcing its presence ensures that anyone, regardless of ability or circumstance, can fully understand your digital experience.

    I like the bit where, even when a CSS background-image is used, you can still use a “spacer GIF” to add alt text. And speaking of alt descriptions, did you know even Open Graph images can have them?

    To Shared LinkPermalink on CSS-Tricks


    Your Image Is Probably Not Decorative originally published on CSS-Tricks, which is part of the DigitalOcean family. You should get the newsletter.

    ]]>
    https://css-tricks.com/your-image-is-probably-not-decorative/feed/ 0 344944
    Looking at WCAG 2.5.5 for Better Target Sizes https://css-tricks.com/looking-at-wcag-2-5-5-for-better-target-sizes/ https://css-tricks.com/looking-at-wcag-2-5-5-for-better-target-sizes/#comments Tue, 08 Jun 2021 18:31:08 +0000 https://css-tricks.com/?p=341982 Have you ever experienced the frustration of trying to tap a button on a mobile device only to have it do nothing because the target size is just not large enough and it’s not picking up on your press? Maybe …


    Looking at WCAG 2.5.5 for Better Target Sizes originally published on CSS-Tricks, which is part of the DigitalOcean family. You should get the newsletter.

    ]]>
    Have you ever experienced the frustration of trying to tap a button on a mobile device only to have it do nothing because the target size is just not large enough and it’s not picking up on your press? Maybe you have larger fingers, like I do, or maybe it’s due to limited dexterity. This is because the sadly ever-decreasing target area of elements we, the users, have to interact with.

    Let’s talk about target size and how to make it large enough for users to easily interact with an element. This is an especially big deal if a user is accessing content on a small hand-held touch screen device where real estate is much tighter.

    Success criterion revisited

    I touched (no pun intended) on Success Criterion in a previous article covering the WCAG 2.1 criterion, Label in Name. In short, the WCAG criteria is the baseline from which we determine whether our work is “accessible.”

    If you’re wondering whether there’s a criterion for target size, the answers is yes. It’s WCAG 2.5.5. Pulling straight from the guidelines. passing WCAG 2.5.5 with a AAA grade requires “the size of the target for pointer inputs is at least 44 by 44 CSS pixels except when:

    • Equivalent: The target is available through an equivalent link or control on the same page that is at least 44×44 CSS pixels;
    • Inline: The target is in a sentence or block of text;
    • User Agent Control: The size of the target is determined by the user agent and is not modified by the author;
    • Essential: A particular presentation of the target is essential to the information being conveyed.”

    What could possibly go wrong?

    It’s just a size, right? Easy peasy. Nothing can possibly go awry.

    Or can it?

    Small target sizes can cause accessibility hurdles for many people. Have you ever been traveling in a vehicle on a bumpy road and you’re trying to interact with an app on your mobile can not press on an element? That is an accessibility hurdle. Those with motor skill or cognitive impairments will have a much harder time because it is much harder for them if the target size is too small and does not meet WCAG requirements.

    I don’t mean to pick on Twitter here, but it’s the first notable example I found while hunting for examples of small targets.

    There are some good examples of small targets in here, from the tiny contextual menu to the actions in the footer of a tweet, and even the small icons to add topics to a timeline. And notice that even with a properly sized target, like the floating button to compose a tweet, it overlaps with another target, obstructing access to it.

    Imagine the hurdles someone with neuromuscular disorders, such as Multiple Sclerosis, Cerebral Palsy, arthritis, tremors, or Alzheimer’s Disease or any other motor impairment would have to overcome to activate a target in any of those cases.

    Another favorite example I see quite often? Ads. Have you ever struggled to click the minuscule “X” button to close them?

    You’re not alone if you’ve ever struggled to click, let alone even locate, the close button.

    Having no motor skill or cognitive disabilities personally, I find myself fumbling around and taking multiple times to hit some target areas. The fact that someone who needs to use something like a pen or stylus on a target size that is not a minimum of 44×44 pixels can be a difficult task. These targets shouldn’t need multiple attempts to activate when the target size doesn’t meet recommended guidelines.

    Target size considerations

    WCAG 2.5.5 goes into specific detail to help us account for these things by defining the four types of controls we just saw: equivalent, inline, User Agent, and essential.

    We’re going to look at different considerations for determining target sizes and hold them up next to the WCAG guidelines to help steer us toward making good, accessible design decisions.

    Consider the difference between “click” and “tap”

    This success criteria ensures that target sizes are large enough for users to easily activate targets, even if the user is accessing these targets on handheld devices. We typically associate small screens with “taps” instead of “clicks” when it comes to activating targets. And that’s something we need to consider in our target sizing.

    Mice and similar input devices use a pointer on the screen, which is considered “fine” precision because it allows a user to access an element on the screen with exact precision. Fine precision makes it easier to access smaller target sizes in theory. The trouble is, that sort of input device can be tough for some users, whether it’s with gripping the device, or some other cognitive or motor skill. So, even with fine precision, having a clear target is still a benefit.

    A Tale of Two Targets: Combining padding and color can help increase the size of a tap target while making it visually clear.

    Touch, on the other hand, can be problematic as it is an input mechanism with very “coarse” precision. Users can lack a level of fine control when using a mouse or stylus, for example. A finger, which is larger than a mouse pointer, generally obstructs a user’s view of the exact location on the screen that is being activated or touched. Hence, “coarse” precision.

    A smaller pointer offers more precision than a larger thumb when it comes to interacting with an element.

    This issue is exacerbated in responsive design, which needs to accommodate for numerous types of fine and coarse inputs. Both input types must be supported for a site that can be accessed by a desktop or laptop with a mouse, as well as a mobile device or tablet with a touch screen.

    That makes the actual size we use for a target a pretty important detail. Depending on who is using a control, what that control does, how often it’s used, and where it’s located, we ought to consider using larger, clearer targets to prevent things like unintended actions.

    But with all this said, we do actually have a CSS media query that can detect a pointer device so we can target certain styles to either fine or coarse input interactions, and it’s well-supported. Here’s an example pulled right out of the spec:

    /* Make radio buttons and check boxes larger if we have an inaccurate primary pointing device */
    @media (pointer: coarse) {
      input[type="checkbox"], input[type="radio"] {
        min-width: 30px;
        min-height: 40px;
        background: transparent;
      }
    }

    But wait. While this is great and all, Patrick H. Lauke offers a word of caution about this interaction media query and it’s potential for making incorrect assumptions.

    Consider that different platforms have different requirements

    When WCAG specifies exact values, it’s worth paying attention. Notice that we’re advised to make target sizes at least 44×44 pixels, which is mentioned no fewer than 18 times in the WCAG 2.5.5 explainer.

    However, you may have also seen similar requirements with different guidance from the likes of Apple’s “Human Interface Guidelines” for iOS, and Google’s “Material Design” in their platform design requirements.

    “Try to maintain a minimum tappable area of 44pt x 44pt for all controls.” (Apple, “Human Interface Guidelines”)
    “Consider making pointer targets at least 44 x 44 dp.”
    (Material Design, “Accessibility”)

    Consider the “tappable area” of a target

    Notice that Apple’s platform requirements refer to a “tappable area” when describing the ideal target size. That means that we’re talking about space as much as we are about the appearance of a target. For example, Google’s Material Design suggests at least a 48×48 dp (density-independent pixels) target size for interactive elements. But what if your design requirements call for a 24×24 dp icon? It’s totally legit to use padding in our favor to create more interactive space around the icon, comprising the 48×48 dp target size. Or, as it’s documented in Material Design:

    Touch targets are the parts of the screen that respond to user input. They extend beyond the visual bounds of an element. For example, an icon may appear to be 24×24 dp, but the padding surrounding it comprises the full 48×48 dp touch target.

    Consider responsive layout behavior

    That’s right, we’ve gotta consider how things shift and move around in a design that’s meant to respond to different viewport sizes. One example might be buttons that stack on small screens but are inline on larger screen. We want to make sure that transition accounts for the placement of surrounding elements in order to prevent overlapping elements or targets.

    Speaking of inline, there’s a particular piece of the WCAG’s exception for inline targets that’s worth highlighting:

    Inline: Content displayed can often be reflowed based on the screen width available (responsive design). In reflowed content, the targets can appear anywhere on a line and can change position based on the width of the available screen. Since targets can appear anywhere on the line, the size cannot be larger than the available text and spacing between the sentences or paragraphs, otherwise the targets could overlap. It is for this reason targets which are contained within one or more sentences are excluded from the target size requirements.

    (Emphasis mine)

    Now, we’re not necessarily talking about buttons that are side-by-side here. We can links within text and that text might break the target’s placement, possibly into two lines.

    While it might be difficult to tap one target without inadvertently tapping the other, the WCAG makes an exception for inline targets, like links within paragraphs.

    Consider the target’s relationship to its surroundings

    We just saw how inline links within a block of text are exempt from the 44×44 rule. There are similar exceptions depending on the target’s relationship to the elements around it.

    Let’s take the example that the WCAG explainer provides, again, in it’s description of inline target exceptions:

    If the target is the full sentence and the sentence is not in a block of text, then the target needs to be at least 44 by 44 CSS pixels.

    That’s a good one. We ought to consider whether the target is its own block or part of a larger block of text. If the target is its own block, then it needs to abide by the rules, whether it’s a button with a short label, or a complete sentence that’s linked up. On the flip side, a complete sentence that’s linked up inside another block of text doesn’t have to meet the target size requirements.

    If the target is its own block of text (left), then it needs to adhere to the WCAG criterion. Otherwise, it is exempt (right).

    You might think that something like a linked icon at the end of a sentence or paragraph would need to play by the rules, but the WCAG is clear that these targets are exempt:

    A footnote or an icon within or at the end of a sentence is considered to be part of a sentence and therefore are excluded from the minimum target size.

    And that makes sense. Imagine content with a line height of, say 32 pixels and an icon at the end that’s all padded up to be 44×44 pixels and how easy it would be to inadvertently activate the icon.

    Consider whether the target is styled by the User Agent

    If the target is completely un-styled — in the sense that you’ve added no CSS to it — and instead takes on the default styles provided by the browser, then there’s no need to stress the 44×44 rule. That makes sense. The User Agent is like system-level UI so changing it superficially with our own styles would be overriding an entire system which could lead to inconsistencies in that UI.

    You’re fine just as you are, little button.

    So, yeah, if you’re rockin’ a default <button> or the like, and there are no other styles or sizing applied to it, then it’s good to go. But lots of us use resets to normalize UI elements across browsers, so watch for that in your codebase because that’s going to affect the User Agent styles of your target.

    Consider if there are other ways to activate the functionality

    We’ve all used in-page anchor links, right? Heck, CSS-Tricks often has a table of contents at the top of an article that’s merely a list of anchor links.

    Should these be at least 44×44 pixels?

    WCAG actually uses anchor links as an example of something that’s off the hook as far as meeting the target size requirements. Why? Because it’s just as possible to manually scroll down to a specific location on a page as it is to click a link to jump there. There are two ways to accomplish the same thing, and one of those ways is built right into the browser.

    But we still ought to use care when working with something like a table of contents. I’m not entirely clear here, but given that a table of contents is list of links, each link may very well constitute its own block of text that’s not part of a larger block of a text, like a paragraph. So, in this sort of case, maybe a little extra space between list items is still a good idea. There’s less change of accidentally clipping or tapping two or more targets at once.

    Wrapping up

    WCAG 2.5.5 criterion provides guidance for applying target sizes that are clear, unobstructed, and easy to activate. As we saw, there are plenty of cases where the size of a target can make all the difference in the world when it comes to completing an action.

    The interesting thing about the target size guidelines is what is exempted from them. While we didn’t cover each specific exemption on its own, we did look at a bunch situations that require careful consideration for sizing a target, from the type of input device that’s in use to the relationship of the target to its surrounding elements, and plenty of things between.

    The key to accessible target sizing isn’t necessary about using less styling on a target (although we did see that default User Agent styles are exempt), but rather having context and styling accordingly. There are probably dozens more situations we could have covered here and examined how styles come into play — so if you have some, share!

    And as far as styling goes, CSS specifications have specific features, like the interation media query for pointer, to make target sizing even better for people. Used well, it could be a great way to detect if a visitor is using a fine or coarse input device. That way, we can tailor things to make their experience better than if we treated those differences the same.

    So, yes, target sizes are an easy thing to brush off and ignore. But hopefully now you’re like me and have a genuine appreciation for targets that are correctly sized now that you have the information to make correctly sized targets of your own.


    Looking at WCAG 2.5.5 for Better Target Sizes originally published on CSS-Tricks, which is part of the DigitalOcean family. You should get the newsletter.

    ]]>
    https://css-tricks.com/looking-at-wcag-2-5-5-for-better-target-sizes/feed/ 7 341982
    Some Articles About Accessibility I’ve Saved Recently II https://css-tricks.com/links-on-accessibility/ https://css-tricks.com/links-on-accessibility/#comments Mon, 07 Jun 2021 19:52:26 +0000 https://css-tricks.com/?p=341805
  • Show/Hide password accessibility and password hints tutorial — Nicolas Steenhout goes deep on <input type="password"> accessibility. For one thing, being able to toggle it to type="text" should be possible, while announcing, politely, the change. But also, put the password hints

  • Some Articles About Accessibility I’ve Saved Recently II originally published on CSS-Tricks, which is part of the DigitalOcean family. You should get the newsletter.

    ]]>
  • Show/Hide password accessibility and password hints tutorial — Nicolas Steenhout goes deep on <input type="password"> accessibility. For one thing, being able to toggle it to type="text" should be possible, while announcing, politely, the change. But also, put the password hints (for choosing a password) before the input and programmatically connect them. And a bunch of other stuff. (Video version)
  • Practical accessibility, part 2: Name (almost) everything — Maggie Wachs explains how it’s all about the ability to move about the page.
  • Modern CSS Upgrades To Improve Accessibility — Stephanie Eckles shows off :focus-visible, outline-offset, order and other properties that can both help and hurt accessibility. My favorite are the clever uses of min() and max() which do things like reduce excessive margin on page zoom and maintain tappable area sizes.
  • WebAIM Million – 2021 Update — Jared Smith notes that things are getting better, even if just a bit. Is that the first time ever?! Things certainly aren’t “good” but it’s an encouraging trend.
  • Shift further left with Deque’s axe-linter for VS Code — Jonathan Thickens intros this new editor plugin which calls out errors just as if they were syntax, spelling, or formatting errors. As it should be! I’m using it and it works great. “Shift left” means “test earlier in the process” and “as you code” is about as early as it gets.
  • Content-visibility and Accessible Semantics — Marcy Sutton notes that the accessibility issues that hurt content-visibility when it first rolled have been resolved. This is the original blog post that documented what they were.
  • More Accessible Skeletons — Adrian Roselli notes that aria-busy="true" for a bit of skeleton HTML isn’t enough, as there is a little more attribute-shuffling to do, paired with CSS selectors to hide what needs to be hidden. (Demo)
  • Giving a damn about accessibility — Sheri Byrne-Haber’s “candid and practical handbook for designers.” Free digital (and audio) book. 📒

  • Some Articles About Accessibility I’ve Saved Recently II originally published on CSS-Tricks, which is part of the DigitalOcean family. You should get the newsletter.

    ]]>
    https://css-tricks.com/links-on-accessibility/feed/ 1 341805
    Front-End Testing is For Everyone https://css-tricks.com/front-end-testing-is-for-everyone/ https://css-tricks.com/front-end-testing-is-for-everyone/#comments Tue, 01 Jun 2021 14:17:43 +0000 https://css-tricks.com/?p=341342 Testing is one of those things that you either get super excited about or kinda close your eyes and walk away. Whichever camp you fall into, I’m here to tell you that front-end testing is for everyone. In fact, …


    Front-End Testing is For Everyone originally published on CSS-Tricks, which is part of the DigitalOcean family. You should get the newsletter.

    ]]>
    Testing is one of those things that you either get super excited about or kinda close your eyes and walk away. Whichever camp you fall into, I’m here to tell you that front-end testing is for everyone. In fact, there are many types of tests and perhaps that is where some of the initial fear or confusion comes from.

    I’m going to cover the most popular and widely used types of tests in this article. This might be nothing new to some of you, but it can at least serve as a refresher. Either way, my goal is that you’re able to walk away with a good idea of the different types of tests out there. Unit. Integration. Accessibility. Visual regression. These are the sorts of things we’ll look at together.

    And not just that! We’ll also point out the libraries and frameworks that are used for each type of test, like Mocha. Jest, Puppeteer, and Cypress, among others. And don’t worry — I’ll avoid a bunch of technical jargon. That said, you should have some front-end development experience to understand the examples we’re going to cover.

    OK, let’s get started!

    What is testing?

    Software testing is an investigation conducted to provide stakeholders with information about the quality of the software product or service under test.

    Cem Kaner, “Exploratory Testing” (November 17, 2006)

    At its most basic, testing is an automated tool that finds errors in your development as early as possible. That way, you’re able to fix those issues before they make it into production. Tests also serve as a reminder that you may have forgotten to check your own work in a certain area, say accessibility.

    In short, front-end testing validates that what people see on the site and the features they use on it work as intended.

    Front-end testing is for the client side of your application. For example, front-end tests can validate that pressing a “Delete” button properly removes an item from the screen. However, it won’t necessarily check if the item was actually removed from the database — that sort of thing would be covered during back-end testing.

    That’s testing in a nutshell: we want to catch errors on the client side and fix them before code is deployed.

    Different tests look at different parts of the project

    Different types of tests cover different aspects of a project. Nevertheless, it is important to differentiate them and understand the role of each type. Confusing which tests do what makes for a messy, unreliable testing suit.

    Ideally, you’d use several different types of tests to surface different types of possible issues. Some test types have a test coverage analytic that shows just how much of your code (as a percentage) is looked at by that particular test. That’s a great feature, and while I’ve seen developers aim for 100% coverage, I wouldn’t rely on that metric alone. The most important thing is to make sure all possible edge cases are covered and taken into account.

    So, with that, let’s turn our attention to the different types of testing. Remember, it’s not so much that you’re expected to use each and every one of these. It’s about being able to differentiate the tests so that you know which ones to use in certain circumstances.

    Unit testing

    Unit testing is the most basic building block for testing. It looks at individual components and ensures they work as expected. This sort of testing is crucial for any front-end application because, with it, your components are tested against how they’re expected to behave, which leads to a much more reliable codebase and app. This is also where things like edge cases can be considered and covered.

    Unit tests are particularly great for testing APIs. But rather than making calls to a live API, hardcoded (or “mocked”) data makes sure that your test runs are always consistent at all time.

    Let’s take a super simple (and primitive) function as an example:

    const sayHello = (name) => {
      if (!name) {
        return "Hello human!";
      }
    
      return `Hello ${name}!`;
    };

    Again, this is a basic case, but you can see that it covers a small edge case where someone may have neglected to provide a first name to the application. If there’s a name, we’ll get “Hello ${name}!” where ${name} is what we expect the person to have provided.

    “Um, why do we need to test for something small like that?” you might wonder. There are some very important reasons for this:

    • It forces you to think deeply about the possible outcomes of your function. More often than not, you really do discover edge cases which helps you cover them in your code.
    • Some part of your code can rely on this edge case, and if someone comes and deletes something important, the test will warn them that this code is important and cannot be removed.

    Unit tests are often small and simple. Here’s an example:

    describe("sayHello function", () => {
      it("should return the proper greeting when a user doesn't pass a name", () => {
        expect(sayHello()).toEqual("Hello human!")
      })
    
      it("should return the proper greeting with the name passed", () => {
        expect(sayHello("Evgeny")).toEqual("Hello Evgeny!")
      })
    })

    describe and it are just syntactic sugar. The most important lines with expect and toEqual. describe and it breaks the test into logical blocks that are printed to the terminal. The expect function accepts the input we want to validate, while toEqual accepts the desired output. There are a lot of different functions and methods you can use to test your application.

    Let’s say we’re working with Jest, a library for writing units. In the example above, Jest will display the sayHello function as a title in the terminal. Everything inside an it function is considered as a single test and is reported in the terminal below the function title, making everything very easy to read.

    The green checkmarks mean both of our tests have passed. Yay!

    Integration testing

    If unit tests check the behavior of a block, integration tests make sure that blocks work flawlessly together. That makes Integration testing super important because it opens up testing interactions between components. It’s very rare (if ever) that an application is composed of isolated pieces that function by themselves. That’s why we rely on integration tests.

    We go back to the function we unit tested, but this time use it in a simple React application. Let’s say that clicking a button triggers a greeting to appear on the screen. That means a test involves not only the function but also the HTML DOM and a button’s functionality. We want to test how all these parts play together.

    Here’s the code for a <Greeting /> component we’re testing:

    export const Greeting = () => {  
      const [showGreeting, setShowGreeting] = useState(false);  
    
     return (  
       <div>  
         <p data-testid="greeting">{showGreeting && sayHello()}</p>  
         <button data-testid="show-greeting-button" onClick={() => setShowGreeting(true)}>Show Greeting</button>  
       </div>
     );  
    };

    Here’s the integration test:

    describe('<Greeting />', () => {  
      it('shows correct greeting', () => {  
        const screen = render(<Greeting />);  
         const greeting = screen.getByTestId('greeting');  
         const button = screen.getByTestId('show-greeting-button');  
    
         expect(greeting.textContent).toBe('');  
         fireEvent.click(button);  
         expect(greeting.textContent).toBe('Hello human!');  
     });  
    });

    We already know describe and it from our unit test. They break tests up into logical parts. We have the render function that displays a <Greeting /> component in the special emulated DOM so we can test interactions with the component without touching the real DOM — otherwise, it can be costly.

    Next up, the test queries <p> and <button> elements via test IDs ( #greeting and #show-greeting-button, respectively). We use test IDs because it’s easier to get the components we want from the emulated DOM. There are other ways to query components, but this is how I do it most often.

    It’s not until line 7 that the actual integration test begins! We first check that <p> tag is empty. Then we click the button by simulating a click event. And lastly, we check that the <p> tag contains “Hello human!” inside it. That’s it! All we’re testing is that an empty paragraph contains text after a button is clicked. Our component is covered.

    We can, of course, add input where someone types their name and we use that input in the greeting function. However, I decided to make it a bit simpler. We’ll get to using inputs when we cover other types of tests.

    Check out what we get in the terminal when running the integration test:

    Termain message showing a passed test like before, but now with a specific test item for showing the correct greeting. It includes the number of tests that ran, how many passed, how many snapshots were taken, and how much time the tests took, which was 1.085 seconds.
    Perfect! The <Greeting /> component shows the correct greeting when clicking the button.

    End-to-end (E2E) testing

    • Level: High
    • Scope: Tests user interactions in a real-life browser by providing it instructions for what to do and expected outcomes.
    • Possible tools: Cypress, Puppeteer

    E2E tests are the highest level of testing in this list. E2E tests care only about how people see your application and how they interact with it. They don’t know anything about the code and the implementation.

    E2E tests tell the browser what to do, what to click, and what to type. We can create all kinds of interactions that test different features and flows as the end user experiences them. It’s literally a robot that’s interacted to click through an application to make sure everything works.

    E2E tests are similar to integration tests in a sort of way. However, E2E tests are executed in a real browser with a real DOM rather than something we mock up — we generally work with real data and a real API in these tests.

    It is good to have full coverage with unit and integration tests. However, users can face unexpected behaviors when they run an application in the browser — E2E tests are the perfect solution for that.

    Let’s look at an example using Cypress, an extremely popular testing library. We are going to use it specifically for an E2E test of our previous component, this time inside a browser with some extra features.

    Again, we don’t need to see the code of the application. All we’re assuming is that we have some application and we want to test it as a user. We know what buttons to click and the IDs those buttons have. That’s all we really have to go off of.

    describe('Greetings functionality', () => {  
      it('should navigate to greetings page and confirm it works', () => {
        cy.visit('http://localhost:3000')  
        cy.get('#greeting-nav-button').click()  
        cy.get('#greetings-input').type('Evgeny', { delay: 400 })  
        cy.get('#greetings-show-button').click()  
        cy.get('#greeting-text').should('include.text', 'Hello Evgeny!')  
      })  
    })

    This E2E test looks very similar to our previous integration test. The commands are extremely similar, the main difference being that these are executed in a real browser.

    First, we use cy.visit to navigate to a specific URL where our application lies:

    cy.visit('http://localhost:3000')

    Second, we use cy.get to get the navigation button by its ID, then instruct the test to click it. That action will navigate to the page with the <Greetings /> component. In fact, I’ve added the component to my personal website and provided it with its own URL route.

    cy.get('#greeting-nav-button').click()

    Then, sequentially, we get text input, type “Evgeny,” click the #greetings-show-button button and, lastly, check that we got the desired greeting output.

    cy.get('#greetings-input').type('Evgeny', { delay: 400 })
    cy.get('#greetings-show-button').click()
    cy.get('#greeting-text').should('include.text', 'Hello Evgeny!')  

    It is pretty cool to watch how the test clicks buttons for you in a real live browser. I slowed down the test a bit so you can see what is going on. All of this usually happens very quickly.

    Here is the terminal output:

    Terminal showing a run test for greetings.spec.js that passed in 12 seconds.

    Accessibility testing

    Web accessibility means that websites, tools, and technologies are designed and developed so that people with disabilities can use them.

    W3C

    Accessibility tests make sure people with disabilities can effectively access and use a website. These tests validate that you follow the standards for building a website with accessibility in mind.

    For example, many unsighted people use screen readers. Screen readers scan your website and attempt to present it to users with disability in a format (usually spoken) those users can understand. As a developer, you want to make a screen reader’s job easy and accessibility testing will help you understand where to start.

    There are a lot of different tools, some of them automated and some that run manually to validate accessibilit. For example, Chrome already has one tool built right into its DevTools. You may know it as Lighthouse.

    Let’s use Lighthouse to validate the application we made in the E2E testing section. We open Lighthouse in Chrome DevTools, click the “Accessibility” test option, and “Generate” the report.

    That’s literally all we have to do! Lighthouse does its thing, then generates a lovely report, complete with a score, a summary of audits that ran, and an outline of opportunities for improving the score.

    But this is just one tool that measures accessibility from its particular lens. We have all kinds of accessibility tooling, and it’s worth having a plan for what to test and the tooling that’s available to hit those points.

    Visual regression testing

    • Level: High
    • Scope: Tests the visual structure of application, including the visual differences produced by a change in the code.
    • Possible tools: Cypress, Percy, Applitools

    Sometimes E2E tests are insufficient to verify that the last changes to your application didn’t break the visual appearance of anything in an interface. Have you pushed the code with some changes to production just to realize that it broke the layout of some other part of the application? Well, you are not alone. Most times than not, changes to a codebase break an app’s visual structure, or layout.

    The solution is visual regression testing. The way it works is pretty straightforward. Visual test merely take a screenshot of pages or components and compare them with screenshots that were captured in previous successful tests. If these tests find any discrepancies between the screenshots, they’ll give us some sort of notification.

    Let’s turn to a visual regression tool called Percy to see how visual regression test works. There are a lot of other ways to do visual regression tests, but I think Percy is simple to show in action. In fact, you can jump over to Paul Ryan’s deep dive on Percy right here on CSS-Tricks. But we’ll do something considerably simpler to illustrate the concept.

    I intentionally broke the layout of our Greeting application by moving the button to the bottom of the input. Let’s try to catch this error with Percy.

    Percy works well with Cypress, so we can follow their installation guide and run Percy regression tests along with our existing E2E tests.

    describe('Greetings functionality', () => {  
      it('should navigate to greetings page and confirm everything is there', () => {  
        cy.visit('http://localhost:3000')  
        cy.get('#greeting-nav-button').click()  
        cy.get('#greetings-input').type('Evgeny', { delay: 400 })  
        cy.get('#greetings-show-button').click()  
        cy.get('#greeting-text').should('include.text', 'Hello Evgeny!')  
    
    
        // Percy test
         cy.percySnapshot() // HIGHLIGHT
      })  
    })

    All we added at the end of our E2E test is a one-liner: cy.percySnapshot(). This will take a screenshot and send it to Percy to compare. That is it! After the tests have finished, we’ll receive a link to check our regressions. Here is what I got in the terminal:

    Terminal output that shows white text on a black background. It displays the same result as before, but with a step showing that Percy created a build and where to view it.
    Hey, look, we can see that the E2E tests have passed as well! That shows how E2E testing won’t always catch a visual error.

    And here’s what we get from Percy:

    Animated gif of a webpage showing a logo and navigation above a form field. The animation overlays the original snapshot with the latest to reveal differences between the two.
    Something clearly changed and it needs to be fixed.

    Performance testing

    Performance testing is great for checking the speed of your application. If performance is crucial for your business — and it likely is given the recent focus on Core Web Vitals and SEO — you’ll definitely want to know if the changes to your codebase have a negative impact on the speed of the application.

    We can bake this into the rest of our testing flow, or we can run them manually. It’s totally up to you how to run these tests and how frequently to run them. Some devs create what’s called a “performance budget” and run a test that calculates the size of the app — and a failed test will prevent a deployment from happening if the size exceeds a certain threshold. Or, test manually every so often with Lighthouse, as it also measures performance metrics. Or combine the two and build Lighthouse into the testing suite.

    Performance tests can measure anything related to performance. They can measure how fast an application loads, the size of its initial bundle, and even the speed of a particular function. Performance testing is a somewhat broad, vast landscape.

    Here’s a quick test using Lighthouse. I think it’s a good one to show because of its focus on Core Web Vitals as well as how easily accessible it is in Chrome’s DevTools without any installation or configuration.

    A Lighthouse report open in Chrome DevTools showing a Performance score of 55 indicated by a orange circle bearing the score. Various metrics are listed below the score, including a timeline of the page as it loads.
    Not a great score, but at least we can see what’s up and we have some recommendations for how to make improvements.

    Wrapping up

    Here’s a breakdown of what we covered:

    TypeLevelScopeTooling examples
    UnitLowTests the functions and methods of an application.
    IntegrationMediumTests Interactions between units.
    End-to-endHighTests user interactions in a real-life browser by providing it instructions for what to do and expected outcomes.
    AccessibilityHighTests the interface of your application against accessibility standards criteria.
    Visual regressionHighTests the visual structure of application, including the visual differences produced by a change in the code. 
    PerformanceHighTests the application forperformance and stability.

    So, is testing for everyone? Yes, it is! Given all the available libraries, services, and tools we have to test different aspects of an application at different points, there’s at least something out there that allows us to measure and test code against standards and expectations — and some of them don’t even require code or configuration!

    In my experience, many developers neglect testing and think that a simple click-through or post check will help any possible bugs from a change in the code. If you want to make sure your application works as expected, is inclusive to as many people as possible, runs efficiently, and is well-designed, then testing needs to be a core part of your workflow, whether it’s automated or manual.

    Now that you know what types tests there are and how they work, how are you going to implement testing into your work?


    Front-End Testing is For Everyone originally published on CSS-Tricks, which is part of the DigitalOcean family. You should get the newsletter.

    ]]>
    https://css-tricks.com/front-end-testing-is-for-everyone/feed/ 11 341342