Since discovering Alpine.js, I've become obsessed with its simplicity for building UI elements that used to take lots of effort or a larger framework to build. Accordions have always been a pain point for me - probably because I haven't built one since jQuery was the go to method for building interactive frontends.
Times have changed, and with the addition of TailwindCSS to my toolkit I've been able to build fast and functional UI components with ease. This tutorial goes over and provides source code for building an accordion with Alpine.js (and TailwindCSS).
Frontend Design with TailwindCSS
Here is the frontend design that I'll be using as a base. This is something I coded up quickly - look how easy Tailwind makes it!
Accordion that Automatically Closes
The intended behaviour of this accordion will be to open the content of the relevant block when it's clicked. Once another block is clicked all others should close automatically. This is achieved by using
x-data to keep track of the index of the opened block. By setting the opened block index to -1, all accordion blocks are closed. Awesome!
@click to change the index, we can change the index to whatever we want so long as that index is then updated in the
x-show checks for that block. If the indexes don't match, the block won't work. When an accordion block is already opened and it is clicked again, the index is set to -1 to close it. This is done with a ternary operator.
@click="openedIndex == 1 ? openedIndex = -1 : openedIndex = 1"
Although this looks very messy, and it is, it makes it very clear for educational purposes what is happening when a block is clicked. If the block with index 1 is already open, the condition will evaluate to true and the index will be set to -1, effectively closing all blocks. If the openedIndex is not 1, it will set the index to 1 and open the block.
Ideally, this logic would be moved to a function in the code somewhere and would be called with the indexes as parameters.
Accordion that Allows Multiple Blocks to be Open
Below is an example of an accordion that allows multiple blocks to be left open simultaneously. The trick to this example was to add a div container around each block element and its data div for the purpose of keeping track of the block's open state. Although this changes the markdown slightly, it does not affect styling.
As you can see in the examples above, I use transitions that come with Alpine.js to make the transitions between open and closed states less jarring. It still isn't perfect, but it's a great start for someone looking to build some simple accordions with Alpine.js (and maybe TailwindCSS)!