Creating an Accordion with sQuery + Polymorph (feat. JavaScript styles)

Edmund Reed
3 min readJun 19, 2019

sQuery and Polymorph are both JavaScript tools I have developed to help work with DOMs that follow the BEM naming convention (and variants thereof). sQuery is used for interacting with DOM elements whilst Polymorph is used for styling DOM elements. This means we can create a fully working and styled accordion, hopefully with much ease.

The finished product looks like this:

View demo on CodePen

If you’re familiar with JavaScript and BEM, the above code should hopefully make sense despite the tools being unfamiliar and the code lacking any comments. This is because the API’s have been attempted to be developed with Developer Experience in mind, a big part of which is intuitive code. It’s also production-ready code that you can run directly in the browser, which emphasise its simplicity. In a world of fancy JavaScript frameworks I think there’s still something to be said about production code that is both DRY and readable by humans, despite the superfluousness of the activity.

Breaking down the above code, we have the following areas of concern:

Accordion Markup

Nothing new has been introduced here, it’s just plain HTML that follows the BEM naming convention.

Accordion Styles

Styles exist as a plain JavaScript object that will be fed to the polymorph() function. Polymorph does all the magic in terms of figuring out which styles to apply to which DOM elements. As we’re working with BEM, we want our API to be saying “I want to style this Element of this Block”, and not “I want to style this child DOM node of this parent DOM node”. Polymorph, with the help of sQuery, essentially converts the former, more human way of speaking, to the latter. As a human It’s much nicer working with BEM Element names than selector queries.

For more information checkout the Using Polymorph to Style a BEM Accordion article.

Accordion Interactions

This is all handled with essentially just 5 lines of code, so shouldn’t be too overwhelming, and to reiterate the APIs have been written to be understandable without much explanation required, but we’re really just querying DOM elements and binding event handlers to them in order to toggle classes, which is far from a new concept. Calling the sQuery modifier API triggers a repaint method that has been attached to the DOM node by Polymorph, which will repaint the element (sQuery and Polymorph were built in tandem to work with each other, so sQuery can detect the repaint method added by Polymorph; if you weren’t using sQuery, the repaint method would need to be called manually after updating the DOM).

For more information checkout the Using sQuery to Interact with a BEM Accordion article.

…what about frameworks like React?

When using React, it’s strongly recommended to not manipulate the DOM directly as this causes React’s virtual DOM to become out-of-sync. Thus, it’s recommended to not use sQuery to add/remove modifiers to DOM elements (in other words, it’s recommended to not use sQuery to write to the DOM). However, sQuery can still be used to read the DOM, and Polymorph can be used with no problem in a React component’s componentDidMount and componentDidUpdate lifecycle methods. Lucid is a library of higher-order React components built to use with Polymorph, so check it out if you’re interested in using Polymorph with React.

Sign me up!

To see how sQuery and Polymorph can be used separately (even if only to learn more about them), checkout these other articles from the same series:

To get started with the example from this article you just need to update the demo code with the paths to the sQuery and Polymorph bundles. For full installation instructions please see the respective documentations.

--

--

Edmund Reed

Design Systems Architect 🎨 UI•UX designer & developer 💻 I take front-end thought experiments too far 🧪 @valtech 💙