Git Product home page Git Product logo

a11y-toggle's Introduction

A11y Toggle

A tiny script (less than 0.6Kb gzipped) to build accessible content toggles. You can try the live demo which also acts as a documentation.

a11y-toggle uses relatively modern JavaScript API (namely reduce, addEventListener, etc.) therefore will not work in Internet Explorer 8 and below. All the other browsers, including mobile ones should work fine.

Install

npm install --save a11y-toggle
bower install a11y-toggle

Tests

Mocha and expect.js are used to run browser tests.

npm test

Deploy example

The example page is deployed through GitHub Pages.

npm run deploy

a11y-toggle's People

Contributors

kittygiraudel avatar saibotsivad avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

a11y-toggle's Issues

aria-hidden="true" and media queries

I'm planning to use a11y-toggle as a fairly standard (hamburger) navigation toggler.

So far it works as per the examples but I've run into a problem when displaying the navigation at large screen sizes and hiding the button. Of course, aria-hidden="true" is set on the navigation so it's hidden from AT user despite being visible to everyone else.

Is a configurable media query option out of the question? I'm guessing I'd have to detect the screen size and switch around aria-hidden="true" (plus deal with the button visibility).

Apologies for not suggesting a solution, my Javascript experience is very limited.

[aria-hidden="true"]

If page has google maps, and with this atr

[aria-hidden="true"] {
  display: none;
}

the map will be hidden too.

Allow multiple aria-controls per target

As per the current implementation multiple toggle buttons for the same target get out of sync when expanding/collapsing.
I made a testcase http://jsbin.com/koyanoxora/edit?html,css,output

In general I think that the following logic is preferable:

 var isExpanded = target.getAttribute('aria-hidden') === 'true';

In addition to that every time one clicks a toggle button all of the buttons with the same namespace value should update their aria-expanded value to true|false.

Multiple instances of Connected Toggles

a11y-toggle is wonderful. Thank you!

When adding multiple instances of connected-toggles to a single page toggling content becomes a problem. In the following codepen demo notice how toggling one item hides images from the other galleries.

I was able to get it working by updating the collapseAll function to...
(Note: I used jQuery to solve the problem.)

function collapseAll(event) {

    var $this = jQuery(this);
    var $container = $this.closest('.connected-toggles');
    var $buttons = $container.find('button');
    var buttonsArr = jQuery.makeArray($buttons);

    buttonsArr
        .filter(function(toggle) {
            return buttonsArr !== event.target;
        })
        .forEach(collapse);

    // toggles
    //   .filter(function (toggle) {
    //     return toggle !== event.target;
    //   })
    //   .forEach(collapse);
}

Go to the following codepen demo for a working example. I assume others would prefer a vanilla JS solution.

Hope this helps in some fashion.

Enjoy,
Aaron

Accessibility of no-JS Version

Looking at this, I'm wondering about a11y problems when JS is turned off (rare) or doesn't load (less rare). By requiring the aria-hidden="true" to be in the HTML source rather than inserted by the JS, this means that–if I'm reading this correctly—the hidden content is screen-reader-inaccessible with no JS.

The best solution I can think of right now is to introduce another data attribute (data-a11y-toggle-default="hidden" maybe?) on either the button or container and then settings aria-hidden based on that.

(And as I think about this even more, shouldn't the <button> be hidden when there's no JS and then made visible once JS loads?)

Support "toggle-others" functionality

While experimenting with using this for an internal pattern library of sorts, we realized this could be used not only for accordion-style displays, but probably tabs as well.

What we found however was that a potentially interesting feature would be an option of sorts to allow for "if click button, close all other divs, open div tied to button" thereby enabling only 1 panel at a time.

Is this something easily feasible within the existing code or would that require a large amount of extra just to enable it as an option? Another dev on our team is working on this as well so we might be able to submit a PR if there's no objections to the concept.

Collapsed by default broken?

Not sure why, but even in the demo, both instances of .collapsible-box initially get aria-hidden="false". Therefore, the “Collapsed by default” example is not actually collapsed by default.

Once the toggler button is clicked, everything works fine, but the initial state is broken. Tested in Chrome, Firefox and Safari, so probably not a browser-related issue.

(Of course, this can be fixed by assigning aria-hidden="true" in the markup, but surely that's not the intended use.)

Document aria-own attribute

by adding aria-owns to the toggle button with the div's id, screen readers will adjust the virtual buffer as if they were adjutants elements, even if they were not so in the DOM.

Toggle content

random text
another random text
Here is some content that can be be toggled visible or invisible.

Add tabindex="-1" to content element

Jeremy Keith has written about an accessible content toggle on his blog - https://adactio.com/journal/10365; it’s almost the same approach as a11y-toggle, except that he also adds tabindex="-1" to the content element, and then when the content is displayed, it is also focused programmatically. That sounds like a good idea.

Doesn't work with element inside button

Hi!

I noticed that, when you put an element inside of the toggle:

<button data-a11y-toggle="content-container" type="button">
  <span>test</span>
</button>

and click onto the element, i.e. span, instead of the button the event handler wouldn't find the target, because the span doesn't have a data-a11y-toggle attribute.

So, I suggest adding sth. like this:

// try the parent
if (!target) {
  var toggle = toggle.parentNode;
  var target = targetsMap[toggle.getAttribute(namespace)];
}

Error when clicking anywhere on the page

When i click anywhere on the page i get the following error

Uncaught TypeError: Cannot read property 'getAttribute' of null

Happens in your demo and my local dev site.

Thanks!

[aria-hidden=true] { display: none; } in example should come with disclaimer

RE: twitter conversation!

Users should consider scoping this rule to only target desired toggle elements. With this set globally there could be issues with 3rd party apps running on the page. Only identified Google Maps as being a culprit so far.

The bug in question is that Google map tiles use aria-hidden on elements within the map tree, with this rule in place Google map tiles will appear grey and map-less.

Feature request: Focus management

Hello :) Great work here!

I'd like to recommend the idea of focus management for your plugin. It would look something like this:

  1. User clicks on toggle.
  2. After the target is expanded send focus to the target element. May have to add tabindex="-1" to target so it can receive focus.
  3. If the target is already visible, maintain focus on the toggle and hide target.

What ya think?

Add support for state transitions

So, from my experience, the biggest issue of not using a clean way to build a toggle for most developers is that they need a slideUp/slideDown transition for it, not a display: none.
As this is hard to achieve, they fall back towards using jQuery’s slideToggle() function and then, to a small part understandably, forget about proper markup afterwards.

I’m not sure if that’s the goal or the scope of the project but having it built in (either into the plugin itself or a demo) would be a benefit and maybe the key feature for people to use it.

My initial thought would be to calculate height via JS and set it on the container and then initialize a max-height [x] to 0 CSS transition. What do you think?

close when click outside

In your example Connected toggles you describe how to close a toggle when opening another.

This can be used on close-all-when-click-outside-an-opened-toggle.

if (!target) {
return false;
}

Replace return false with collapseAll (event) and all opened toggles will be closed when clicking outside an opened toggle.

Can you add the code from the example in the base of your a11y-toggle?

function collapse (toggle) {
  var id = toggle.getAttribute('data-a11y-toggle');
  var collapsibleBox = document.getElementById(id);
  collapsibleBox.setAttribute('aria-hidden', true);
  toggle.setAttribute('aria-expanded', false);
}

function collapseAll (event) {
  toggles
    .filter(function (toggle) {
      return toggle !== event.target;
    })
    .forEach(collapse);
}

Information on browser support in README

It would be good to have some info on supported browsers or — and maybe that is more relevant — unsupported browsers.

Given the use of DOMContentLoaded and addEventListener, I'm guessing IE8 is not supported. Has this been tried in IE9? Android browser 4.x?

aria-labelledby

Ensuring your hidden/shown region has a correct label is important, moreover if the region is expanded by default.

You may add two things:

  • an [id] to your button;
  • an [aria-labelledby]to your expanding region, referring to button's [id].

Pretty easy to automate, I guess. Please also consider that "Read more" is generally not a good way to label anything ;)

Here are a few examples using it:

What do you think about it?

Non interactive elements can't be controlled via keyboard

Even with role="button" and tabindex="0". The toggle can be tabbed too, but not triggered.

https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/ARIA_Techniques/Using_the_button_role

Buttons are interactive controls and thus focusable. If the button role is added to an element that is not focusable by itself (such as <span>, <div> or <p>) then, the tabindex attributes have to be used to make the button focusable.

But if another tag is used to create a custom button, the onclick event will only fire when clicked by the mouse cursor, even if role="button" is used. Because of this, the developer will have to surely add a separate key event handler to the element so that the button can be triggered,even when the space key is pressed.

Needs some javascript to capture the keyboard events for non-interactive elements

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.