visit
npx create-react-app HamburgerMenu
Install styled-components dependency:npm install styled-components
Now if you want to create different file for your Hamburger Menu then you can, here I'm writing everything in the app.js file for this tutorial.We will start by importing styled components.
import styled from "styled-components";
Let's create one fixed rounded menu first. Name it as MenuLabel and create it using styled-components.
import React,{useState} from "react";
import "./styles.css";
import styled from "styled-components";
const MenuLabel = styled.label`
background-color: #B6EDC8;
position: fixed;
top: 6rem;
right: 6rem;
border-radius: 50%;
height: 7rem;
width: 7rem;
cursor: pointer;
z-index: 1000;
box-shadow: 0 1rem 3rem rgba(182, 237, 200, 0.3);
text-align: center;
`;
export default function App() {
return (
<>
<MenuLabel htmlFor="navi-toggle">
Menu
</MenuLabel>
</>
);
}
Now we will create icon above this menu.
Remove Menu written inside of MenuLabel and create new component Icon as below:<MenuLabel htmlFor="navi-toggle">
<Icon> </Icon>
</MenuLabel>
const Icon = styled.span`
position: relative;
background-color: black;
width: 3rem;
height: 2px;
display: inline-block;
margin-top: 3.5rem;
&::before,
&::after {
content: "";
background-color: black;
width: 3rem;
height: 2px;
display: inline-block;
position: absolute;
left: 0;
}
&::before {
top: -0.8rem;
}
&::after {
top: 0.8rem;
}
`;
import React,{useState} from "react";
import "./styles.css";
import styled from "styled-components";
const MenuLabel = styled.label`
background-color: #B6EDC8;
position: fixed;
top: 6rem;
right: 6rem;
border-radius: 50%;
height: 7rem;
width: 7rem;
cursor: pointer;
z-index: 1000;
box-shadow: 0 1rem 3rem rgba(182, 237, 200, 0.3);
text-align: center;
`;
const Icon = styled.span`
position: relative;
background-color: ${(props) => (props.clicked ? "transparent" : "black")};
width: 3rem;
height: 2px;
display: inline-block;
margin-top: 3.5rem;
transition: all 0.3s;
&::before,
&::after {
content: "";
background-color: black;
width: 3rem;
height: 2px;
display: inline-block;
position: absolute;
left: 0;
transition: all 0.3s;
}
&::before {
top: ${(props) => (props.clicked ? "0" : "-0.8rem")};
transform: ${(props) => (props.clicked ? "rotate(135deg)" : "rotate(0)")};
}
&::after {
top: ${(props) => (props.clicked ? "0" : "0.8rem")};
transform: ${(props) => (props.clicked ? "rotate(-135deg)" : "rotate(0)")};
}
`;
export default function App() {
const [click, setClick] = useState(false);
const handleClick = () => setClick(!click);
return (
<>
<MenuLabel htmlFor="navi-toggle" onClick={handleClick}>
<Icon clicked={click}> </Icon>
</MenuLabel>
</>
);
}
In MenuLabel set onClick to handleClick method to change click
state.
In the Icon pass state click as props clicked.(You can change prop
name clicked to anything you like)
In styling Icon background-color use this props and put ternary condition like if props.clicked is true then background will be transparent else it will be black → by doing this we’re removing the middle line. To remove it smoothly add transition effect.
Now in &::before and &::after Set top to **”0"** when someone clicks on icon so that both of those lines came little bit down to form X.
At transform property This is where we rotate both of this lines to form a Cross(X). If someone clicks it then state becomes true so it lines will rotate to 135deg. we can set low degree to make cross but by using 135deg we can see more animation.
Put transition in &::before and &::after block so that both of this lines create smooth animation.
Now if you want hover effect then we can do it as below:${MenuLabel}:hover &::before {
top: ${(props) => (props.clicked ? “0” : “-1rem”)};
}
${MenuLabel}:hover &::after {
top: ${(props) => (props.clicked ? “0” : “1rem”)};
}
Also published on: