css only menu

by Laurens Maneschijn

HTML

<input style="width:1px; height:1px;" onfocus="this.nextElementSibling.focus();">
<input style="width:1px; height:1px;">
<small>&larr; shift-tab focus catcher</small>

<h1>Hover menu:</h1>

<div class="block menu_hover">
	<m>
		&equiv;
		<m>
			item 1
			<m>
				item 1.1
				<m>
					<a href="#">item 1.1.1</a>
				</m>
				<m>
					<a href="#">item 1.1.2</a>
				</m>
			</m>
			<m>
				item 1.2
				<m>
					item 1.2.1
				</m>
				<m>
					item 1.2.2
				</m>
			</m>
		</m>
		<m>
			item 2
			<m>
				item 2.1
				<m>
					item 2.1.1
				</m>
				<m>
					item 2.1.2
				</m>
			</m>
			<m>
				item 2.2
				<m>
					item 2.2.1
				</m>
				<m>
					item 2.2.2
				</m>
			</m>
		</m>
	</m>
</div>

<h1>Focus menu: click or tab through elements:</h1>

<small>
Almost same as above, but uses :focus instead of :hover, and all elements have &lt tabindex="0"&gt;.<br>
</small>

<div class="block menu_focus">
	<m tabindex="0">
		&equiv;
		<m tabindex="0">
			item 1
			<m tabindex="0">
				item 1.1
				<m DISABLED_tabindex="0">
					<a href="#">item 1.1.1</a>
				</m>
				<m DISABLED_tabindex="0">
					<a href="#">item 1.1.2</a>
				</m>
			</m>
			<m tabindex="0">
				item 1.2
				<m tabindex="0">
					item 1.2.1
				</m>
				<m tabindex="0">
					item 1.2.2
				</m>
			</m>
		</m>
		<m tabindex="0">
			item 2
			<m tabindex="0">
				item 2.1
				<m tabindex="0">
					item 2.1.1
				</m>
				<m tabindex="0">
					item 2.1.2
				</m>
			</m>
			<m tabindex="0">
				item 2.2
				<m tabindex="0">
					item 2.2.1
				</m>
				<m tabindex="0">
					item 2.2.2
				</m>
			</m>
		</m>
	</m>
</div>

<input style="width:1px; height:1px;">
<input style="width:1px; height:1px;" onfocus="this.previousElementSibling.focus();">
<small>&larr; tab focus catcher</small>

SCSS

/* simple hover menu: */
.menu_hover {
	/* just some fancy display: */
	m {
		display: inline-block;
		margin: 4px;
		padding: 4px;
		border: 1px solid #888;
		border-radius: 4px;
		background: #8888;
	}

	/* highlight current hover element: */
	m:hover:not(:has(:hover)) {
		border: 1px dashed #000;
	}

	/* handle show and hide of elements: */
	m > m {
		display: none;
	}

	m:hover > m {
		display: block;
	}
}


/* focus variant, click or tab-able: */
.menu_focus {
	/* just some fancy display: */
	m {
		display: inline-block;
		margin: 4px;
		padding: 4px;
		border: 1px solid #888;
		border-radius: 4px;
		background: #8888;
	}

	/* highlight current focus element: */
	m:focus {
		border: 1px dashed #000;
	}

	/* handle show and hide of elements: */
	m > m {
		display: none;
	}

	/*
	:has() only supports basic selectors inside.
	:has(:focus) might not be supported, but
	:focus-within does the same and is supported in most browsers.
	*/
	m:has(:focus) > m,
	m:focus-within > m,
	m:focus > m {
		display: block;
	}
}



/* menu unrelated css: */

h1,h2,h3,h4,h5,h6 {
	font-size: 100%;
	margin: 10px 0 0 0;
}

.block {
	margin: 4px;
	padding: 4px;
	border: 1px solid #888;
	border-radius: 4px;
}