How to create easy, accessible accordion panels in Vue 3

Derrick Otte
4 min readFeb 14, 2023
Screenshot of the accordion that will be created at the end of this project.

When you’ve got a large screen with a ton of content, accordions can come in really handy. Whether it be a large checkout form with multiple steps or a government website with loads of directories and tools, accordions are incredibly helpful in chunking out large sets of information.

While it’s tempting to reach out for a external library, creating your own stylish and accessible accordion is pretty simple. Let me show you how I went about creating one in Vue 3.

Before continuing, I’m assuming you have some experience in JavaScript. Additionally, I’ll be using Vue’s Composition API rather than the regular options API.

Creating the Project

Screenshot of the terminal output given to you after running ‘npm create vue@3’
Image of terminal output taken from the create-vue Github page.

First, make sure you have the latest version of NodeJS installed. After that, create a new Vue 3 project with npm create vue@3. This will create a new Vue 3 project with Vite as your build tool.

If you’d like to learn more about the create-vue command, you can check their Github page.

Since this is such a small project, you can select No for every optional package you’re asked to add — such as TypeScript, the Vue Router, Pinia, and more.

Creating the Accordion Panel component

Now that the project is created, we need to create a new component: AccordionPanel. Inside of your /components directory, add a file named AccordionPanel.vue. Inside of it, we’ll create a basic component with a few properties, a button, and a content div:

To summarize the main functionality of this component: it has props for a title and ariaTitle (for accessibility), a reactive showPanel ref that will control hiding and showing the content of the accordion, and a <slot> for injecting components inside of it.

For the most part, you’ve got a working accordion component! It just needs styles, accessibility, and some content added to it.

Now that we’ve got the accordion panel component, we can make a simple component to serve as our first accordion panel. Imagine you’re in the context of a checkout form for an online order. When you go to checkout, sometimes there’s a shipping warning saying orders are delayed. Let’s create this warning as an accordion panel.

Open up /components and create a new component inside, CustomerWarning.vue:

This is a really simple component, but we’ll add styles to it in the next step.

Adding Styling

Right now, if you were to put these components on the page, it wouldn’t look like an accordion. Let’s make it! For smaller projects like this, I prefer to use a framework like TailwindCSS for styling. For me, it has all of the utilities I would need for a bigger project, and I can get some styles working with a single line of HTML.

Additionally, if you want to add nice looking icons to really make it look like an accordion, Google Material icons is a great choice for a one-line, ready to go solution.

To add both of these, open up index.html, and add the TailwindCSS development build, and Google Material Icons in your <head>:

<script src="https://cdn.tailwindcss.com"></script>
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">

Now that we have styles, we can make our CustomerWarning component look like an actual warning. You can use any styles you want, but to make it look like my screenshot above, add these classes on line 4 in the template:

<div class="w-full h-full bg-orange-300 rounded-lg p-4">

Putting it on the Page

Finally, we can put the accordion on the page. If you want to make your accordion look exactly like mine, first delete any boilerplate components and styles that come with the create-vue command. This includes HelloWorld.vue, TheWelcome.vue, and any .css files inside of src/assets.

Open up App.vue, and inside of the <main> tag, add your AccordionPanel component with a title and ariaTitle:

Back in AccordionPanel.vue, we can add a couple more touches to the template to make it really look like an accordion: styles, a right/down chevron icon depending on whether or not the panel is open, and more accessibility attributes:

Now if you head back to your terminal window, and spin up the project by running npm install thennpm run dev, you should see a fully functional and accessible accordion panel:

Screenshot of the tracking incidents accordion panel created through this project.

And you’re done! If you wanted to check out a larger version of the project that produces the webpage at the top of this article, you can check out the Github repo that I created for this project.

Additionally, I wanted to make sure I explicility added and showed accessibility attributes to make this component much more accessible. I’m not an expert when it comes to accessibility, so feel free to reach out for corrections if you are.

--

--