menu flexible layout
by liveasnotes
HTML
<input type="checkbox" id="menu_tgl">
<label for="menu_tgl" data-ui>menu</label>
<header>
<nav>
<ul id="menu_list">
<li><a href="#">AAA</a></li>
<li><a href="#">BBB</a></li>
<li><a href="#">CCC</a></li>
</ul>
</nav>
</header>
CSS
*,*::before,*::after {
padding: 0;
margin: 0;
box-sizing: border-box;
}
[data-ui] {
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
}
#menu_tgl,
[for="menu_tgl"] {/* toggle */
position: fixed;
top: 0;
right: 0;
z-index: 0; /* @SP, for make UNtouchable */
display: none;
width: 50px;
height: 50px;
background: palegreen;
opacity: 0.5;
}
#menu_list {
display: flex;
list-style: none;
text-align: center;
background: palegreen;
transition: 0s;
}
#menu_list > li {
border: 1px solid gray;
padding: 1em;
margin: 1em;
}
/* at transition PC -> SP, to prevent show animation of menu, wrapper of menu need to change own position with no transition time */
nav {
position: fixed;
top: 0;
left: 0;
width: 100%;
}
nav a {
display: block;
}
/* @SP */
@media screen and (max-width: 768px) {
#menu_tgl,
[for="menu_tgl"] {
display: block;
z-index: 100; /* @SP, for make touchable */
}
nav {
top: auto;
bottom: 100%;
}
#menu_list {
flex-direction: column;
opacity: 0;
transition: 0.5s;
}
#menu_tgl:checked ~ header #menu_list {
transform: translateY(100%);
opacity: 1;
}
}
JavaScript
// cf. .matchMedia()でJSでもメディアクエリを使って条件分岐する | SPYWEB
// https://spyweb.media/2018/01/10/css-media-queries-in-js-matchmedia/
// cssはPCファーストで書いてたけど,
// jsはSPファーストで書いてるので,「MAX-width: 768px」ではなく,「MIN-width: 768.0001px」
const mediaQuery = matchMedia('(min-width: 768.0001px)');
function handle(mq) {
if (mq.matches) {
document.getElementById("menu_tgl").checked = false;
}
}
// ページが読み込まれた時に実行
handle(mediaQuery);
// ウィンドウサイズが変更されても実行されるように
mediaQuery.addListener(handle);