<div id="root"></div>
* {
box-sizing: border-box;
}
body {
background: #ffddee;
margin: 0;
height: 100vh;
}
.menu {
display: inline-flex;
flex-direction: column;
height: 4rem;
}
.menu ul {
margin: 0;
padding: 0 1rem;
list-style: none;
display: flex;
flex-direction: column;
font-family: sans-serif;
font-size: 2rem;
text-transform: uppercase;
font-weight: bold;
overflow: hidden;
gap: 1rem;
color: #444;
}
.burger {
border: 0;
background: transparent;
display: flex;
flex-direction: column;
gap: 0.5rem;
padding: 1rem;
cursor: pointer;
}
.burger span {
display: block;
width: 2rem;
height: 0.3rem;
background-color: #444;
}
import React, { useState } from "https://esm.sh/react";
import ReactDOM from "https://esm.sh/react-dom";
import { motion } from "https://esm.sh/framer-motion";
function App() {
const [isActive, setIsActive] = useState(false);
return (
<motion.div
className="menu"
initial="closed"
animate={isActive ? "open" : "closed"}
variants={{
open: { backgroundColor: "#fff", height: "100vh" }
}}
>
<motion.button className="burger" onClick={() => setIsActive(!isActive)}>
<motion.span variants={{ open: { rotate: 45, y: "0.8rem" } }} />
<motion.span variants={{ open: { opacity: 0 } }} />
<motion.span variants={{ open: { rotate: -45, y: "-0.8rem" } }} />
</motion.button>
<motion.ul
variants={{
open: { transition: { staggerChildren: 0.2, delayChildren: 0.2 } }
}}
>
{["Home", "About", "Contact"].map((page) => (
<motion.li
variants={{ closed: { opacity: 0 }, open: { opacity: 1 } }}
>
{page}
</motion.li>
))}
</motion.ul>
</motion.div>
);
}
ReactDOM.render(<App />, document.getElementById("root"));
View Compiled
This Pen doesn't use any external CSS resources.
This Pen doesn't use any external JavaScript resources.