Skip to main content

How to create an accordion in HTML

Most of the time the functionality of accordions on the web is built with JavaScript. That could work, but did you know there is a better way? Meet the native HTML <details> element.

See the Pen Details element by Rogier (@rvwebdev) on CodePen.

The <details> element, also known as the details disclosure element, has built-in functionality to toggle between an open and closed state. Opening or closing the element toggles an open attribute on the <details> element. The pros of this are that this element works as an accordion out of the box, without the use of CSS or JavaScript.

Optional enhancements

So the <details> element already works as an accordion element. But we can enhance it with some CSS and JavaScript to make it even better while still being accessible.

CSS enhancement

First we will be adding a pointer cursor to the <summary> element to make it more clear that it can be clicked.

summary {
	cursor: pointer;
}

To remove the default toggle icon, we can add the following CSS.

summary {
	list-style-type: none;
}

summary::-webkit-details-marker {
	display: none;
}

To add our custom toggle icon, we can use the ::before pseudo element. For now we are using a plus and minus character to indicicate the open or closed state.

details summary::before {
	content: '+';
	display: inline-block;
	width: 1rem;
	height: 1rem;
}

/* when details is opened  */
details[open] summary::before {
	content: '-';
}

JavaScript enhancement

To only have one accordion open at all times, we can add some JavaScript. We will need a function that will close all other details elements when the clicked <details> element is opened.

function toggleHandler (event) {
	// Only run if accordion is open
	if (!event.target.hasAttribute('open')) return;

	// Get all open accordions inside parent
	let opened = document.querySelectorAll('details[open]');

	// Close open ones that aren't current accordion
	for (let accordion of opened) {
		if (accordion === event.target) continue;
		accordion.removeAttribute('open');
	}
}

After this, we will listen for a toggle event on the document and call the toggleHandler function.

// The toggle event doesn't bubble, so we need to set the optional third argument, useCapture, to true.
document.addEventListener('toggle', toggleHandler, true);

Result

And there we go! We have an accordion element enchanced with CSS and JavaScript!

See the Pen Accordion by Rogier (@rvwebdev) on CodePen.

Scroll to top