Code Monkey home page Code Monkey logo

van11y-accessible-hide-show-aria's Introduction

Van11y Accessible hide/show (collapsible regions) using ARIA

Van11y

This script will transform a simple list of Hx/contents into shiny and accessible hide/show – collapsible regions – using ARIA.

The demo is here: https://van11y.net/downloads/hide-show/demo/index.html

Website is here: https://van11y.net/accessible-hide-show/

La page existe aussi en français : https://van11y.net/fr/panneaux-depliants-accessibles/

How it works

Basically, it transforms this:

<h2 class="js-expandmore">Lorem dolor si amet</h2>
<div class="js-to_expand">
   here the hidden content
</div>

Into this:

<h2 class="js-expandmore">
  <button data-controls="expand_1" aria-expanded="false" class="expandmore__button" type="button">Lorem dolor si amet</button>
</h2>
<div id="expand_1" class="js-to_expand" data-labelledby="label_expand_1" data-hidden="true">
   here the hidden content
</div>

Attribute values are generated on-the-fly (data-controls="expand_1", id="expand_1", data-labelledby="label_expand_1"), no need to worry about it.

The script is launched when the page is loaded. If you need to execute it on AJAX-inserted content, you may use for example on <div id="newContent">your expand source</div>:

var my_expand = van11yAccessibleHideShowAria();
my_expand.attach(document.getElementById('newContent'));

How to use it

Download the script

You may use npm command: npm i van11y-accessible-hide-show-aria. You may also use bower: bower install van11y-accessible-hide-show-aria.

Conventions

Please follow this convention (the conventions may be adapted to your needs, see in bonuses):

<h2 class="js-expandmore">Lorem dolor si amet</h2>
<div class="js-to_expand">
   here the hidden content
</div>

For accessibility reasons, you shall add class="js-expandmore" on an Hx (h1, h2, h3, etc.). Elements that have js-expandmore and js-to_expand classes must be adjacent.

Then use the script, it will do the rest.

Styles needed to work

The minimal style needed is:

.js-to_expand[aria-hidden=true],
.js-to_expand[data-hidden=true] {
  display: none;
}

However, as the plugin adds a button into a Hx, you will have to style this case. Here is an example:

.expandmore__button {
  background: none;
  font-size: inherit;
  color: inherit;
}
/* optional */
.expandmore__button:before,
.expandmore__button:before {
  content : '+ ';
}
.expandmore__button[aria-expanded=true]:before,
.expandmore__button[data-expanded=true]:before {
  content : '- ';
}

How to create different styles?

It is possible and very simple, you may use the attribute data-hideshow-prefix-class="<your_value>" like this:

<h2 class="js-expandmore" data-hideshow-prefix-class="mini-combo">Lorem dolor si amet</h2>
<div class="js-to_expand">
   here the hidden content
</div>

It will prefix generated classes, <your_value>-expandmore__button and <your_value>-expandmore__to_expand, like this:

<h2 class="js-expandmore" data-hideshow-prefix-class="mini-combo">
 <button id="label_expand_2" class="mini-combo-expandmore__button js-expandmore-button" data-controls="expand_2" aria-expanded="false" type="button">
  Lorem dolor si amet
 </button>
</h2>
<div id="expand_2" class="js-to_expand mini-combo-expandmore__to_expand" data-hidden="true" data-labelledby="label_expand_2">
 here the hidden content
</div>

The script will prefix all classes, so you will able to style elements as you want. If you don’t use it, the script won’t mind.

Bonuses

Opened by default

No problem, it is possible and very simple, use the class is-opened on:

<h2 class="js-expandmore">Lorem dolor si amet</h2>
<div class="js-to_expand is-opened">
   here the hidden content
</div>

The script will detect it, and make it open by default. As simple as one copy/paste.

Animations

No problem, it is possible using some CSS transitions. You have to keep in mind several things to keep it accessible:

  • You can’t animate the display property, and height property might be complicated too to animate.
  • So you can’t use display: none; to hide a content (even for assistive technologies).
  • You have to set up visibility to visible or hidden to show/hide a content.
  • Basically, you should animate max-height, opacity (if needed), and use visibility to hide content to assistive technology.

If you have clicked on this section, you might have noticed the animation. Let’s assume we are using this source:

<h2 class="js-expandmore mb0 mt0" data-hideshow-prefix-class="animated">Bonus: some animations?</h2>
 <div class="js-to_expand"></div>

So here is the CSS code (unprefixed):

/* This is the opened state */
.animated-expandmore__to_expand {
 display: block;
 overflow: hidden;
 opacity: 1;
 transition: visibility 0s ease, max-height 2s ease, opacity 2s ease ;
 max-height: 80em;
 /* magic number for max-height = enough height */
 visibility: visible;
 transition-delay: 0s;
}
/* This is the hidden state */
[data-hidden=true].animated-expandmore__to_expand {
 display: block;
 max-height: 0;
 opacity: 0;
 visibility: hidden;
 transition-delay: 2s, 0s, 0s;
}

Here is the trick: from “hidden” to “visible” state, visibility is immediately set up to visible, and max-height/opacity are “normally” animated.

From “visible” to “hidden” state, the visibility animation is delayed. So the content will be immediately hidden… at the end of the animation of max-height/opacity.

Default config

const CONFIG = {
    HIDESHOW_EXPAND: 'js-expandmore',
    HIDESHOW_BUTTON_EXPAND: 'js-expandmore-button',
    HIDESHOW_BUTTON_EXPAND_STYLE: 'expandmore__button',
    HIDESHOW_BUTTON_LABEL_ID: 'label_expand_',

    DATA_PREFIX_CLASS: 'data-hideshow-prefix-class',

    HIDESHOW_BUTTON_EMPTY_ELEMENT_SYMBOL: 'expandmore__symbol',
    HIDESHOW_BUTTON_EMPTY_ELEMENT_TAG: 'span',
    ATTR_HIDESHOW_BUTTON_EMPTY_ELEMENT: 'aria-hidden',

    HIDESHOW_TO_EXPAND_ID: 'expand_',
    HIDESHOW_TO_EXPAND_STYLE: 'expandmore__to_expand',

    /*
     recommended settings by a11y expert
    */
    ATTR_CONTROL: 'data-controls',
    ATTR_EXPANDED: 'aria-expanded',
    ATTR_LABELLEDBY: 'data-labelledby',
    ATTR_HIDDEN: 'data-hidden',

    IS_OPENED_CLASS: 'is-opened',

    DISPLAY_FIRST_LOAD: 'js-first_load',
    DISPLAY_FIRST_LOAD_DELAY: '1500',
    ...config
};

If you need to use another configuration, you may call the plugin like this:

var other_expand = van11yAccessibleHideShowAria({
     HIDESHOW_EXPAND: 'js-expandmore2',
     DATA_PREFIX_CLASS: 'data-hideshow-prefix-class2'
    });
other_expand.attach();

ARIA attributes or data attributes?

No problem. At the beginning of the plugin, you can set up the attributes you need for your special case.

ATTR_CONTROL: 'data-controls',
ATTR_EXPANDED: 'aria-expanded',
ATTR_LABELLEDBY: 'data-labelledby',
ATTR_HIDDEN: 'data-hidden',

However, the default settings are recommended by accessibility experts.

If you need to update, you can do it anyway, the plugin will adapt itself. Example:

var my_expand = van11yAccessibleHideShowAria({
    ATTR_CONTROL: 'aria-controls',
    ATTR_EXPANDED: 'aria-expanded',
    ATTR_LABELLEDBY: 'aria-labelledby',
    ATTR_HIDDEN: 'aria-hidden',
    });
my_expand.attach();

Of course, you will have to update your CSS by using the good attributes.

van11y-accessible-hide-show-aria's People

Contributors

dhoko avatar nico3333fr 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

Watchers

 avatar  avatar  avatar  avatar

van11y-accessible-hide-show-aria's Issues

Rewamp builds

TODO:

  • scripts should work with webpack/gulp (with or without autoload),

  • and "normal" guy which is not strong at JS should be able to take a built file (with or without autoload) and it works on a "classic" site.

  • bonus: if we can move to gulp v4, this will be puuuurfect.

ping @dhoko

ARIA is insufficient and fails screenreaders

Your examples look nice, but they are failing the point of ARIA attributes completely. You link to the excellent inspiration, but the resulting markup is adding aria-expanded on the button instead of the expanded field. You're also not hiding the expandable in any way from screenreaders.

Current output code

<h2 class="js-expandmore" data-hideshow-prefix-class="animated">
  <button class="animated-expandmore__button js-expandmore-button" data-controls="expand_1ugacpb3ta" aria-expanded="true" id="label_expand_1ugacpb3ta" type="button"><span class="animated-expandmore__symbol" aria-hidden="true"></span>Example animated (opened by default)</button>
</h2>
<div class="js-to_expand animated-expandmore__to_expand" data-labelledby="label_expand_1ugacpb3ta" id="expand_1ugacpb3ta">
    <p>Yes, it rocks.</p>
 </div>

Main key missing from package.json

A main entry is missing from package.json:

missing main: https://github.com/nico3333fr/van11y-accessible-hide-show-aria/blob/master/package.json

has main: https://github.com/nico3333fr/van11y-accessible-modal-window-aria/blob/7e5d7b90c41d4990621e514b1669bf724fc68806/package.json#L5

The exclusion of the main key is causing webpack to throw an error: cannot resolve module van11y-accessible-hide-show-aria.

Thank you for all your work on this wonderful package.
Take care

Allow reusing an existing button

Hi,

I'd like to implement this script, but my page already has a button with specific classes on it. How can I initialize the script and make it use the existing button, instead of creating a new button in a h* element?

Thanks

Edge - van11y 'AccessibleHideShowAria' is not defined

Hi!
I'm using this script on a new project, and I faced an issue on Edge : It's not working there is an error in the console.

By going to the demo page with Edge :
https://van11y.net/downloads/hide-show/demo/index.html

0: van11y 'AccessibleHideShowAria' is not defined.

Updated Windows 10
Edge 44.18362
EdgeHTML 18.18

EDIT :
In my project (Gulp + Webpack with Babel etc.) I include the es6 file this is why I have the error, I think you also use this one on the demo.
By importing the simple .js file it's okay.

Handle a dropdown variant

Hi there,

It would be great to mention and demonstrate that this script might be used for dropdowns :)
As far as I understand, it should only be a style variant.

Thanks :)

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.