A Webflow-Native Accordion component

Questions are frequently asked, & nearly as often answered. And there's no better way to catalog these exchanges than an FAQ accordion. This Webflow-native component uses a combination of "all" & "parent/sibling/child" interactions to link together a group of hide/show components.

View in Webflow
See it in action
Implementation notes

Update: 3/31/2023 - Updated accordions to be more accessibility friendly.

Building these accordions can be a little tricky, but a few basic concepts make things far easier to understand.

  • Separation of style classes & interaction classes: Complex interactions are far easier to build & maintain if you don't cross the streams. I normally start by building out the structure with my interaction classes, & then nest the styled content inside them.
  • Stacking interaction classes: Since Webflow Interactions bind a class to a relationship (all/parent/sibling/child), it's sometimes necessary to use 2 different classes assigned to the same element to define conflicting behaviors. For instance, when a closed accordion is clicked, we'll use Accordion Body - Universal Trigger set to "all elements with this class" to close all accordions (setting the height to 0px), & then use Accordion Body set to "only siblings with this class" to override that animation, opening our intended accordion. It's essential that any universal trigger animations (which are used to close accordions) be defined earlier in the interaction so that the more specific interactions (which are used to open accordions) can override them. And anywhere we're using stacked classes, we'll want to avoid applying interactions to the combo class. This means we'll sometimes want to apply a secondary class to a temp div in order that we can make sure we're applying animations to the base class.
  • Using trigger divs instead of 2nd click interactions: 2nd click interactions are only useful for simple, 2-step animations that are isolated to a single element. When we intend for multiple accordions to work interdependently, we want to avoid a scenario where 1st clicking on a second accordion closes a previously open according, leaving the previously open accordion closed but stranded in the 2nd click state (meaning it would take 2 clicks to re-open). To avoid that, we'll attach the "close" animation to an Accordion Close class, which is positioned absolutely on top of the accordion but hidden by default & displayed when the accordion is open. This way, regardless of whether the user closes an open accordion by second click or by engaging a new accordion, we can reset the interaction by hiding the Accordion Close class.
  • Keep your animations consistent: These components tend to look best when all of the animations are the same duration & easing. So pick a style & stick to it & your components will function like a well-oiled machine.

With all that in mind, we're ready to start building.

1. The basic structure of the component.

  • Accordion Accordion - Universal Trigger: This wrapper div contains all of our accordion components. We'll target it in our interaction to change the background color. But we'll also append a Position Relative class to define the size of the absolutely positioned Accordion Close div, an Overflow Hidden class so that our Accordion Body content doesn't spill outside the component when closed, a Cursor - Pointer class so that the user knows the component is clickable, & a few styling class for things like text color & border.
  • Accordion Hover: This div has a background color hover style that functions independently of the open/close background color animation set to the Accordion div. Because this style is the same color as the "open" background color, only set to a lower opacity, it's only apparent when the accordion is closed.
  • Accordion Head: This is the wrapper for the Question displayed in the component's initial, "closed" state.
  • Accordion Body Accordion Body - Universal Trigger: This is the wrapper for the Answer displayed on in the "open" state.
  • Accordion Close Accordion Close - Universal Trigger: A transparent, absolutely positioned div that triggers the close animation.

2.Set up basic styling.

On the Accordion div, we'll add Border - M, Text - White, & Border Radius - S. We'll also add some text inside Accordion HeadAccordion Body, along with some padding. Tip: It's important that we apply any padding to a div nested inside the Accordion Body div because any top or bottom padding added directly to that div will prevent us decreasing the height to 0px.

3.Create the basic functions of the "open" animation.

On the Accordion Head div, we'll apply a Click interaction. This will need to be applied to the class, so that the interaction can be used modularly, as will all steps of the animation itself. We'll want to set the initial state of the Accordion Body to height: 0px, & set it to "only siblings with this class." And on click, we'll want to set Accordion Close to "only siblings with this class" & set it to "show." Then we'll want to set the height of Accordion Body to "auto." This will enlarge the div to whatever size is needed to accommodate the content within.

4.Create the basic functions of the "close" animation.

On the Accordion Close - Universal Trigger div, we'll apply a Click interaction. Again, this will need to be applied to the class, as will all steps of the animation itself. We'll set Accordion Close Trigger to "all elements with this class" & set it to "hide." (Because only one accordion drawer can be open at a time, so one is closing is no different than all closing.) Then we will set the Accordion Body - Universal Trigger to "all elements with this class" & set it to a height of 0px. (For the same reason.)

5. Create the "close all" functions of the "open" animation. Since the Universal Trigger classes are appended to the basic structure classes, we'll need to create temp divs to apply these classes as base classes in order to avoid assigning these animations to the combo class. F we'll set cAccordion Close - Universal Trigger & within the "open" animation, set it to "all elements with this class" & set the display to hide. This will need to be ordered before the Accordion Close animation. We'll also set Accordion Body - Universal Trigger to "all elements with this class" & give it a height of 0. Again, this should be ordered before Accordion Body in the animation. These can be grouped together so that they occur simultaneously, but needed to be ordered correctly for the sake of overriding.

6. Add additional functionality. You might want to animate an icon when a drawer opens or closes, or change the background color. These will all just need to follow the basic steps that we applied to Accordion Body & Accordion Body - Universal Trigger. In other words, for every animation that occurs on "open," you'll need to use a Universal Trigger class to reset that animation on click. View this project in Webflow in order to dig into the interactions created for this demo.

7. Duplicate the component. Once the component is done, you'll be able to duplicate as many as you'd like & they should all work codependently of one another. But if you'd like to have multiple sets on the same page, you'll have to recreate the component with unique class names.

8. Hit the tennis courts. You are finally done.