ua

Dropdown menu with details

Created: | Updated:


Demo & Repo


Making dropdown menu with details is easy.

First, create HTML skeleton.

<details class="dropdown">
	<summary>
		<span>dropdown</span>

		<span class="up"> ⬆️ </span>
		<span class="down"> ⬇️ </span>
	</summary>

	<div class="menu">
		<div class="menu-list">
			<a href="#!" class="menu-list-item">item 0</a>
			<a href="#!" class="menu-list-item">item 1</a>
			<a href="#!" class="menu-list-item">item 2</a>
		</div>
	</div>
</details>

Then, make it look like a button.

details.dropdown {
	display: inline;
}

details.dropdown > summary {
	position: relative;
	overflow: hidden;
	display: flex;
	gap: 1rem;
	padding: 1rem 2rem;
	border-radius: 1rem;
	text-transform: capitalize;
	cursor: pointer;
	background-color: white;
}

details.dropdown > summary:hover {
	background-color: lightblue;
}

Show arrows depending on the state (open or close).

details.dropdown > summary span.up {
	display: none;
}

details.dropdown[open] > summary span.up {
	display: inline;
}

details.dropdown[open] > summary span.down {
	display: none;
}

Add a backdrop on the open state.

details.dropdown[open] > summary::before {
	z-index: 100;
	position: fixed;
	inset: 0;
	content: ' ';
	background-color: hsla(0, 0%, 50%, 0.66);
	cursor: default;
}

Place the menu just on bottom.

details.dropdown[open] .menu {
	z-index: 1;
	position: absolute;
	display: block;
}

details.dropdown.right[open] .menu {
	right: 0;
}

Customize the menu list.

details.dropdown .menu-list {
	max-height: 20rem;
	overflow-y: auto;
	margin-top: 0.5rem;
	padding: 0.33rem 0;
	border-radius: 1rem;
	box-shadow: 0 0 0.9rem -0.1rem hsla(0, 0%, 0%, 0.75);
	background-color: white;
}

details.dropdown .menu-list-item {
	display: flex;
	align-items: center;
	gap: 1rem;
	width: 100%;
	padding: 1rem 1.2rem;
	color: var(--text);
	background-color: transparent;
	text-decoration: none;
	line-height: 1;
}

details.dropdown .menu-list-item:is(:hover, :focus) {
	color: blue;
	background-color: hsla(0, 0%, 50%, 0.1);
}

A little bit of JS to close the dropdown on click event inside the menu.

function closeDropdown(id) {
	console.log('closeDropdown', id);

	if (id) {
		document.getElementById(id)?.removeAttribute('open');
	} else {
		document.querySelectorAll('details.dropdown')?.forEach((el) => {
			el.removeAttribute('open');
		});
	}
}

Attach the event listener.

<div class="menu" onclick="closeDropdown()">
	<!--  -->
</div>