Skip to content

Instantly share code, notes, and snippets.

@Anaminus
Created March 12, 2024 20:17
Show Gist options
  • Save Anaminus/5ef8086ba5260c480e2b7a895d55ce5a to your computer and use it in GitHub Desktop.
Save Anaminus/5ef8086ba5260c480e2b7a895d55ce5a to your computer and use it in GitHub Desktop.
Multiple menu panels through CSS only.
<!DOCTYPE html>
<!--
Multiple menu panels through CSS only.
Radio inputs control the panel state. The initial state, with no panels,
corresponds to the "none" input, which is checked by default. Labels are mapped
to each input, acting as the buttons that enter each panel. Each panel contains
a label that maps to the "none" input, which returns to the initial state.
-->
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="minimum-scale=1, initial-scale=1, width=device-width">
<title>Panel test</title>
<style>
body {
margin: 0;
padding: 0;
}
body > header {
display: flex;
flex-direction: row;
background-color: #F0F0F0;
}
body > header > h1 {
flex-grow: 1;
flex-shrink: 1;
min-width: 0;
font-size: 1.2em;
overflow: hidden;
padding: 0;
margin: 0;
box-sizing: content-box;
}
body > header > h1::before {
content: "";
margin-left: 0.25em;
}
body > header > * {
display: flex;
align-items: center;
padding: 0.5em;
}
label {
display: inline-flex;
align-items: center;
padding: 0.5em;
background-color: #E0E0E0;
user-select: none;
}
/* Panel behavior */
.panel, body > main > nav {
background-color: #F0F0F0;
position: fixed;
top: 0;
width: 100vw;
height: 100vh;
box-shadow: 0 0 16px #A0A0A0;
overscroll-behavior: none;
left: calc(-100vw - 16px);
/* Transition does not work on display. */
visibility: hidden;
}
body:has(#focus-search:checked) #search-panel {
left: 0;
visibility: visible;
}
body:has(#focus-settings:checked) #settings-panel {
left: 0;
visibility: visible;
}
body:has(#focus-nav:checked) > main > nav {
left: 0;
visibility: visible;
}
@media not (prefers-reduced-motion) {
.panel, body > main > nav {
transition:
left 100ms ease-out,
visibility 100ms ease-out;
}
}
.panel-state {
display: none;
}
</style>
</head>
<body>
<div class="panel-state">
<input type="radio" name="focused-panel" id="focus-none" checked />
<input type="radio" name="focused-panel" id="focus-nav" />
<input type="radio" name="focused-panel" id="focus-search" />
<input type="radio" name="focused-panel" id="focus-settings" />
</div>
<header>
<label for="focus-nav">Nav</label>
<h1>Header</h1>
<label for="focus-search">Search</label>
<label for="focus-settings">Settings</label>
</header>
<main>
<nav>
<label for="focus-none">Close</label>
<p>Navigation</p>
</nav>
<section>
<p>Content</p>
</section>
</main>
<div id="search-panel" class="panel">
<label for="focus-none">Close</label>
<p>Search</p>
</div>
<div id="settings-panel" class="panel">
<label for="focus-none">Close</label>
<p>Settings</p>
</div>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment