Skip to main content Accessibility Feedback

<show-hide>

Create a progressively enhanced disclosure component.

Source Code

Usage

Wrap a <button> and some content to selectively show or hide in the <show-hide> component.

Add the [trigger] and [hidden] attributes to the toggle <button>. Add the [content] attribute to the content to show or hide.

<show-hide>
    <button trigger hidden>Show Content</button>

    <div content>
        <p>Now you see me, now you don't!</p>
    </div>
</show-hide>

When the Web Component loads, it will display the button, hide the content, add required ARIA attributes, and add event listeners to selectively show or hide the [content] when the [trigger] is clicked.

The Web Component

customElements.define('show-hide', class extends HTMLElement {

    /**
     * Instantiate the Web Component
     */
    constructor () {

        // Get parent class properties
        super();

        // Get the elements
        this.trigger = this.querySelector('[trigger]');
        this.content = this.querySelector('[content]');
        if (!this.trigger || !this.content) return;

        // Setup default UI
        this.trigger.removeAttribute('hidden');
        this.trigger.setAttribute('aria-expanded', false);
        this.content.setAttribute('hidden', '');

        // Create the event handler
        this.handler = this.createHandler();

    }

    /**
     * Create the event handler
     */
    createHandler () {
        return (event) => {

            // Don't let the button trigger other actions
            event.preventDefault();

            // If the content is expanded, hide it
            // Otherwise, show it
            if (this.trigger.getAttribute('aria-expanded') === 'true') {
                this.trigger.setAttribute('aria-expanded', false);
                this.content.setAttribute('hidden', '');
            } else {
                this.trigger.setAttribute('aria-expanded', true);
                this.content.removeAttribute('hidden');
            }

        };
    }

    /**
     * Start listening to clicks
     */
    connectedCallback () {
        if (!this.trigger || !this.content) return;
        this.trigger.addEventListener('click', this.handler);
    }

    /**
     * Stop listening to clicks
     */
    disconnectedCallback () {
        this.trigger.removeEventListener('click', this.handler);
    }

});

Find this useful? You can support my work by purchasing an annual membership.