Stuck with hamburger menu - javascript

I am making a hamburger menu that when clicked will show up on the entire screen it works just fine but now I am trying to make it when i click on option in the menu it takes me to the section i want but them it closes i have written this code but it only works on the first option the others don't do anything
const hamburger = document.querySelector(".hamburger");
const navMenu = document.querySelector(".nav_options");
const navMargin = document.querySelector(".sec_about");
const onClick = document.querySelector(".nav_item")
hamburger.addEventListener("click", mobileMenu);
function mobileMenu() {
hamburger.classList.toggle("active");
navMenu.classList.toggle("active");
navMargin.classList.toggle("active");
}
onClick.addEventListener("click", closeham);
function closeham() {
navMenu.classList.toggle("active");
hamburger.classList.toggle("active");
}
/* making the navbar responsive */
.hamburger {
display: none;
margin-right: 20px;
}
.bar {
display: block;
width: 30px;
height: 3px;
margin: 5px auto;
-webkit-transition: all 0.3s ease-in-out;
transition: all 0.3s ease-in-out;
background-color: #fa900f;
}
#media only screen and (max-width: 1000px) {
.nav_options {
position: absolute;
left: -100%;
top: 4rem;
flex-direction: column;
background-color: #000000;
border: solid 15px #fff;
width: 100%;
height: 1000px;
text-align: center;
transition: 0.3s;
box-shadow: 0 10px 27px rgba(0, 0, 0, 0.05);
}
nav ul li a {
color: #fa900f;
}
.nav_options.active {
left: 0;
}
.nav_item {
margin: 3rem 0;
}
.hamburger {
display: block;
cursor: pointer;
}
.hamburger.active .bar:nth-child(2) {
opacity: 0;
}
.hamburger.active .bar:nth-child(1) {
transform: translateY(8px) rotate(45deg);
}
.hamburger.active .bar:nth-child(3) {
transform: translateY(-8px) rotate(-45deg);
}
.sec_about.active {
margin-top: 35rem;
}
}
<header>
<nav>
<img src="/images/Logo.png" alt="Logo">
<ul class="nav_options">
<li class="nav_item"><a class="nav_item" href="#About">&ltAbout&gt</a></li>
<li class="nav_item"><a class="nav_item" href="#Skills">&ltSkill&gt</a></li>
<li class="nav_item"><a class="nav_item" href="#ResumeWork">&ltWork&gt</a></li>
<li class="nav_item"><a class="nav_item" href="#ResumeWork">&ltResume&gt</a></li>
<li class="nav_item"><a class="nav_item" href="#Contact">&ltContact&gt</a></li>
</ul>
<div class="hamburger">
<span class="bar"></span>
<span class="bar"></span>
<span class="bar"></span>
</div>
</nav>
</header>

You have a tiny error in your code.
The function querySelector() captures only one item that pass the requirements. You need to use querySelctorAll() to assign a click event. Based on your posted code here your new javascript:
const hamburger = document.querySelector(".hamburger");
const navMenu = document.querySelector(".nav_options");
const navMargin = document.querySelector(".sec_about");
//Here was a mistake
const onClick = document.querySelectorAll(".nav_options li.nav_item");
hamburger.addEventListener("click", mobileMenu);
function mobileMenu() {
hamburger.classList.toggle("active");
navMenu.classList.toggle("active");
navMargin.classList.toggle("active");
}
//Addational change, because querySelectorAll returns an array of elements
for (i = 0; i < onClick.length;i++) {
onClick[i].addEventListener("click", closeham);
}
function closeham() {
navMenu.classList.toggle("active");
hamburger.classList.toggle("active");
}

Related

How to close the floating menu if you click outside it with React

I created a Header component containing the site navbar which through useState and aria-attribute in the css shows or hides the menu in the mobile version of the site.
I used onFocus to manage the automatic closing of the side menu but it doesn't work if you click outside the menu ... it only works if you click on a menu item.
I also tried with onBlur but still it doesn't work.
How do I make the menu close if I click outside its panel?
Header component:
import { useRef, useState } from 'react';
import { Link } from 'react-router-dom';
import logo from '../imgs/logo.webp';
function Header() {
const refNavBar = useRef(),
[isOpen, setIsOpen] = useState(false),
handleToggle = () => setIsOpen(!isOpen);
return (
<header>
<div className="container g-2 pbk-1">
<Link to="/">
<img src={logo} alt="" />
</Link>
<button
className="nav-toggle"
aria-controls={refNavBar}
aria-expanded={isOpen}
onClick={handleToggle}
>
<div className="bar1" />
<div className="bar2" />
<div className="bar3" />
</button>
<nav
id="navbar"
ref={refNavBar}
data-visible={isOpen}
onFocus={handleToggle}
>
<ul className="flex g-2">
<li><Link to="/">Home</Link></li>
<li><Link to="/about">About</Link></li>
<li><Link to="/gallery">Gallery</Link></li>
<li><Link to="/contact">Contact</Link></li>
</ul>
</nav>
</div>
</header>
);
}
export default Header;
style:
.flex {
display: flex;
justify-content: center;
align-items: center;
flex-wrap: wrap;
}
.g-2 { gap: 2rem; }
.pbk-1 { padding-block: 1rem; }
header {
position: fixed;
width: 100%;
background-color: var(--bg);
}
header .container {
display: grid;
justify-items: end;
align-items: center;
grid-template-columns: 10rem 1fr;
}
button.nav-toggle {
display: none;
}
header nav ul li > a {
color: var(--white);
text-decoration: none;
}
header nav ul li > a:hover {
opacity: .8;
}
#media (max-width: 44em) {
.flex {
flex-direction: column;
}
button.nav-toggle {
display: block;
position: absolute;
right: 1rem;
width: 2.5rem;
border-radius: 0;
padding: 0;
background: transparent;
z-index: 9999;
}
button.nav-toggle .bar1,
button.nav-toggle .bar2,
button.nav-toggle .bar3 {
width: 100%;
height: .12rem;
margin-block: .65rem;
background-color: var(--white);
transition: var(--ease-in-out);
}
button.nav-toggle[aria-expanded="true"] .bar1 {
transform: rotate(-45deg) translate(-50%, -50%);
}
button.nav-toggle[aria-expanded="true"] .bar2 {
opacity: 0;
}
button.nav-toggle[aria-expanded="true"] .bar3 {
transform: rotate(45deg) translate(-50%, -50%);
}
nav#navbar {
position: fixed;
inset: 0 0 0 28%;
padding: min(20rem, 15vh) 2rem;
background: var(--bg);
z-index: 9998;
transform: translateX(100%);
transition: transform var(--ease-in-out);
}
nav#navbar[data-visible="true"] {
transform: translateX(0);
}
What am I doing wrong?
A thousand thanks
Detect click outside component example, can this work at your example?
import React, { useRef, useEffect } from "react";
/**
* Hook that alerts clicks outside of the passed ref
*/
function useOutsideAlerter(ref) {
useEffect(() => {
/**
* Alert if clicked on outside of element
*/
function handleClickOutside(event) {
if (ref.current && !ref.current.contains(event.target)) {
alert("You clicked outside of me!");
}
}
// Bind the event listener
document.addEventListener("mousedown", handleClickOutside);
return () => {
// Unbind the event listener on clean up
document.removeEventListener("mousedown", handleClickOutside);
};
}, [ref]);
}
/**
* Component that alerts if you click outside of it
*/
export default function OutsideAlerter(props) {
const wrapperRef = useRef(null);
useOutsideAlerter(wrapperRef);
return <div ref={wrapperRef}>{props.children}</div>;
}

JavaScript If and else statement w/function calls not producing expected result

I have a mobile menu that includes four list items. When you click on the "Features" list item, another unordered list is supposed to populate below it, and when you click it again, it's supposed to close it.
Here's my issue:
Inside the addEventListener function, I am calling two other functions (displayType and displayTypeCheck) inside the if, and else statement. When I do this and click on the "Features" list item, it opens but does not close when I click it again.
If I don't use the displayType and displayTypeCheck functions in the if and else statement and click on the "Features" list item, the UL will both open and close.
Why does the if and else statement that calls the other two functions not work, and how do I get it to work?
In the provided Javascript code below, the if and else statement that's commented out works, and the block that's not commented out is the code that doesn't entirely work.
const menuIcon = document.querySelector(".mobile-menu-icon");
const mobileMenu = document.querySelector(".mobile-menu");
const closeMenuIcon = document.querySelector(".close-menu-icon");
const featuresMobile = document.querySelector(".features-mobile");
const featuresMobileDropdown = document.querySelector(".features-mobile-dropdown");
const overlay = document.querySelector(".overlay");
function displayType(element, displayValue) {
element.style.display = displayValue;
}
function displayTypeCheck(element, displayValue) {
element.style.display === displayValue;
}
menuIcon.addEventListener("click", function () {
displayType(mobileMenu, 'block');
displayType(overlay, 'block');
});
closeMenuIcon.addEventListener("click", function () {
displayType(mobileMenu, 'none');
displayType(overlay, 'none');
});
featuresMobile.addEventListener("click", function () {
// if (featuresMobileDropdown.style.display === "block") {
// featuresMobileDropdown.style.display = "none";
// } else {
// featuresMobileDropdown.style.display = "block";
// }
if (displayTypeCheck(featuresMobileDropdown, "block")) {
displayType(featuresMobileDropdown, "none");
} else {
displayType(featuresMobileDropdown, "block");
}
});
#import url("https://fonts.googleapis.com/css2?family=Epilogue:wght#500;700&display=swap");
:root {
--almostWhite: hsl(0, 0%, 98%);
--mediumGray: hsl(0, 0%, 41%);
--almostBlack: hsl(0, 0%, 8%);
--navDropDownColor: #e9ecef;
}
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
ul {
list-style: none;
}
body {
min-height: 100vh;
font-family: "Epilogue", sans-serif;
background-color: var(--almostWhite);
}
header {
padding: .9375rem 2.5rem .9375rem 2.5rem;
max-width: 100rem;
margin: auto;
}
header nav {
display: flex;
align-items: center;
justify-content: flex-end;
}
header nav ul li {
cursor: pointer;
}
.register {
border: .125rem solid var(--mediumGray);
padding: .625rem .9375rem;
border-radius: .8125rem;
}
.mobile-menu-icon {
height: 3.125rem;
}
.mobile-menu-icon {
display: block;
cursor: pointer;
}
.mobile-menu .mobile-nav-links {
margin-top: 4.375em;
padding-left: .9375em;
color: var(--mediumGray);
}
.mobile-menu ul li {
padding: .625em;
}
.mobile-menu .mobile-nav-links li ul {
margin-left: .625em;
margin-top: .625em;
display: none;
}
.mobile-menu {
background-color: white;
width: 18.75em;
height: 100vh;
position: absolute;
top: 0;
right: 0;
z-index: 2;
display: none;
}
.close-menu-icon {
margin-left: auto;
margin-right: 1.25em;
margin-top: 1.25em;
display: block;
cursor: pointer;
height: 3.125em;
}
.login-register-mobile-container {
color: var(--mediumGray);
width: 90%;
margin: 3.125em auto;
}
.login-register-mobile-container span {
display: block;
text-align: center;
cursor: pointer;
}
.login-register-mobile-container span:first-child {
margin-bottom: 1.25em;
}
.overlay {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: rgba(0, 0, 0, 0.6);
backdrop-filter: blur(.1875rem);
z-index: 1;
display: none;
}
<header>
<nav>
<img class="mobile-menu-icon" src="https://upload.wikimedia.org/wikipedia/commons/thumb/b/b2/Hamburger_icon.svg/2048px-Hamburger_icon.svg.png" alt="" />
<div class="mobile-menu">
<img
class="close-menu-icon"
src="https://cdn4.iconfinder.com/data/icons/user-interface-131/32/close-512.png"
alt=""
/>
<ul class="mobile-nav-links">
<li class="features-mobile">Features
<ul class="features-mobile-dropdown">
<li>Todo List</li>
<li>Calenders</li>
<li>Reminders</li>
<li>Planning</li>
</ul>
</li>
<li class="company-mobile">Company</li>
<li>Careers</li>
<li>About</li>
</ul>
<div class="login-register-mobile-container">
<span class="login">Login</span>
<span class="register">Register</span>
</div>
</div>
</nav>
<div class="overlay"></div>
</header>
You forgot the return statement.
function displayTypeCheck(element, displayValue) {
return element.style.display === displayValue;
}
Otherwise the function will always return undefined which is a falsey value.
Within the displayTypeCheck function, you aren't returning the boolean result of the conditions.
Without the return statement, it is returning void
function displayTypeCheck(element, displayValue) {
return element.style.display === displayValue;
}

How do I get the dropdown navigation bar to work with html and css?

I've been trying to make a dropdown navigation bar (having the links centered) for the mobile view, with only html and css (separate javascript file isn't needed, as the project isn't that dense).
I think I missed something earlier on, but I can't find the problem anymore. Can someone make it work? Doesn't matter what method you use. If more parts of the code is needed, please inform me.
html navbar section:
<!-- Navigation bar section -->
<header class="navbar">
<div class='nav_container'>
<ion-icon class="mobile-menu-icon" id="mobile-cta" name="menu-outline"></ion-icon>
<nav>
<ion-icon class="mobile-close-icon" id="mobile-exit" name="close-outline"></ion-icon>
<ul class="primary_nav">
<li>Home</li>
<li>About</li>
<li>Portfolio</li>
<li>Contact</li>
</ul>
</nav>
</div>
</header>
script inside html:
<script>
const mobileBtn = document.getElementById('mobile-cta')
nav = document.querySelector('nav')
mobileBtnExit = document.getElementById('mobile-exit');
mobileBtn.addEventListener('click', () => {
nav.classList.toggle('menu-btn');
})
mobileBtnExit.addEventListener('click', () => {
nav.classList.toggle('menu-btn');
})
</script>
scss:
.navbar {
background: black;
.navbar_container {
display: flex;
place-content: space-between;
}
nav{
display: none;
position: fixed;
width: 100%;
height: 58vh;
padding: 1em;
top: 0;
z-index: 999;
background: var(--primary-blue);
ul {
margin-top: 2.1em;
}
li {
a {
display: block;
padding: .9em;
font-size: 2em;
font-weight: 500;
text-align: center;
opacity: 0.85;
&:hover {
opacity: 1;
transition: all 0.4 ease;
}
}
}
}
}
.mobile-close-icon {
position: absolute;
right: 0px;
margin-right: 1em;
cursor: pointer;
font-size: 3em;
color: white;
opacity: 0.85;
&:hover {
opacity: 1;
}
}
.mobile-menu-icon {
cursor: pointer;
color: white;
position: absolute;
right: 0px;
margin-right: 1em;
top: 15px;
width: 40px;
height: 40px;
}
It looks like you haven't defined your const declarations correctly. Try something like below:
<!-- Option 1: Explictly defined `const` definitions -->
<script>
const mobileBtn = document.getElementById('mobile-cta');
const nav = document.querySelector('nav');
const mobileBtnExit = document.getElementById('mobile-exit');
mobileBtn.addEventListener('click', () => {
nav.classList.toggle('menu-btn');
})
mobileBtnExit.addEventListener('click', () => {
nav.classList.toggle('menu-btn');
})
</script>
<!-- Option 2: "Inlined" const definitions -->
<script>
const mobileBtn = document.getElementById('mobile-cta'),
nav = document.querySelector('nav'),
mobileBtnExit = document.getElementById('mobile-exit');
mobileBtn.addEventListener('click', () => {
nav.classList.toggle('menu-btn');
})
mobileBtnExit.addEventListener('click', () => {
nav.classList.toggle('menu-btn');
})
</script>

Add a button to change to dark mode in html website

I have added a button on my site which let's the users change to dark or light mode whenever they want. I added the button with a moon icon on it, but the problem is that I want that the moon icon changes to sun icon when the user is in dark mode. And changes to moon icon when user is in light mode.
function myfunction(e) {
console.log("you clicked");
document.documentElement.classList.toggle("dark-mode");
document.querySelectorAll(".inverted").forEach((result) => {
result.classList.toggle("invert");
});
}
const btn = document.querySelector('.btn')
btn.addEventListener('click', myfunction);
.dark-mode {
filter: invert(1) hue-rotate(180deg);
}
.invert {
filter: invert(1) hue-rotate(180deg);
}
<button class="btn"><img src='moon.png'></img></button>
The .inverted class in js is because I don't want the images to invert their colors.. so I gave all the images a class='inverted'
So, this is what I've done and someone please let me know how I should change the icon to moon and sun depending on the current mode (light or dark)
Thanks!
You could add the sun as another image to the button and change the visibility of the two images via your .dark-mode css class.
So whenever the .dark-mode class is present the moon gets hidden and the sun gets shown.
function myfunction(e) {
console.log("you clicked");
document.documentElement.classList.toggle("dark-mode");
document.querySelectorAll(".inverted").forEach((result) => {
result.classList.toggle("invert");
});
}
const btn = document.querySelector('.btn')
btn.addEventListener('click', myfunction);
.dark-mode {
filter: invert(1) hue-rotate(180deg);
}
.invert {
filter: invert(1) hue-rotate(180deg);
}
/* button handling */
.moon {
display: block;
}
.sun {
display: none;
}
.dark-mode .moon {
display: none;
}
.dark-mode .sun {
display: block;
}
<button class="btn">
<img class="moon" src="moon.png" alt="moon"></img>
<img class="sun" src="sun.png" alt="sun"></img>
</button>
You could go with the CSS approach as in #Fabian's answer. If you would like to go with JS, you could simply use a flag to indicate whether or not the user switched to dark mode, and dynamically set the icon based on it.
let isDarkMode = document.documentElement.classList.contains("dark-mode");
function myfunction(e) {
document.documentElement.classList.toggle("dark-mode");
document.querySelectorAll(".inverted").forEach((result) => {
result.classList.toggle("invert");
});
e.currentTarget.querySelector("img").src = isDarkMode ? "sun.png" : "moon.png";
}
You can use the below reference for the toggle button from light mode to dark mode and dark mode to light mode.
body {
height: 100vh;
display: flex;
align-items: center;
justify-content: center;
}
.toggle-checkbox {
position: absolute;
opacity: 0;
cursor: pointer;
height: 0;
width: 0;
}
.toggle-slot {
position: relative;
height: 10em;
width: 20em;
border: 5px solid #e4e7ec;
border-radius: 10em;
background-color: white;
box-shadow: 0px 10px 25px #e4e7ec;
transition: background-color 250ms;
}
.toggle-checkbox:checked ~ .toggle-slot {
background-color: #374151;
}
.toggle-button {
transform: translate(11.75em, 1.75em);
position: absolute;
height: 6.5em;
width: 6.5em;
border-radius: 50%;
background-color: #ffeccf;
box-shadow: inset 0px 0px 0px 0.75em #ffbb52;
transition: background-color 250ms, border-color 250ms, transform 500ms cubic-bezier(.26,2,.46,.71);
}
.toggle-checkbox:checked ~ .toggle-slot .toggle-button {
background-color: #485367;
box-shadow: inset 0px 0px 0px 0.75em white;
transform: translate(1.75em, 1.75em);
}
.sun-icon {
position: absolute;
height: 6em;
width: 6em;
color: #ffbb52;
}
.sun-icon-wrapper {
position: absolute;
height: 6em;
width: 6em;
opacity: 1;
transform: translate(2em, 2em) rotate(15deg);
transform-origin: 50% 50%;
transition: opacity 150ms, transform 500ms cubic-bezier(.26,2,.46,.71);
}
.toggle-checkbox:checked ~ .toggle-slot .sun-icon-wrapper {
opacity: 0;
transform: translate(3em, 2em) rotate(0deg);
}
.moon-icon {
position: absolute;
height: 6em;
width: 6em;
color: white;
}
.moon-icon-wrapper {
position: absolute;
height: 6em;
width: 6em;
opacity: 0;
transform: translate(11em, 2em) rotate(0deg);
transform-origin: 50% 50%;
transition: opacity 150ms, transform 500ms cubic-bezier(.26,2.5,.46,.71);
}
.toggle-checkbox:checked ~ .toggle-slot .moon-icon-wrapper {
opacity: 1;
transform: translate(12em, 2em) rotate(-15deg);
}
<head>
<script src="https://code.iconify.design/1/1.0.4/iconify.min.js"> </script>
</head>
<label>
<input class='toggle-checkbox' type='checkbox'>
<div class='toggle-slot'>
<div class='sun-icon-wrapper'>
<div class="iconify sun-icon" data-icon="feather-sun" data-inline="false"></div>
</div>
<div class='toggle-button'></div>
<div class='moon-icon-wrapper'>
<div class="iconify moon-icon" data-icon="feather-moon" data-inline="false"></div>
</div>
</div>
</label>
function myfunction(e) {
const doc = document.documentElement
doc.classList.toggle("dark-mode");
document.querySelectorAll(".inverted").forEach((result) => {
result.classList.toggle("invert");
});
const img = e.currentTarget.querySelector('img')
const label = e.currentTarget.querySelector('span')
if (doc.classList.contains('dark-mode')) {
img.src = 'sun.png'
label.innerHTML = 'Light mode'
} else {
img.src = 'moon.png'
label.innerHTML = 'Dark mode'
}
}
const btn = document.querySelector('.btn')
btn.addEventListener('click', myfunction);
.dark-mode {
filter: invert(1) hue-rotate(180deg);
}
.invert {
filter: invert(1) hue-rotate(180deg);
}
'
<button class="btn">
<img src='moon.png' alt="" />
<span>Dark mode</span>
</button>

How to remove div re-positioning when zoom up? (shrink the browser)

I've made a simple slider that responses the mouseenter event.
The algorithm is when if the user moves its mouse pointer one of Appear menu contents, a div called .slate goes down.
My problem is in Chrome or Opera, when the user zoomed up by using CTRL + Mouse Wheel Up, the .slate is going to spills a bit and goes back up smoothly while Firefox doesn't:
I'm looking for a solution to remove this unwanted re-positioning except not using transition.
I've tried to give the transition more dynamically to resolve the problem. Add the transition when mouse entered to the Appear, remove it when mouse entered to Disappear.
But this one didn't work with an another new issue. The transition is going to ignore when I wag the mouse like this:
Are there any ways to resolve this problem?
CodePen: Original Code / Attempt 2
Snippet (Original):
'use strict';
class Slate {
constructor(header) {
this.header = document.querySelector(header);
this.slate = document.querySelector('.slate');
this.menu = this.header.querySelector('.menu');
this.contents = this.menu.querySelectorAll('.contents');
this.addEvent();
}
addEvent() {
this.contents.forEach((cur, idx) => {
cur.addEventListener('mouseenter', (e) => this.expand(e, idx));
})
}
expand(e, index) {
let lesser = (index < 2),
ternary = {
toggle: (lesser) ? this.slate.classList.add('toggle') : this.slate.classList.remove('toggle')
};
}
}
const proSlate = new Slate('header');
* {
margin: 0;
padding: 0;
font-family: Helvetica;
}
div, section, header {
position: relative;
}
ul, li {
list-style-type: none;
}
header, .slate {
width: 800px;
}
header {
height: 100px;
line-height: 100px;
background-color: rgba(69, 255, 0, .4);
}
.slate {
height: 400px;
line-height: 400px;
text-align: center;
color: white;
background-color: steelblue;
top: -25rem;
transition: top 500ms cubic-bezier(0.455, 0.03, 0.515, 0.955);
z-index: -1;
font-size: 4rem;
}
.menu {
width: 100%;
display: flex;
}
.contents {
margin: 0 20px;
}
.toggle {
top: 0;
}
<header>
<ul class="menu">
<li class="contents">Appear</li>
<li class="contents">Appear</li>
<li class="contents">Disapper</li>
<li class="contents">Disapper</li>
</ul>
</header>
<div class="slate">
CONTEXT OF SLATE
</div>
Instead of using top, go for transform
'use strict';
class Slate {
constructor(header) {
this.header = document.querySelector(header);
this.slate = document.querySelector('.slate');
this.menu = this.header.querySelector('.menu');
this.contents = this.menu.querySelectorAll('.contents');
this.addEvent();
}
addEvent() {
this.contents.forEach((cur, idx) => {
cur.addEventListener('mouseenter', (e) => this.expand(e, idx));
})
}
expand(e, index) {
let lesser = (index < 2),
ternary = {
toggle: (lesser) ? this.slate.classList.add('toggle') : this.slate.classList.remove('toggle')
};
}
}
const proSlate = new Slate('header');
* {
margin: 0;
padding: 0;
font-family: Helvetica;
}
div,
section,
header {
position: relative;
}
ul,
li {
list-style-type: none;
}
header,
.slate {
width: 800px;
}
header {
height: 100px;
line-height: 100px;
background-color: rgba(69, 255, 0, .4);
}
.slate {
height: 400px;
line-height: 400px;
text-align: center;
color: white;
background-color: steelblue;
transform: translateY(-100%);
transition: transform 500ms cubic-bezier(0.455, 0.03, 0.515, 0.955);
z-index: -1;
font-size: 4rem;
}
.menu {
width: 100%;
display: flex;
}
.contents {
margin: 0 20px;
}
.toggle {
transform: translateY(0);
}
<header>
<ul class="menu">
<li class="contents">Appear</li>
<li class="contents">Appear</li>
<li class="contents">Disapper</li>
<li class="contents">Disapper</li>
</ul>
</header>
<div class="slate">
CONTEXT OF SLATE
</div>

Categories