A tiny JavaScript library to easily toggle the state of any HTML element, and create UI components in no time.
Dropdown, navigation button, tooltip, collapsible panel, lightbox, tabs, switch like above…
UI components made in minutes without worried about JavaScript. Only set a few HTML attributes, and code the rest with your CSS skills.
Why?
A front-end developer often has to code scripts for interface components. Components such as dropdowns, navigation buttons, tooltips, expandable panels, lightboxes, tabs, etc.
The thing is… Most of these components expose a recurrent behavior: a trigger element toggles the state of one or more target elements. So why not code this behavior once and for all?
So here is a solution: a simple script to toggle the state of a trigger element with a CSS class. You can then associate this element with one or more others: let’s call them targets. By adding the right HTML attributes, it can adapt to any contexts and behave like a chosen component.
Only focus on adjusting the rest with your CSS creativity.
Quickstart
Locally
- Direct download
- Or choose another version: ES5 or ES6
Then, add the script into your page:
<script src="./your-path/easy-toggle-state.es6.min.js"></script>
and it’s done.
From CDN
Easy Toggle State is available on cdnjs, so you can link it directly from there instead of using it locally.
Go check easy-toggle-state on cdnjs.
With NPM
Install with npm:
npm install easy-toggle-state
Then use Easy Toggle State into your application, inside your JS file:
import easyToggle from "easy-toggle-state";
easyToggle();
For example, you could make sure your DOM is fully loaded before initializing Easy Toggle State in your page. To do so:
import easyToggle from "easy-toggle-state";
const handler = () => {
easyToggle();
document.removeEventListener("DOMContentLoaded", handler);
};
document.addEventListener("DOMContentLoaded", handler);
Refer to the API using ES module section to learn more about what you can do.
About compatibility
In addition to using ES5 version, compatibility for Internet Explorer is provided by polyfill.io which supports back to IE 7. It brings polyfills for Array.from
, Array.filter
, Element.closest
and more.
And before you ask, yes, you can run it locally.
How to use
First recommendation
Although you could use any element you want, I strongly recommend using only buttons as trigger elements. It’s more accessible, and it’s meant to be used for this kind of thing. The following examples will show you that.
If you still want to use links with fake href
values, such as href="#"
, don’t forget to add role="button"
attribute.
And please, don’t use divs or spans anymore.
Basics
-
<foo data-toggle-class="class">
-
A CSS class to toggle each time a click is triggered on this element. If empty, the
is-active
class is used. -
<foo data-toggle-class="class" data-toggle-target="selector">
-
Toggle the class on the trigger element and all the target elements, defined by the selector, in the page.
The
selector
value must be a valid CSS selector string, containing one or more selectors to match. Learn more about CSS selectors.
Targeting
You can go further into selecting targets by using one of the following options that specify a scope within which targets can be selected.
-
<foo data-toggle-class="class" data-toggle-target="selector">
-
Basic targeting: Toggle the class on the trigger element and all the target elements, defined by the selector, in the whole page. This attribute has
data-toggle-target-all
as alias. -
<foo data-toggle-class="class" data-toggle-target-parent="selector">
-
Toggle the class on the trigger element and all the target elements, defined by the selector, belonging to its parent container.
-
<foo data-toggle-class="class" data-toggle-target-self="selector">
-
Toggle the class on the trigger element and all the target elements, defined by the selector, within it.
-
<foo data-toggle-class="class" data-toggle-target-previous>
-
Toggle the class on the trigger element and its previous adjacent element.
-
<foo data-toggle-class="class" data-toggle-target-next>
-
Toggle the class on the trigger element and its next adjacent element.
Toggling
You can go further into toggling too, by choosing if some classes must be toggled only on trigger, or only on targets, or on both. And you can combine these options.
Actually, you can fill these toggling attributes with as many classes as you need. If an attribute is left empty, the default class is-active
is used.
-
<foo data-toggle-class="class1 class2 class3" data-toggle-target="selector">
-
Toggle each class on the trigger element and all the target elements.
-
<foo data-toggle-class-on-trigger="class1 class2 class3">
-
Toggle each class only on the trigger element.
-
<foo data-toggle-class-on-target="class1 class2 class3" data-toggle-target="selector">
-
Toggle each class only on all the target elements.
Note that this attribute must be used with one of the targeting attributes,
data-toggle-target
[?] for example.
Advanced
-
data-toggle-is-active
-
Specify a trigger element and its targets toggled as default, set during the
onload
event. In this case, you should add the specified class name on each element, even if the script will check that for you. -
data-toggle-group="group"
-
Specify if a trigger is a part of a group. Only one trigger of a group can be active at a time. It will actually behave like an accordion component.
-
data-toggle-radio-group="group"
-
Specify if a trigger is a part of a radio group. Only one trigger of a radio group can be active at a time.
Unlike a simple group as seen above, as soon as a trigger is activated, a radio group will always keep one trigger active. It will actually behave like radio buttons or tabs component.
Note that a radio grouped trigger can’t have
data-toggle-outside
ordata-toggle-escape
behavior. -
data-toggle-event="event"
-
Specify the event that will toggle the class,
mouseover
for example.click
by default if not specified. -
data-toggle-outside
-
Toggle off the class when the event is triggered again outside of the trigger element. The event will be the same as
data-toggle-event
value, orclick
by default.Note that this attribute does not work on an element with
data-toggle-radio-group="group"
. -
data-toggle-outside-event="event"
-
When using
data-toggle-outside
attribute, add this attribute to use a specific event for that behavior.Note that this attribute only works when used in addition to
data-toggle-outside
attribute. -
data-toggle-escape
-
Toggle the class when the trigger element is active and when the escape key is pressed.
Note that this attribute does not work on an element with
data-toggle-radio-group="group"
. -
data-toggle-arrows
-
Specify that when a grouped trigger is focused, you can navigate between other triggers of the same group with arrows ↑ → ↓ ←, home and end keys.
Remember that this attribute must be used with
data-toggle-group
ordata-toggle-radio-group
. -
data-toggle-modal
-
Specify that the target is a modal, such as a dialog or a lightbox. This way, when the target is active – open –, the focus is trapped inside this target. This means tabbing will only focus on focusable elements inside this target, letting anything outside be out of scope.
Be really careful when using this feature. A focus trap can be very annoying – and an accessibility fault – when used in a wrong way, so be sure your target is a modal component.
-
data-toggle-trigger-off
-
Add this attribute to an element inside a target to enable it to toggle the state of this target. For example, a close button inside a modal.
Remember that this attribute must be used on an element that must be placed inside a target element.
Accessibility
If a trigger or a target element has an ARIA attribute, its value will also change, so please consider using the right roles and ARIA attributes to optimize your components for accessibility.
The list of supported ARIA attributes is:
aria-checked
aria-expanded
aria-hidden
aria-pressed
aria-selected
The following examples will help you for that.
Expert
Custom prefix
You can change the prefix toggle
in data-toggle-class
and every attributes to prevent conflict with another JS library. To do so, add this attribute to your <html>
element with your new prefix:
<html data-easy-toggle-state-custom-prefix="my-prefix">
It will so be set to all attributes like data-my-prefix-class
.
Toggling combination
You can combine all toggling attributes. This way, Easy Toggle State is compatible with any CSS framwork.
<foo
data-toggle-class="is-open"
data-toggle-class-on-trigger="text-white font-bold bg-blue"
data-toggle-class-on-target="text-gray bg-white"
data-toggle-target="#plop">
With the combination, a click on the trigger element will toggle:
is-open
,text-white
,font-bold
,bg-blue
classes on this triggeris-open
,text-gray
,bg-white
classes on the target, the element#plop
API
API using the bundle (locally or from CDN)
initialization
Initialize all trigger elements not yet binded.
window.easyToggleState();
No parameter. Returns an Array of newly initialized trigger elements.
unbind
Unbind a trigger element, or a trigger element list.
window.easyToggleState.unbind( Node || NodeList );
Takes a Node or a NodeList as parameter. Returns the same Node or NodeList.
unbindAll
Unbind all trigger elements.
window.easyToggleState.unbindAll();
No parameter. Returns a NodeList of all newly unbinded trigger elements.
isActive
Get the state of a trigger element.
window.easyToggleState.isActive( Node );
Takes a Node as parameter. Returns a boolean.
API using ES module
initialization
Initialize all trigger elements not yet binded.
import initialize from "easy-toggle-state";
initialize();
No parameter. Returns an Array of newly initialized trigger elements.
unbind
Unbind a trigger element, or a trigger element list.
import { unbind } from "easy-toggle-state";
unbind( Node || NodeList );
Takes a Node or a NodeList as parameter. Returns the same Node or NodeList.
unbindAll
Unbind all trigger elements.
import { unbindAll } from "easy-toggle-state";
unbindAll();
No parameter. Returns a NodeList of all newly unbinded trigger elements.
isActive
Get the state of a trigger element.
import { isActive } from "easy-toggle-state";
isActive( Node );
Takes a Node as parameter. Returns a boolean.
Hooks
You can also add some hooks: each trigger and target element fires a toggleBefore
event before and a toggleAfter
event after toggling its state, so you can add event listeners on these events, and test the active state.
For example:
document.querySelector("#myTrigger").addEventListener("toggleAfter", event => {
console.log(`Active: ${window.easyToggleState.isActive(event.target)}`);
}, false);
Examples
Here are some demos to show you how this is powerful.
Of course, these examples can be made in other ways, with Easy Toggle State or not. For example, checkboxes, switchboxes and radio buttons can be made in pure CSS using natives inputs and labels.
Checkbox
You want to display a checkbox, i.e. a box with a checkmark that appears on click on this box.
Even if you should use the <input type="checkbox">
native component, in some case, you can’t.
Simple checkbox
<button type="button"
class="example-checkbox"
data-toggle-class="is-checked">
</button>
Checkbox with ARIA attributes for accessibility
<button type="button"
class="example-checkbox"
data-toggle-class="is-checked"
role="checkbox"
aria-checked="false"
title="Toggle this box">
<span class="sr-only">Toggle</span>
</button>
Checkbox with external label
<button type="button"
class="example-checkbox"
data-toggle-class="is-checked"
id="checkbox"
role="checkbox"
aria-checked="false"
title="Toggle this box">
<span class="sr-only">Toggle</span>
</button>
<label for="checkbox">
Awesome checkbox
</label>
Checkbox with internal label
<button type="button"
class="example-checkbox-container"
data-toggle-class="is-checked"
data-toggle-target-self=".example-checkbox"
role="checkbox"
aria-checked="false">
<span class="example-checkbox" aria-hidden="true"></span>
Awesome checkbox
</button>
Explanation
Toggle .is-checked
class on click on the box. As aria-checked
attribute is set, its value changes too.
The CSS class .sr-only
is for hiding content for accessibility.
Switchbox
You want to display a switchbox, i.e. a box with a "ball" that moves on click on this box.
Even if you should use the <input type="checkbox">
native component, in some case, you can’t.
Switchbox with an external label
<button type="button"
class="example-switchbox"
data-toggle-class="is-pressed"
id="switchbox"
aria-pressed="false"
title="Toggle this box">
<span class="example-switchbox-yes" aria-hidden="true">yes</span>
<span class="example-switchbox-no" aria-hidden="true">no</span>
<span class="sr-only">Toggle</span>
</button>
<label for="switchbox">
Isn’t this awesome?
</label>
Explanation
Toggle .is-pressed
class on click on the box. As aria-pressed
attribute is set, its value changes too.
The words “yes” and “no” are here to add more sense and to make this component more accessible by not rendering each state with only colors.
The CSS class .sr-only
is for hiding content for accessibility.
Radio buttons
You want to display some radio buttons, i.e. some circles which are filled on click on them, only one at a time.
Even if you should use the <input type="radio">
native component, in some case, you can’t.
Simple radio buttons
<button type="button"
class="example-radio"
id="radio_1"
data-toggle-class="is-checked"
data-toggle-radio-group="radioGroup">
</button>
<label for="radio_1">Option 1</label><br>
<button type="button"
class="example-radio"
id="radio_2"
data-toggle-class="is-checked"
data-toggle-radio-group="radioGroup">
</button>
<label for="radio_2">Option 2</label><br>
<button type="button"
class="example-radio"
id="radio_3"
data-toggle-class="is-checked"
data-toggle-radio-group="radioGroup">
</button>
<label for="radio_3">Option 3</label>
Radio buttons with arrow keys support
<button type="button"
class="example-radio"
id="radio_1"
data-toggle-class="is-checked"
data-toggle-radio-group="radioGroup"
data-toggle-arrows>
</button>
<label for="radio_1">Option 1</label><br>
<button type="button"
class="example-radio"
id="radio_2"
data-toggle-class="is-checked"
data-toggle-radio-group="radioGroup"
data-toggle-arrows>
</button>
<label for="radio_2">Option 2</label><br>
<button type="button"
class="example-radio"
id="radio_3"
data-toggle-class="is-checked"
data-toggle-radio-group="radioGroup"
data-toggle-arrows>
</button>
<label for="radio_3">Option 3</label>
Radio buttons with ARIA attributes for accessibility
<div role="radiogroup">
<button type="button"
class="example-radio"
id="radio_1"
data-toggle-class="is-checked"
data-toggle-radio-group="radioGroup"
data-toggle-arrows
role="radio"
aria-checked="false"
title="Toggle this box">
<span class="sr-only">Toggle</span>
</button>
<label for="radio_1">Option 1</label><br>
<button type="button"
class="example-radio"
id="radio_2"
data-toggle-class="is-checked"
data-toggle-radio-group="radioGroup"
data-toggle-arrows
role="radio"
aria-checked="false"
title="Toggle this box">
<span class="sr-only">Toggle</span>
</button>
<label for="radio_2">Option 2</label><br>
<button type="button"
class="example-radio"
id="radio_3"
data-toggle-class="is-checked"
data-toggle-radio-group="radioGroup"
data-toggle-arrows
role="radio"
aria-checked="false"
title="Toggle this box">
<span class="sr-only">Toggle</span>
</button>
<label for="radio_3">Option 3</label>
</div>
Explanation
Toggle .is-checked
class on click on this element, but only one of the radioGroup
group at a time, and always keep one active. As aria-checked
attribute is set, its value changes too.
Thanks to data-toggle-arrows
[?] attribute, you can navigate between options with arrow keys as soon as one option is focused.
The label is associated to the trigger by the for
attribute.
The CSS class .sr-only
is for hiding content for accessibility.
Tooltip
You want to put a tooltip on a text, i.e. show an element when hovering this text, and hide it when the cursor leaves this text.
In most of cases, tooltips are not a good idea for displaying information, and are not accessible to all, screen readers for instance, so please consider not using it, or only for trivial contents.
Simple tooltip
<span class="example-tooltip"
data-toggle-class-on-target="is-visible"
data-toggle-target-self=".tooltip"
data-toggle-event="mouseover"
data-toggle-outside
aria-describedby="tooltip_id">
Hover me
<span class="tooltip"
id="tooltip_id"
role="tooltip"
aria-hidden="true">
Awesome tooltip
</span>
</span>
Double-click tooltip
<span class="example-tooltip"
data-toggle-class-on-target="is-visible"
data-toggle-target-self=".tooltip"
data-toggle-event="dblclick"
data-toggle-outside
data-toggle-outside-event="click"
aria-describedby="tooltip_id">
Click twice on me
<span class="tooltip"
id="tooltip_id"
role="tooltip"
aria-hidden="true">
Awesome tooltip
</span>
</span>
Explanation
Toggle .is-visible
class only on the target .tooltip
located inside this trigger.
In the simple tooltip example, toggle on mouseover
event, and toggle again when mouseover
outside of this trigger, as mentioned in data-toggle-event
[?] attribute.
In the double-click example, toggle on dblclick
event, and, since the data-toggle-outside-event
[?] attribute is specified, toggle again when click
is triggered outside of this trigger.
As aria-hidden
attribute is set, its value changes too.
Collapsible panel / accordion
You want to create a collapsible panel, i.e. a frame, with some content, that can be collapsed on click on a button.
Even if you should use <details>
and <summary>
HTML elements, in some case, you can’t.
Simple collapsible panel
<button type="button"
class="example-collapsible-button"
data-toggle-class="is-open"
data-toggle-target-next>
Click here
</button>
<div class="example-collapsible-panel">
<div class="example-collapsible-panel-content">
Lorem ipsum dolor sit amet…
</div>
</div>
Collapsible panel with escape key support
<button type="button"
class="example-collapsible-button"
data-toggle-class="is-open"
data-toggle-target-next
data-toggle-escape>
Click here
</button>
<div class="example-collapsible-panel">
<div class="example-collapsible-panel-content">
Lorem ipsum dolor sit amet…
</div>
</div>
Collapsible panel with ARIA attributes for accessibility
<button type="button"
class="example-collapsible-button"
id="buttonForPanel"
data-toggle-class="is-open"
data-toggle-target-parent="#panel"
data-toggle-escape
aria-controls="panel"
aria-expanded="false">
Click here
</button>
<div class="example-collapsible-panel"
id="panel"
role="region"
aria-labelledby="buttonForPanel"
aria-hidden="true">
<div class="example-collapsible-panel-content">
Lorem ipsum dolor sit amet…
</div>
</div>
Accordion
<!-- First panel, opened by default -->
<button type="button"
class="example-collapsible-button"
id="buttonForPanel_1"
data-toggle-class="is-open"
data-toggle-target-parent="#panel_1"
data-toggle-group="accordion"
data-toggle-escape
data-toggle-arrows
data-toggle-is-active
aria-controls="panel_1"
aria-expanded="true">
Click here
</button>
<div class="example-collapsible-panel"
id="panel_1"
role="region"
aria-labelledby="buttonForPanel_1"
aria-hidden="false">
<div class="example-collapsible-panel-content">
Lorem ipsum dolor sit amet…
</div>
</div>
<!-- Second panel -->
<button type="button"
class="example-collapsible-button"
id="buttonForPanel_2"
data-toggle-class="is-open"
data-toggle-target-parent="#panel_2"
data-toggle-group="accordion"
data-toggle-escape
data-toggle-arrows
aria-controls="panel_2"
aria-expanded="false">
Click here
</button>
<div class="example-collapsible-panel"
id="panel_2"
role="region"
aria-labelledby="buttonForPanel_2"
aria-hidden="true">
<div class="example-collapsible-panel-content">
In in erat blandit ante mollis tincidunt…
</div>
</div>
<!-- … -->
Explanation
The button toggles .is-open
class on itself and its target located inside its parent container. If there’s more than one button / panel, be careful to target a unique ID.
For an accordion, each trigger must be linked to the same group with data-toggle-group
[?] attribute, here accordion
. This way, only one of this group can be opened at a time. The first panel is opened by default with data-toggle-is-active
[?].
Thanks to data-toggle-arrows
[?] attribute, you can also navigate between panels with arrow keys as soon as one tab is focused.
As aria-expanded
and aria-hidden
attributes are set, their value changes too.
Tabs
You want to create some tabs, i.e. some panels visualizable by clicking on their associated button.
Simple tabs
<div class="example-tabs">
<button type="button"
data-toggle-class
data-toggle-target="#tabPanel_1"
data-toggle-radio-group="tabsGroup"
data-toggle-is-active>
tab 1
</button>
<button type="button"
data-toggle-class
data-toggle-target="#tabPanel_2"
data-toggle-radio-group="tabsGroup">
tab 2
</button>
<button type="button"
data-toggle-class
data-toggle-target="#tabPanel_3"
data-toggle-radio-group="tabsGroup">
tab 3
</button>
</div>
<div class="example-tab-panel" id="tabPanel_1">
Panel 1<br>
Lorem ipsum dolor sit amet…
</div>
<div class="example-tab-panel" id="tabPanel_2">
Panel 2<br>
In in erat blandit ante mollis tincidunt…
</div>
<div class="example-tab-panel" id="tabPanel_3">
Panel 3<br>
Nam posuere tortor a augue vulputate…
</div>
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Etiam semper faucibus odio, vitae faucibus dui tempor in. Duis vitae luctus mi. Phasellus ultrices rhoncus lectus, non vehicula tortor sodales id.
In in erat blandit ante mollis tincidunt. Quisque ac tempus nisi, a ultricies metus. Suspendisse et quam nec mauris feugiat luctus. Curabitur porta sem vitae nulla congue malesuada.
Nam posuere tortor a augue vulputate, at blandit ipsum tincidunt. Donec dictum eros ligula, id congue justo porta eget. Aliquam vel erat venenatis, ornare nisi vel, convallis libero.
Tabs with arrow keys support
<div class="example-tabs">
<button type="button"
data-toggle-class
data-toggle-target="#tabPanel_1"
data-toggle-radio-group="tabsGroup"
data-toggle-arrows
data-toggle-is-active>
tab 1
</button>
<button type="button"
data-toggle-class
data-toggle-target="#tabPanel_2"
data-toggle-radio-group="tabsGroup"
data-toggle-arrows>
tab 2
</button>
<!-- … -->
</div>
<div class="example-tab-panel" id="tabPanel_1">
Panel 1<br>
Lorem ipsum dolor sit amet…
</div>
<div class="example-tab-panel" id="tabPanel_2">
Panel 2<br>
In in erat blandit ante mollis tincidunt…
</div>
<!-- … -->
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Etiam semper faucibus odio, vitae faucibus dui tempor in. Duis vitae luctus mi. Phasellus ultrices rhoncus lectus, non vehicula tortor sodales id.
In in erat blandit ante mollis tincidunt. Quisque ac tempus nisi, a ultricies metus. Suspendisse et quam nec mauris feugiat luctus. Curabitur porta sem vitae nulla congue malesuada.
Nam posuere tortor a augue vulputate, at blandit ipsum tincidunt. Donec dictum eros ligula, id congue justo porta eget. Aliquam vel erat venenatis, ornare nisi vel, convallis libero.
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Etiam semper faucibus odio, vitae faucibus dui tempor in. Duis vitae luctus mi. Phasellus ultrices rhoncus lectus, non vehicula tortor sodales id.
In in erat blandit ante mollis tincidunt. Quisque ac tempus nisi, a ultricies metus. Suspendisse et quam nec mauris feugiat luctus. Curabitur porta sem vitae nulla congue malesuada.
Nam posuere tortor a augue vulputate, at blandit ipsum tincidunt. Donec dictum eros ligula, id congue justo porta eget. Aliquam vel erat venenatis, ornare nisi vel, convallis libero.
Tabs with ARIA attributes for accessibility
<div class="example-tabs" role="tablist">
<button type="button"
id="tab_1"
data-toggle-class
data-toggle-target="#tabPanel_1"
data-toggle-radio-group="tabsGroup"
data-toggle-arrows
data-toggle-is-active
role="tab"
aria-selected="true"
aria-controls="tabPanel_1">
tab 1
</button>
<button type="button"
id="tab_2"
data-toggle-class
data-toggle-target="#tabPanel_2"
data-toggle-radio-group="tabsGroup"
data-toggle-arrows
role="tab"
aria-selected="false"
aria-controls="tabPanel_2">
tab 2
</button>
<!-- … -->
</div>
<div class="example-tab-panel"
id="tabPanel_1"
role="tabpanel"
aria-labelledby="tab_1"
aria-hidden="false">
Panel 1<br>
Lorem ipsum dolor sit amet…
</div>
<div class="example-tab-panel"
id="tabPanel_2"
role="tabpanel"
aria-labelledby="tab_2"
aria-hidden="true">
Panel 2<br>
In in erat blandit ante mollis tincidunt…
</div>
<!-- … -->
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Etiam semper faucibus odio, vitae faucibus dui tempor in. Duis vitae luctus mi. Phasellus ultrices rhoncus lectus, non vehicula tortor sodales id.
Explanation
Toggle .is-active
class – by default – on click on this element, but only one of the tabsGroup
group at a time, and always keep one active. Toggle the same class on the target element. As there’s more than one button / panel, be careful to target a unique ID.
Each trigger must be linked to the same group, here tabsGroup
. This way, only one of this group can be opened at a time. Since data-toggle-radio-group
[?] is used instead of data-toggle-group
[?], this group will always keep one of its triggers active. The first panel is opened by default with data-toggle-is-active
[?].
Thanks to data-toggle-arrows
[?] attribute, you can also navigate between panels with arrow keys as soon as one tab is focused.
As aria-selected
and aria-hidden
attributes are set, their value changes too.
Dropdown
You want to create a dropdown, i.e. a list of choices that appears when you click on a button. Of course you should use <select>
and <option>
HTML elements, but in some case, you can’t.
Simple dropdown
<div class="example-dropdown">
<button type="button"
class="example-dropdown-button"
data-toggle-class="is-open"
data-toggle-target-next
data-toggle-outside
data-toggle-escape>
Select something here
</button>
<ul class="example-dropdown-list">
<li>
<button type="button">Lorem ipsum dolor</button>
</li>
<!-- Several options -->
</ul>
</div>
Dropdown with ARIA attributes for accessibility
<div class="example-dropdown">
<button type="button"
class="example-dropdown-button"
data-toggle-class="is-open"
data-toggle-target-next
data-toggle-outside
data-toggle-escape
id="dropdownButton"
aria-haspopup="listbox"
aria-controls="dropdownList"
aria-expanded="false">
Select something here
</button>
<ul class="example-dropdown-list"
id="dropdownList"
role="listbox"
aria-labelledby="dropdownButton"
aria-hidden="true">
<li>
<button type="button">Lorem ipsum dolor</button>
</li>
<!-- Several options -->
</ul>
</div>
Explanation
Toggle .is-open
class on click on this element. At the same time, toggle the class on its target, the next adjacent element, thanks to data-toggle-target-next
[?] attribute.
The attributes data-toggle-outside
[?] and data-toggle-escape
[?] means you can click outside of the trigger or its target, or press escape key to toggle off.
You could also add data-toggle-trigger-off
[?] attribute on each option button to toggle off dropdown’s state by clicking on them.
As aria-expanded
and aria-hidden
attributes are set, their value change too.
Note: You can not change the value of the trigger by clicking on an option with this script. Easy Toggle State only deals with changing state. You will have to do this by yourself.
Dialog
You want to create a dialog, i.e. an information or form box displayed in front of all page content on click on a trigger.
Even if you should use <dialog>
HTML element, in some case, you can’t.
Simple dialog
<button type="button"
class="example-dialog-trigger"
data-toggle-class-on-target
data-toggle-target="#dialog"
data-toggle-escape
data-toggle-modal>
Click to see the awesomeness
</button>
<!-- This dialog anywhere you want in the page -->
<div class="example-dialog" id="dialog">
<section class="example-dialog-container">
<!-- Your content here, such as text or form. -->
<button type="button" data-toggle-trigger-off>close</button>
</section>
</div>
Any content you want, such as text or form.
The following fake links are here to illustrate the focus trap inside this modal, thanks to data-toggle-modal
attribute on the trigger.
Lorem ipsum dolor sit amet, consectetur adipisicing elit. Et quibusdam labore tempore repudiandae minima earum adipisci, dolor distinctio facere illo recusandae fuga placeat amet corrupti omnis ullam accusamus reprehenderit id.
Dialog with ARIA attributes for accessibility
<button type="button"
class="example-dialog-trigger"
data-toggle-class-on-target
data-toggle-target="#dialog"
data-toggle-escape
data-toggle-modal>
Click to see the awesomeness
</button>
<!-- This dialog anywhere you want in the page -->
<div class="example-dialog"
id="dialog"
role="dialog"
aria-labelledby="dialogTitle"
aria-describedby="dialogContent"
aria-hidden="true">
<section class="example-dialog-container">
<header id="dialogTitle" class="example-dialog-header">
Dialog title
</header>
<div id="dialogContent" class="example-dialog-content">
<!-- Your content here, such as text or form. -->
</div>
<footer class="example-dialog-footer">
<button type="button" data-toggle-trigger-off>close</button>
</footer>
</section>
</div>
Explanation
Toggle .is-active
class – as default – on click on this element. Toggle the class on its target #dialog
, placed anywhere in the page – at the bottom for example –, at the same time. Press escape key to toggle off, thanks to data-toggle-escape
[?] attribute.
The attribute data-toggle-modal
[?] specify that the target is a modal, and create a focus trap inside of it when active.
The attribute data-toggle-trigger-off
[?] enable the “close” button to toggle off dialog’s state by clicking on it.
As aria-hidden
attribute is set, its value changes too.
Lightbox
You want to create a lightbox, i.e. a box displayed in front of all page content to see a larger version of an image.
Simple lightbox
<a class="example-lightbox-trigger"
href="image-lg.jpg"
title="Zoom"
role="button"
data-toggle-class-on-target
data-toggle-target-parent=".example-lightbox"
data-toggle-escape
data-toggle-modal>
<img src="image.jpg" alt="desc">
</a>
<div class="example-lightbox" role="dialog" aria-hidden="true">
<div class="example-lightbox-backdrop"
data-toggle-trigger-off>
</div>
<button type="button"
class="example-lightbox-close"
data-toggle-trigger-off
aria-label="Close"
title="Close this lightbox">
✖
</button>
<img class="example-lightbox-img" src="image-lg.jpg" alt="desc">
</div>
Explanation
Toggle .is-active
class – as default – on click on this element. Toggle the class on its target .example-lightbox
, belonging to its parent container, at the same time. Press escape key to toggle off, thanks to data-toggle-escape
[?] attribute.
The attribute data-toggle-modal
[?] specify that the target is a modal, and create a focus trap inside of it when active.
The attribute data-toggle-trigger-off
[?] enable the “close” button and the backdrop – the opacified black background – to toggle off lightbox state by clicking on them.
As aria-hidden
attribute is set, its value changes too.
Contribution
- Clone the repo:
git clone https://github.com/twikito/easy-toggle-state.git
- Development:
npm run build
- Fork repository on GitHub
- Report a bug
- Suggest a feature