css only menu
by Laurens Maneschijn
HTML
<input style="width:1px; height:1px;" onfocus="this.nextElementSibling.focus();">
<input style="width:1px; height:1px;">
<small>← shift-tab focus catcher</small>
<h1>Hover menu:</h1>
<div class="block menu_hover">
<m>
≡
<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 < tabindex="0">.<br>
</small>
<div class="block menu_focus">
<m tabindex="0">
≡
<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>← 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;
}