Collapsable components (sometimes called slide-reveals, or show-hides) are used for showing and/or hiding panel content.
Collapses are often found in navbars, tall sidebars, FAQs, and dismissable “top ribbon” notifications.
Codebase collapse components make use of the AlpineJS Collapse Plugin.
Basic collapse example
Collapsable panel content with an example link. Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
<div
x-data="{ open: false }"
x-id="['collapse']"
class="b-thin rounded"
>
<button
type="button"
class="w-100% flex-space-between b-0 unrounded hover:bg-transparent"
@click="open = !open;"
:aria-controls="$id('collapse')"
:aria-expanded="open"
@keydown.escape.prevent.stop="open = false"
>
<span class="t-semibold">Collapse toggle</span>
<!-- Icon caret down -->
<svg x-cloak x-show="!open">...</svg>
<!-- Icon caret up -->
<svg x-cloak x-show="open">...</svg>
</button>
<div
x-cloak
x-show="open"
x-collapse
:id="$id('collapse')"
@keydown.escape.prevent.stop="open = false"
>
<div class="p-2">
<em>Collapsable panel content with an <a href="#/">example link</a>.</em> Lorem ipsum dolor sit amet...
</div>
</div>
</div>
Notes on collapse
- Codebase collapse components make use of the AlpineJS Collapse Plugin.
- There are two basic elements to a Codebase collapse component:
- The collapse toggle button – control to open/close the collapse panel
- The collapse panel itself
x-cloak
is used to hide the collapsed panel before AlpineJS has hidden it programatically. Codebase already contains the style[x-cloak] {display: none;}
. If you’re starting with the panel in the open state, then don’t putx-cloak
on it. For example, seen the Dismissable message box below.- The collapse toggle
<button>
is not being used as part of a form. Therefore it must have the attributetype="button"
- The collapse panel can be toggled open/close by the collapse toggle button (mouse click, touch screen tap, etc.) and by tabbing onto the button and hitting the enter key or the space bar.
- The collapse can be closed by hitting the escape key whether the focus is on the dropdown button or on the dropdown panel. The focus will then be returned to the dropdown button.
- The
x-collapse
directive must be paired with thex-show
directive on the collapse panel. During the collapsing animation,x-collapse
temporarily removesx-show
s inline styledisplay: none
and then puts it back on when the animation is completed. So, the contents of fully collapsed panels are removed from the accessibility tree (tabindex). This means that tabbing can’t go inside collapsed panels and become lost to view. - It is easy to make a switchable open/close indicator on the collapse toggle button, based on the true/false state of the the collapse component. The basic collapse example above has two embedded SVG caret icons (from Phosphor Icons), one pointint down and one pointing up, that are hidden or revealed depending on the state of this component’s
open
variable.<!-- Icon caret down -->
<svg x-cloak x-show="!open">...</svg>
<!-- Icon caret up -->
<svg x-cloak x-show="open">...</svg> - ARIA attributes have been assigned to the collapse toggle button, to make it accessible for screen readers.
- The ID of the collapse panel (used by
aria-controls=""
on its respective toggle button) has been assigned using the Alpine x-id directive, which automatically adds an incremented number to your specified ID (prefix). That way, you can include several collapse components to a webpage without having to think up an ID for each one.
Adding an indicator rotation animation
Instead of switching between two icons (caret down and caret up), you can have only one icon and rotate it using Codebase animation utility classes:
Collapsable panel content with an example link. Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
<!-- Icon caret down -->
<svg
class="transition-all-300ms"
:class="open && 'rotate-180'"
...
/>...</svg>
Dismissable message box
For a dismissable message box:
- Initiate the Alpine component in the
open = true
state:<div
x-data="{ open: true }"
...
>
...
</div> - Place the button inside the panel, and make it only change the
open
state to false (i.e. closed) instead of being a toggle. - Label the button with “Close”, whether visibly and/or in the
aria-label
, and give it an “×” icon (dismiss; exit). - Do not put
x-cloak
on the collapse panel, because you’re initiating it in the open (displayed) state.
Success
This message is just to tell you that you’ve had some success.
(To make this collapse panel reappear, refresh your browser.)
<div
x-data="{ open: true }"
x-id="['collapse']"
>
<div
x-show="open"
x-collapse
:id="$id('collapse')"
@keydown.escape.prevent.stop="open = false"
>
<div class="bg-success">
<button
class="btn-success btn-icon unrounded float-right t-lg"
:aria-expanded="open"
aria-controls="$id('collapse')"
aria-label="Close panel"
@click="open = false"
>×</button>
<div class="p-2 t-white">
<p class="mb-1 t-lg">Success</p>
<p class="mb-0">This message is just to tell you that you’ve had some success.</p>
</div>
</div>
</div>
</div>