<button id="toggle" class="toggle" type="button" aria-label="MENU" aria-controls="nav" aria-expanded="false">
<span></span>
</button>
<nav id="nav" class="nav" aria-hidden="true">
<ul class="menu">
<li><a href="#a">MENU 1</a></li>
<li><a href="#b">MENU 2</a></li>
<li><a href="#c">MENU 3</a></li>
<li><a href="#d">MENU 4</a></li>
</ul>
</nav>
<main class="main">
<section id="a" class="section">
<h2>Heading 1</h2>
<p>Lorem ipsum dolor sit amet consectetur, adipisicing, elit. Veritatis facilis ab ipsam deleniti, assumenda quaerat in obcaecati accusamus doloribus molestiae? Accusantium optio ea ducimus ipsa animi eius rerum veritatis ad aliquid consequatur hic minus cumque atque incidunt, libero, sed maxime eos quia repellat ipsam et corporis unde, ratione! Adipisci aliquid placeat debitis porro fugit ducimus optio, consequuntur unde quae voluptatibus dolor, provident voluptatem facere culpa vel iste velit soluta dolore alias tempore, voluptatum natus sint! Sunt culpa, omnis, numquam distinctio ad quae id eligendi sit quisquam facilis, autem, iusto cum iure animi hic non laboriosam libero dicta magni! Facilis, consequatur.</p>
</section>
<section id="b" class="section">
<h2>Heading 2</h2>
<p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Animi, sit accusantium repellat amet ex non autem, asperiores magni deserunt facilis commodi nemo iusto consequatur omnis nostrum ipsam rerum cum inventore. Molestiae rem reiciendis maiores itaque aliquid quas aperiam consequuntur asperiores nostrum sit accusantium, placeat, eum fugit, ipsam eaque officiis esse est iure! Consequuntur aspernatur placeat odio aliquid similique blanditiis laborum commodi nulla, fugiat neque delectus voluptatibus consectetur saepe. Amet quis quos, perferendis consequuntur. Laudantium, reprehenderit quibusdam aut ullam! Modi, praesentium. Quae eius dolore unde maiores dignissimos, ratione facere voluptates numquam a architecto dolorem, eligendi illum nostrum iure ut praesentium minus deleniti! Ipsa aut quos itaque corporis eaque rem, doloremque nostrum obcaecati non. Officiis, laudantium praesentium? Facere ratione nesciunt quo officiis maiores et, ab rerum ipsa atque alias cumque excepturi, explicabo nostrum neque, delectus nihil esse provident doloremque ipsum iusto eius soluta quibusdam quaerat dicta nobis. Maiores modi dicta repellat laboriosam perspiciatis, corporis, aliquid quisquam deleniti. Provident accusamus quam cum illo debitis corrupti voluptate totam dolore quas. Impedit repellat ex iure porro rerum veniam, omnis distinctio accusamus rem? Voluptatibus ex dolorum dicta reiciendis possimus magni iure quisquam, minus aliquid, accusamus! Eligendi fugit accusamus soluta, delectus voluptatum maiores modi at. Aut, quia.</p>
</section>
<section id="c" class="section">
<h2>Heading 3</h2>
<p>Lorem ipsum dolor sit amet consectetur, adipisicing, elit. Veritatis facilis ab ipsam deleniti, assumenda quaerat in obcaecati accusamus doloribus molestiae? Accusantium optio ea ducimus ipsa animi eius rerum veritatis ad aliquid consequatur hic minus cumque atque incidunt, libero, sed maxime eos quia repellat ipsam et corporis unde, ratione! Adipisci aliquid placeat debitis porro fugit ducimus optio, consequuntur unde quae voluptatibus dolor, provident voluptatem facere culpa vel iste velit soluta dolore alias tempore, voluptatum natus sint! Sunt culpa, omnis, numquam distinctio ad quae id eligendi sit quisquam facilis, autem, iusto cum iure animi hic non laboriosam libero dicta magni! Facilis, consequatur.</p>
</section>
<section id="d" class="section">
<h2>Heading 4</h2>
<p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Animi, sit accusantium repellat amet ex non autem, asperiores magni deserunt facilis commodi nemo iusto consequatur omnis nostrum ipsam rerum cum inventore. Molestiae rem reiciendis maiores itaque aliquid quas aperiam consequuntur asperiores nostrum sit accusantium, placeat, eum fugit, ipsam eaque officiis esse est iure! Consequuntur aspernatur placeat odio aliquid similique blanditiis laborum commodi nulla, fugiat neque delectus voluptatibus consectetur saepe. Amet quis quos, perferendis consequuntur. Laudantium, reprehenderit quibusdam aut ullam! Modi, praesentium. Quae eius dolore unde maiores dignissimos, ratione facere voluptates numquam a architecto dolorem, eligendi illum nostrum iure ut praesentium minus deleniti! Ipsa aut quos itaque corporis eaque rem, doloremque nostrum obcaecati non. Officiis, laudantium praesentium? Facere ratione nesciunt quo officiis maiores et, ab rerum ipsa atque alias cumque excepturi, explicabo nostrum neque, delectus nihil esse provident doloremque ipsum iusto eius soluta quibusdam quaerat dicta nobis. Maiores modi dicta repellat laboriosam perspiciatis, corporis, aliquid quisquam deleniti. Provident accusamus quam cum illo debitis corrupti voluptate totam dolore quas. Impedit repellat ex iure porro rerum veniam, omnis distinctio accusamus rem? Voluptatibus ex dolorum dicta reiciendis possimus magni iure quisquam, minus aliquid, accusamus! Eligendi fugit accusamus soluta, delectus voluptatum maiores modi at. Aut, quia.</p>
</section>
</main>
// ハンバーガーボタン
.toggle {
& {
appearance: none;
display: block;
position: fixed;
top: 25px;
right: 25px;
z-index: 101;
margin: 0;
padding: 0;
width: 60px;
height: 60px;
border: none;
border-radius: 50%;
background-color: black;
transition: background-color 0.2s ease;
cursor: pointer;
}
> span,
&:before,
&:after {
display: block;
position: absolute;
top: 50%;
left: 50%;
width: 30px;
height: 4px;
margin: -2px 0 0 -15px;
border-radius: 2px;
}
> span {
background-color: maroon;
transition: opacity 0.3s ease;
will-change: opacity;
}
&::before,
&::after {
content: "";
background-color: peru;
transition: background-color 0.3s ease;
}
&::before {
transform: translateY(-10px);
}
&::after {
transform: translateY(10px);
}
&[aria-expanded="true"] {
> span {
opacity: 0;
}
&::before,
&::after {
background-color: white;
}
&::before {
animation: 0.3s ease closeBar1 forwards;
}
&::after {
animation: 0.3s ease closeBar2 forwards;
}
}
&.-close {
&::before {
animation: 0.3s ease closeBar1Rev forwards;
}
&::after {
animation: 0.3s ease closeBar2Rev forwards;
}
}
}
// ナビゲーション
.nav {
& {
display: flex;
justify-content: center;
align-content: center;
align-items: center;
position: fixed;
top: 0;
left: 0;
z-index: 100;
width: 100%;
height: 100%;
overflow: hidden;
background: #46e678;
color: black;
transition: opacity 0.3s ease, visibility 0.3s ease;
}
&[aria-hidden="true"] {
visibility: hidden;
opacity: 0;
pointer-events: none;
}
&[aria-hidden="false"] {
visibility: visible;
opacity: 1;
pointer-events: auto;
}
}
.menu {
li {
font-weight: bold;
font-size: 1.25rem;
line-height: calc(1em + 0.5rem);
a {
color: black;
}
+ li {
margin-top: rem;
}
}
}
// 基本構造
body {
background-color: #333;
color: #fff;
font-family: "Teko", sans-serif;
}
.main {
}
.section {
padding: 2rem 1rem;
&:nth-child(odd) {
background-color: #333;
}
&:nth-child(even) {
background-color: #666;
}
}
h2 {
margin: 0 0 1rem;
font-weight: bold;
font-size: 1.625rem;
line-height: calc(1em + 0.5rem);
}
p {
font-size: 1rem;
line-height: 2;
}
// ×ボタンアニメーション
@keyframes closeBar1 {
0% {
transform: translateY(-10px);
}
50% {
transform: translateY(0) rotate(0);
}
100% {
transform: translateY(0) rotate(45deg);
}
}
@keyframes closeBar2 {
0% {
transform: translateY(10px);
}
50% {
transform: translateY(0) rotate(0);
}
100% {
transform: translateY(0) rotate(-45deg);
}
}
@keyframes closeBar1Rev {
0% {
transform: translateY(0) rotate(45deg);
}
50% {
transform: translateY(0) rotate(0);
}
100% {
transform: translateY(-10px);
}
}
@keyframes closeBar2Rev {
0% {
transform: translateY(0) rotate(-45deg);
}
50% {
transform: translateY(0) rotate(0);
}
100% {
transform: translateY(10px);
}
}
View Compiled
const NAV = document.getElementById("nav");
const TOGGLE = document.getElementById("toggle");
const BODY = document.body;
let y = 0;
// 閉じる
function menuClose() {
TOGGLE.setAttribute("aria-expanded", "false");
TOGGLE.setAttribute("aria-label", "MENU");
NAV.setAttribute("aria-hidden", "true");
BODY.removeAttribute("style");
window.scrollTo(0, y);
// アニメーション用class付加
TOGGLE.classList.add("-close");
TOGGLE.addEventListener(
"animationend",
() => {
TOGGLE.classList.remove("-close");
},
{ once: true }
);
}
// 開く
function menuOpen() {
y = window.scrollY;
TOGGLE.setAttribute("aria-expanded", "true");
TOGGLE.setAttribute("aria-label", "CLOSE");
NAV.setAttribute("aria-hidden", "false");
BODY.style.position = "fixed";
BODY.style.top = -y + "px";
}
TOGGLE.addEventListener("click", () => {
if (TOGGLE.getAttribute("aria-expanded") === "true") {
menuClose();
} else {
menuOpen();
}
});
// 閉じるevent(全体)
const CLICK_EVENT = "ontouchstart" in window ? "touchstart" : "click";
window.addEventListener(CLICK_EVENT, (e) => {
if (e.target === NAV) {
menuClose();
}
});
// 閉じるevent(アンカーリンク)
document.querySelectorAll('.menu a[href^="#"]').forEach((e, i) => {
e.addEventListener("click", menuClose);
});
This Pen doesn't use any external CSS resources.
This Pen doesn't use any external JavaScript resources.