<div class="menu" tabindex="0">
  <a href="https://google.com" target="_blank" tabindex="-1">Link to Google</a>
  <a href="#" tabindex="-1">Link</a>
  <a href="#" tabindex="-1">Link</a>
  <a href="#" tabindex="-1">Link</a>
  <a href="#" tabindex="-1">Link</a>
</div>
<div class="menu" tabindex="0">	
  <a href="#" tabindex="-1">Link</a>
  <a href="#" tabindex="-1">Link</a>
  <a href="#" tabindex="-1">Link</a>
  <a href="#" tabindex="-1">Link</a>
  <a href="#" tabindex="-1">Link</a>
</div>
<p><kbd>Tab</kbd> / <kbd>Shift + Tab</kbd> to switch between the menus, <kbd>🠕</kbd> and <kbd>🠗</kbd> to go up and down inside the menu. <kbd>Space</kbd> to click a link.</p>
* {
	padding: 0;
	margin: 0;
	color: white;
	box-sizing: border-box;
	font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";
}

body {
	display: grid;
	grid-auto-flow: column;
	max-width: 40rem;
	margin-inline: auto;
	place-items: center;
	background-color: #111;
	height: 100vh;
}

.menu {
	background-color: ;
	display: flex;
	flex-direction: column;
	border: 1px solid #555;
	border-radius: 0.5rem;
	overflow: hidden;
}

.menu > a {
	padding-inline: 4rem;
	padding-block: 1rem;
}

.menu > * + * {
	border-top: 1px solid #555;
}

.menu:focus-within {
	outline: 0.2rem solid #666;
	outline-offset: 0.25rem;
}

a {
	text-decoration: none;
	text-align: center;
}

a:hover, a:focus {
	background-color: #444850;
	outline: none;
	text-decoration: #aaa underline 0.2rem;
}

kbd {
	padding: 0.5rem;
	margin-inline: 0.2rem;
	border-radius: 0.3rem;
	font-family: monospace;
	border: 0.5px solid #666;
}

p {
	position: absolute;
	left: 2rem;
	top: 2rem;
	line-height: 2.5rem;
}
const menuList = document.querySelectorAll(".menu");

menuList.forEach((menu) => {
	const children = Array.from(menu.children);
	let current = 0;
	const handleKeyDown = (e) => {
		if (!(["ArrowUp", "ArrowDown", "Space"].includes(e.code))) return;
		if(e.code === "Space") {
			children[current].click();
			return;
		}
		const selected = children[current];
		selected.setAttribute("tabindex", -1);
		let next;
		if (e.code === "ArrowDown") {
			next = current + 1;
			if (current == children.length - 1) {
				next = 0;
			}
		} else if ((e.code = "ArrowUp")) {
			next = current - 1;
			if (current == 0) {
				next = children.length - 1;
			}
		}
		children[next].setAttribute("tabindex", 0);
		children[next].focus();
		current = next;
	};

	menu.addEventListener("focus", (e) => {
		if (children.length > 0) {
			menu.setAttribute("tabindex", -1);
			children[current].setAttribute("tabindex", 0);
			children[current].focus();
		}

		menu.addEventListener("keydown", handleKeyDown);
	});

	menu.addEventListener("blur", (e) => {
		menu.removeEventListener("keydown", handleKeyDown);
	});
});

External CSS

This Pen doesn't use any external CSS resources.

External JavaScript

This Pen doesn't use any external JavaScript resources.