Why is the animation not reversed in GSAP? - javascript

I have question, I wanted reverse animation showMenuList (this is pink background), but this not working, where is the mistake? I tried paused, and so many method but this not working, please help
I know that this is mostly code but I don't know what else to write. Find my code below and here a Codepen link.
const menuToggler = document.querySelector(".toggler");
const menuTogglerHamburger = document.querySelector(".toggler .hamburger");
menuToggler.addEventListener("click", function () {
//checking if there is a class animationToggler
if (menuTogglerHamburger.classList.contains("animationToggler")) {
//restart animation rotate
menuTogglerHamburger.classList.remove("animationToggler");
void menuTogglerHamburger.offsetWidth;
menuTogglerHamburger.classList.add("animationToggler");
}
menuTogglerHamburger.classList.add("animationToggler");
menuToggler.classList.toggle("show");
menuToggler.classList.contains("show")
? showMenuList(true)
: showMenuList(false);
setTimeout(() => {
//animation line on the cross
menuTogglerHamburger.classList.toggle("active");
}, 200);
});
//---------------------- Show menu list ----------------------//
const showMenuList = (e) => {
console.log(e);
const showMenuTl = gsap.timeline({ pause: true });
e ? showMenuTl.play() : showMenuTl.reverse();
showMenuTl
.to(".nav-menu", 0.8, { css: { top: "50%" } })
.to(".nav-menu", 0.4, { css: { width: "140vw", height: "140vw" } });
};
body {
overflow: hidden;
}
nav {
display: flex;
width: 100%;
align-items: center;
justify-content: space-around;
padding-top: 1em;
}
.toggler {
display: flex;
align-items: center;
cursor: pointer;
}
.animationToggler {
animation: animationTogglerMenu .8s ease;
}
.toggler p {
margin: 0;
text-transform: uppercase;
font-size: 1.65rem;
margin: 0 0 0 10px;
z-index: 3;
}
.hamburger {
z-index: 3;
}
.hamburger .line {
height: 4px;
width: 2.5em;
background: #000;
margin: .45em 0;
border-radius: 50px;
transition: .3s;
}
.active .one {
transform: rotate(45deg) translateY(15px);
}
.active .two {
background-color: transparent;
transition: none;
}
.active .three {
transform: rotate(-45deg) translateY(-15px);
}
.nav-menu {
position: absolute;
top: -100%;
left: 50%;
transform: translate(-50%, -50%);
width: 3em;
height: 3em;
background-color: rgb(255, 117, 117);
border-radius: 50%;
/* opacity: 0.4; */
z-index: 2;
}
.nav-menu ul {
display: none;
}
#keyframes animationTogglerMenu {
100% {
transform: rotate(360deg);
}
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<div class="toggler">
<div class="hamburger">
<div class="line one"></div>
<div class="line two"></div>
<div class="line three"></div>
</div>
<p>Menu</p>
</div>
<div class="nav-menu">
<ul>
<li>Home</li>
<li>Projekty</li>
<li>O nas</li>
<li>Kontakt</li>
</ul>
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.10.4/gsap.min.js"></script>
<script src="main.js"></script>
</body>
</html>

One issue with your code is you need to pass paused: true instead of pause:true to the timeline function.
One way you could improve your code (in my opinion) is to move the creation of your timeline object to the top level of your code block. Like so...
const menuToggler = document.querySelector(".toggler");
const menuTogglerHamburger = document.querySelector(".toggler .hamburger");
// Add it here -----------------------
const showMenuTl = gsap.timeline({ paused: true });
showMenuTl
.to(".nav-menu", 0.8, { css: { top: "50%" } })
.to(".nav-menu", 0.4, { css: { width: "140vw", height: "140vw" } });
Then you can get rid of the showMenuList function and call play and reverse directly.
menuToggler.classList.toggle("show");
menuToggler.classList.contains("show")
? showMenuTl.play()
: showMenuTl.reverse()

First, it should be { paused: true }, not { pause: true }, as #jessegavin said. Second, at the point where the click happens, you should have already set up the animation, which means the timeline definition should be at the top, outside of showMenuList. Third, you could simplify your code (See the JavaScript part, it's way more short, I slightly modified the CSS). Like so:
const menuToggler = document.querySelector(".toggler");
const showMenuTl = gsap.timeline({ paused: true });
showMenuTl
.to(".nav-menu", 0.8, { css: { top: "50%" } })
.to(".nav-menu", 0.4, { css: { width: "140vw", height: "140vw" } });
menuToggler.addEventListener("click", function () {
if (menuToggler.classList.contains("active")) {
menuToggler.classList.remove("active");
showMenuTl.reverse();
} else {
menuToggler.classList.add("active");
showMenuTl.play();
}
});
body {
overflow: hidden;
}
nav {
display: flex;
width: 100%;
align-items: center;
justify-content: space-around;
padding-top: 1em;
}
.toggler {
display: flex;
align-items: center;
cursor: pointer;
}
.toggler p {
margin: 0;
text-transform: uppercase;
font-size: 1.65rem;
margin: 0 0 0 10px;
z-index: 3;
}
.hamburger {
z-index: 3;
}
.hamburger .line {
height: 4px;
width: 2.5em;
background: #000;
margin: 0.45em 0;
border-radius: 50px;
transition: 0.3s;
}
.active .hamburger {
animation: animationTogglerMenu 0.8s ease;
}
.active .one {
transform: rotate(45deg) translateY(15px);
}
.active .two {
background-color: transparent;
transition: none;
}
.active .three {
transform: rotate(-45deg) translateY(-15px);
}
.nav-menu {
position: absolute;
top: -100%;
left: 50%;
transform: translate(-50%, -50%);
width: 3em;
height: 3em;
background-color: rgb(255, 117, 117);
border-radius: 50%;
/* opacity: 0.4; */
z-index: 2;
}
.nav-menu ul {
display: none;
}
#keyframes animationTogglerMenu {
100% {
transform: rotate(360deg);
}
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<div class="toggler">
<div class="hamburger">
<div class="line one"></div>
<div class="line two"></div>
<div class="line three"></div>
</div>
<p>Menu</p>
</div>
<div class="nav-menu">
<ul>
<li>Home</li>
<li>Projekty</li>
<li>O nas</li>
<li>Kontakt</li>
</ul>
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.10.4/gsap.min.js"></script>
<script src="main.js"></script>
</body>
</html>

One way you could approach this is creating another timeline. Which would be annoying to deal with if you added more keyframes. Another way you could do this is by adding a starting keyframe and then everything should run smoothly as shown below.
showMenuTl
.to(".nav-menu", 1, { css: { width: "3rem", height: "3rem", top: "-100%" } })
.to(".nav-menu", 0.8, { css: { width: "3rem", height: "3rem", top: "50%" } })
.to(".nav-menu", 0.4, { css: { width: "140vw", height: "140vw", top: "50%" } });
e ? showMenuTl.play() : showMenuTl.reverse(0);

Related

Creating a slider with a menu bar - The heading as a link isn't aligning up correctly

I hope you're all well.
I am using a code that I took from Codepen, many may come across this before, I am trying to use this code as a navigation menu with the text as a link to the section/page. The text isn't aligning correctly. Please bear in mind, that I am still new to HTML and CSS and exploring code to create usable websites. I am aware that the text container will need a anchor link for it to become a menu - this is not the issue. I really appreciate your time.
Code:
HTML
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta name="description" content="bespoke furniture" />
<meta property="og:title" content="GSP Furniture" />
<meta property="og:description" content="GSP Furniture" />
<meta property="og:type" content="website" />
<meta property="og:image" content="http://" />
<meta property="og:url" content="https://gspfurniture.com/" />
<title>GSP Furniture | Tailor Made Furniture</title>
<link rel="stylesheet" href="css/style.css" />
<link
rel="stylesheet"
href="https://cdnjs.cloudflare.com/ajax/libs/slick-carousel/1.6.0/slick.min.css"
/>
<link
rel="stylesheet"
href="https://cdnjs.cloudflare.com/ajax/libs/slick-carousel/1.6.0/slick-theme.min.css"
/>
</head>
<body>
<!--Navigation-->
<nav class="split-slideshow">
<div class="slideshow">
<div class="slider">
<div class="item">
<img
src="https://themegoods-cdn-pzbycso8wng.stackpathdns.com/dotlife/demo/wp-content/uploads/2019/04/group-of-high-school-students-with-female-teacher-X8D9B7H.jpg"
/>
</div>
<div class="item">
<img
src="https://themegoods-cdn-pzbycso8wng.stackpathdns.com/dotlife/demo/wp-content/uploads/2019/04/friends-studying-together-PREVX3X.jpg"
/>
</div>
<div class="item">
<img
src="https://themegoods-cdn-pzbycso8wng.stackpathdns.com/dotlife/demo/wp-content/uploads/2019/04/rear-view-of-male-high-school-teacher-standing-at-YQ95J8T.jpg"
/>
</div>
<div class="item">
<img
src="https://themegoods-cdn-pzbycso8wng.stackpathdns.com/dotlife/demo/wp-content/uploads/2019/04/busy-woman-working-with-her-laptop-PQ9KULX.jpg"
/>
</div>
</div>
</div>
<div class="slideshow-text">
<div class="item">About us</div>
<div class="item">Our Work</div>
<div class="item">Testimonial</div>
<div class="item">Contact us</div>
</div>
</nav>
<!-- partial -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery-mousewheel/3.1.12/jquery.mousewheel.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/slick-carousel/1.6.0/slick.min.js"></script>
<script src="./js/jsScript.js"></script>
</body>
</html>
CSS:
/* Import and merge normalized.css stylesheet*/
#import "./normalize.css";
/* Root Color for the website */
:root {
/* Declaring a variable */
--color-headings: #020431;
--color-primary: #d0aa41;
}
/* HTML Page */
*,
*::after,
*::before {
box-sizing: border-box;
}
html {
/* by default html font-size is 16px */
/* 62.5% of 16px = 10px */
font-size: 62.5%;
margin: 0;
scroll-behavior: smooth;
}
body {
font-family: Inter, Arial, Helvetica, sans-serif;
font-size: 1.4rem;
}
/* Navigation */
.slideshow {
position: absolute;
z-index: 1;
top: 0;
left: 0;
width: 100vw;
height: 100vh;
overflow: hidden;
}
.slideshow .slider {
width: 100vw;
height: 100vw;
z-index: 2;
}
.slideshow .slider * {
outline: none;
}
.slideshow .slider .item {
height: 100vh;
width: 100vw;
position: relative;
overflow: hidden;
border: none;
}
.slideshow .slider .item .text {
display: none;
}
.slideshow .slider .item img {
min-width: 101%;
max-height: 70vh;
position: absolute;
top: 35%;
left: 50%;
transform: translate(-50%, -50%);
}
.slideshow .slick-dots {
position: fixed;
z-index: 100;
width: 40px;
height: auto;
bottom: auto;
top: 10%;
right: 0;
transform: translateY(-50%);
left: auto;
color: var(--color-headings);
display: block;
}
.slideshow .slick-dots li {
display: block;
width: 100%;
height: auto;
}
.slideshow .slick-dots li button {
position: relative;
width: 20px;
height: 15px;
text-align: center;
transition: all 0.8s ease-in;
}
.slideshow .slick-dots li button:hover {
transform: translateX(-0.5rem);
}
.slideshow .slick-dots li button:before {
content: "";
background: var(--color-primary);
color: var(--color-primary);
height: 2px;
width: 20px;
border-radius: 0;
position: absolute;
top: 50%;
right: 0;
left: auto;
transform: translateY(-50%);
transition: all 0.3s ease-in-out;
opacity: 0.6;
}
.slideshow .slick-dots li.slick-active button:before {
width: 40px;
opacity: 1;
}
.slideshow.slideshow-right {
left: 0;
z-index: 1;
width: 50vw;
pointer-events: none;
}
.slideshow.slideshow-right .slider {
left: 0;
position: absolute;
}
.slideshow-text {
position: absolute;
top: 20%;
left: 50%;
transform: translate(-50%, -50%);
z-index: 100;
font-size: 80px;
width: 100%;
text-align: center;
color: #fff;
font-family: "Roboto Condensed", sans-serif;
font-weight: 100;
pointer-events: none;
text-transform: uppercase;
letter-spacing: 20px;
line-height: 0.8;
}
#media (max-width: 768px) {
.slideshow-text {
font-size: 40px;
}
}
JS:
//Slideshow slider
var $slider = $('.slideshow .slider'), maxItems = $('.item', $slider).length, dragging = false, tracking,rightTracking;
$sliderRight = $('.slideshow').clone().addClass('slideshow-right').appendTo($('.split-slideshow'));
rightItems = $('.item', $sliderRight).toArray();
reverseItems = rightItems.reverse();
$('.slider', $sliderRight).html('');
for (i = 0; i < maxItems; i++) {
$(reverseItems[i]).appendTo($('.slider', $sliderRight));
}
$slider.addClass('slideshow-left');
$('.slideshow-left').slick({
vertical: true,
verticalSwiping: true,
arrows: false,
infinite: true,
dots: true,
speed: 1000,
cssEase: 'cubic-bezier(0.7, 0, 0.3, 1)'
}).on('beforeChange', function(event, slick, currentSlide, nextSlide) {
if (currentSlide > nextSlide && nextSlide == 0 && currentSlide == maxItems - 1) {
$('.slideshow-right .slider').slick('slickGoTo', -1);
$('.slideshow-text').slick('slickGoTo', maxItems);
} else if (currentSlide < nextSlide && currentSlide == 0 && nextSlide == maxItems - 1) {
$('.slideshow-right .slider').slick('slickGoTo', maxItems);
$('.slideshow-text').slick('slickGoTo', -1);
} else {
$('.slideshow-right .slider').slick('slickGoTo', maxItems - 1 - nextSlide);
$('.slideshow-text').slick('slickGoTo', nextSlide);
}
}).on("mousewheel", function(event) {
event.preventDefault();
if (event.deltaX > 0 || event.deltaY < 0) {
$(this).slick('slickNext');
} else if (event.deltaX < 0 || event.deltaY > 0) {
$(this).slick('slickPrev');
};
}).on('mousedown touchstart', function(){
dragging = true;
tracking = $('.slick-track', $slider).css('transform');
tracking = parseInt(tracking.split(',')[5]);
rightTracking = $('.slideshow-right .slick-track').css('transform');
rightTracking = parseInt(rightTracking.split(',')[5]);
}).on('mousemove touchmove', function(){
if (dragging) {
newTracking = $('.slideshow-left .slick-track').css('transform');
newTracking = parseInt(newTracking.split(',')[5]);
diffTracking = newTracking - tracking;
$('.slideshow-right .slick-track').css({'transform': 'matrix(1, 0, 0, 1, 0, ' + (rightTracking - diffTracking) + ')'});
}
}).on('mouseleave touchend mouseup', function(){
dragging = false;
});
$('.slideshow-right .slider').slick({
swipe: false,
vertical: true,
arrows: false,
infinite: true,
speed: 950,
cssEase: 'cubic-bezier(0.7, 0, 0.3, 1)',
initialSlide: maxItems - 1
});
$('.slideshow-text').slick({
swipe: false,
vertical: true,
arrows: false,
infinite: true,
speed: 900,
cssEase: 'cubic-bezier(0.7, 0, 0.3, 1)'
});
Thank you.
You have to add the margin-top:30px; to the CSS class slideshow-text.
Updated the CSS class
.slideshow-text {
position: absolute;
top: 20%;
left: 50%;
transform: translate(-50%, -50%);
z-index: 100;
font-size: 80px;
width: 100%;
text-align: center;
color: #fff;
font-family: "Roboto Condensed", sans-serif;
font-weight: 100;
pointer-events: none;
text-transform: uppercase;
letter-spacing: 20px;
line-height: 0.8;
margin-top:30px;
}
#media (max-width: 768px) {
.slideshow-text {
font-size: 40px;
letter-spacing: normal;
}
}
CSS Margin:
The CSS margin properties are used to create space around elements, outside of any defined borders.
With CSS, you have full control over the margins. There are properties for setting the margin for each side of an element (top, right, bottom, and left).
CSS has properties for specifying the margin for each side of an element:
margin-top
margin-right
margin-bottom
margin-left
iPhone SE screenshot:
Moto G4 screenshot:
DEMO Link

How do I animate my Navigation Button to perform the proper animation assigned to it using JavaScript?

So here's what I have and I can figure out why my burger div (navigation button on mobile) won't animate to shape a X can anyone explain what I'm missing or doing wrong?
Ive tried changing the class name using toggle through javaScript but it doesn't animate the lines 45 degrees and Im unsure why that is?
I would like to know what I can do in terms of changing the burger (nav button) to form a X and hide the center line by fading it out using a javaScript
This also my first time using stack overflow in terms of asking a question so please go easy on me.
const navSlide = () => {
const burger = document.querySelector('.burger');
const nav = document.querySelector('.nav-items');
const navItems = document.querySelectorAll('.nav-items li');
burger.addEventListener('click', () => {
//NAV Toggle
nav.classList.toggle('nav-active');
//Items Animated
navItems.forEach((item, index) => {
if (item.style.animation) {
item.style.animation = '';
} else {
item.style.animation = `navItemFade 0.5s ease forwards ${index / 7 + .3}s`;
}
});
//Burger Animation
burger.classList.toggle('tip');
});
}
navSlide();
* {
box-sizing: border-box;
margin: 0;
padding: 0;
}
html {
scroll-behavior: smooth;
}
a {
text-decoration: none;
color: rgb(245, 245, 245);
transition: .3s;
}
/* NAV */
nav {
display: flex;
justify-content: space-between;
align-items: center;
min-height: 11vh;
font-family: 'Poppins', sans-serif;
background-color: rgb(255, 145, 0);
}
.logo {
margin-left: 3rem;
}
.logo>a>h1 {
color: rgb(245, 245, 245);
letter-spacing: 3px;
text-transform: uppercase;
font-size: 32px;
}
.nav-items {
display: flex;
align-items: center;
list-style-type: none;
margin-right: 25rem;
}
.nav-items>li {
padding: 1.5rem;
}
.nav-items>li>a {
font-size: 16px;
}
.nav-items>li>a:hover {
color: rgb(0, 0, 0);
}
.nav-icons {
display: flex;
margin-right: 2rem;
}
.nav-fas {
margin: 1rem;
cursor: pointer;
}
.burger {
display: none;
margin-left: 1rem;
}
.burger>div {
width: 25px;
height: 3px;
background-color: rgb(0, 0, 0);
margin: 5px;
transition: all 0.3s ease;
}
/* NAV MOBILE */
#media screen and (max-width:1240px) {
.nav-items {
margin-right: 10px;
transition: .3s;
}
}
#media screen and (max-width:860px) {
body {
overflow-x: hidden;
}
.nav-items {
width: 100%;
max-width: 300px;
display: flex;
flex-direction: column;
justify-content: space-evenly;
position: absolute;
height: 90vh;
top: 14vh;
background-color: rgb(255, 145, 0);
transform: translateX(-100%);
transition: transform 0.5s ease-in;
}
.nav-items li {
opacity: 0;
}
.burger {
display: block;
cursor: pointer;
}
#fas1,
#fas2 {
display: none;
}
}
.nav-active {
transform: translateX(0%);
}
#keyframes navItemFade {
from {
opacity: 0;
transform: translateX(50px);
}
to {
opacity: 1;
transform: translateX(0px);
}
}
.tip .line1 {
transform: rotate(-45deg) translate(-5px, 6px);
}
.tip .line2 {
opacity: 0;
}
.tip .line3 {
transform: rotate(45deg) translate(-5px, -6px);
}
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="main.css">
<link rel="preconnect" href="https://fonts.gstatic.com">
<link href="https://fonts.googleapis.com/css2?family=Poppins&display=swap" rel="stylesheet">
<title>E-Store</title>
</head>
<body>
<header>
<nav>
<div class="burger">
<div clsss="line1"></div>
<div clsss="line2"></div>
<div clsss="line3"></div>
</div>
<div class="logo">
<a href="index.html">
<h1>logo</h1>
</a>
</div>
<ul class="nav-items">
<li>Home</li>
<li>Collection</li>
<li>About</li>
<li>Contact us</li>
</ul>
<div class="nav-icons">
<div class="nav-fas" id="fas1">
<i class="fas fa-map-marker-alt"></i>
</div>
<div class="nav-fas" id="fas2">
<i class="fas fa-envelope"></i>
</div>
<div class="nav-fas" id="fas3">
<i class="fas fa-search"></i>
</div>
<div class="nav-fas" id="fas4">
<i class="fas fa-shopping-cart"></i>
</div>
</div>
</nav>
</header>
<script src="./app.js" type="module"></script>
</body>
</html>
Everything is right. You just have one simple spelling mistake, you wrote clsss instead of class on three divs with class line1, line2, line3.
PS:- It looks like you are new to web development. A piece of advice for you, make use of text editor(whatever you might be using) to detect small spelling mistakes and other linting errors. It will save you a lot of time.

How can I use click event properly in my custom navigation menu?

I was trying to create an animated hamburger nav menu. The functionality is simple. It will be in a fixed position & incorporate in a circle. When I click that circle the background will overlap the entire screen & nav links will be visible. I have used pseudo-class to create functionality. it works well, but a little mistake appeared. When I clicked the nav links the background should scale to 0. But it is nowhere can be done using CSS. So I used JS click event for it. It worked for the first try after that the menu keep scaled to 0 unit. I need to fix it so that the js click event functionality reset itself on every try. The link is given below.
codepen here
Code-
const navElement = document.querySelector('.navigation__nav');
const navBackground = document.querySelector('.navigation__background');
const navgationList = document.querySelectorAll('.navigation__item');
navgationList.forEach(function(items) {
let x = items;
items.addEventListener('click', closeNav);
function closeNav() {
navElement.style.transform = 'scale(0)';
navBackground.style.transform = 'scale(0)';
}
});
body {
background-color: cyan;
}
.navigation__checkbox {
display: none;
}
.navigation__button {
background-color: #fff;
height: 7rem;
width: 7rem;
position: fixed;
top: 6rem;
right: 6rem;
border-radius: 50%;
z-index: 2000;
box-shadow: 0 1rem 3rem rgba(0, 0, 0, 0.1);
text-align: center;
cursor: pointer;
}
#media only screen and (max-width: 56.25em) {
.navigation__button {
top: 4rem;
right: 4rem;
}
}
#media only screen and (max-width: 37.5em) {
.navigation__button {
top: 3rem;
right: 3rem;
}
}
.navigation__background {
height: 6rem;
width: 6rem;
border-radius: 50%;
position: fixed;
top: 6.5rem;
right: 6.5rem;
background-image: radial-gradient(#4ea5f7, #0400ff);
z-index: 1000;
transition: transform 0.8s cubic-bezier(0.86, 0, 0.07, 1);
}
#media only screen and (max-width: 56.25em) {
.navigation__background {
top: 4.5rem;
right: 4.5rem;
}
}
#media only screen and (max-width: 37.5em) {
.navigation__background {
top: 3.5rem;
right: 3.5rem;
}
}
.navigation__nav {
height: 100vh;
position: fixed;
top: 0;
left: 0;
z-index: 1500;
opacity: 0;
width: 0;
transition: all 0.8s cubic-bezier(0.68, -0.55, 0.265, 1.55);
}
.navigation__list {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
list-style: none;
text-align: center;
width: 100%;
}
.navigation__item {
margin: 1rem;
}
.navigation__link:link,
.navigation__link:visited {
display: inline-block;
font-size: 3rem;
font-weight: 300;
padding: 1rem 2rem;
color: #fff;
text-decoration: none;
text-transform: uppercase;
background-image: linear-gradient(120deg, transparent 0%, transparent 50%, #fff 50%);
background-size: 220%;
transition: all .4s;
}
.navigation__link:link span,
.navigation__link:visited span {
margin-right: 1.5rem;
display: inline-block;
}
.navigation__link:hover,
.navigation__link:active {
background-position: 100%;
color: #0400ff;
transform: translateX(1rem);
}
.navigation__checkbox:checked~.navigation__background {
transform: scale(80);
}
.navigation__checkbox:checked~.navigation__nav {
opacity: 1;
width: 100%;
}
.navigation__icon {
position: relative;
margin-top: 3.5rem;
}
.navigation__icon,
.navigation__icon::before,
.navigation__icon::after {
width: 3rem;
height: 2px;
background-color: #333;
display: inline-block;
}
.navigation__icon::before,
.navigation__icon::after {
content: "";
position: absolute;
left: 0;
transition: all .2s;
}
.navigation__icon::before {
top: -.8rem;
}
.navigation__icon::after {
top: .8rem;
}
.navigation__button:hover .navigation__icon::before {
top: -1rem;
}
.navigation__button:hover .navigation__icon::after {
top: 1rem;
}
.navigation__checkbox:checked+.navigation__button .navigation__icon {
background-color: transparent;
}
.navigation__checkbox:checked+.navigation__button .navigation__icon::before {
top: 0;
transform: rotate(135deg);
}
.navigation__checkbox:checked+.navigation__button .navigation__icon::after {
top: 0;
transform: rotate(-135deg);
}
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Menu</title>
</head>
<body>
<div class="navigation">
<input type="checkbox" class="navigation__checkbox" id="navi-toggle">
<label for="navi-toggle" class="navigation__button">
<span class="navigation__icon"> </span>
</label>
<div class="navigation__background"> </div>
<nav class="navigation__nav">
<ul class="navigation__list">
<li class="navigation__item"><span>01</span> Our Works</li>
<li class="navigation__item"><span>02</span> Features</li>
<li class="navigation__item"><span>03</span> Our Services</li>
<li class="navigation__item"><span>04</span> Blogs</li>
<li class="navigation__item"><span>05</span> Contact Us</li>
<li class="navigation__item"><span>06</span> Know About Author</li>
</ul>
</nav>
</div>
</body>
</html>
[p.s.- comment out the js code first to see the working CSS.]
Although this is for practices hence any help will be a big help for me to understand js and dom.
I reworked a bit your closeNav function in order to get what you want working.
function closeNav(){
navElement.style.transform = 'scale(0)';
navBackground.style.transform = 'scale(0)';
// setTimeout will be useful for resetting our elements once they
// reached scale(0)
setTimeout(() => {
// You can check or uncheck a checkbox in javascript using .checked,
// here in order to set the styles back to normal.
document.querySelector('.navigation__checkbox').checked = false;
// Wait a bit more that the elements have been reset to remove the
// styles given in JS above.
setTimeout(() => {
navElement.style = '';
navBackground.style = '';
}, 500);
}, 1000);
}
You'll need to rework the timeouts so that they exactly meet your transition duration !
The CSS already handles what happens when the checkbox isn't checked. This works fine for me.
function closeNav(){
document.querySelector('.navigation__checkbox').checked = false;
}

js for custom select works in codepen and jsfiddle but not in browser?

I'm working on a custom select element, the code runs as expected in codepen and jsfiddle, but won't drop down if I run it in browser. I've never implemented js in a web project before so I feel like I'm missing something fairly simple.
here's the link to the codepen: https://codepen.io/kylegendy/pen/xxwYrPr
and here's the code I put in...:
script.js
for (const dropdown of document.querySelectorAll(".custom-select-wrapper")) {
dropdown.addEventListener('click', function() {
this.querySelector('.custom-select').classList.toggle('open');
})
}
for (const option of document.querySelectorAll(".custom-option")) {
option.addEventListener('click', function() {
if (!this.classList.contains('selected')) {
this.parentNode.querySelector('.custom-option.selected').classList.remove('selected');
this.classList.add('selected');
this.closest('.custom-select').querySelector('.custom-select__trigger span').textContent = this.textContent;
}
})
}
window.addEventListener('click', function(e) {
for (const select of document.querySelectorAll('.custom-select')) {
if (!select.contains(e.target)) {
select.classList.remove('open');
}
}
});
function selectOption(index) {
var optionOnIdx = document.querySelector('.custom-option:nth-child(' + index + ')');
var optionSelected = document.querySelector('.custom-option.selected');
if (optionOnIdx !== optionSelected) {
optionSelected.parentNode.querySelector('.custom-option.selected').classList.remove('selected');
optionOnIdx.classList.add('selected');
optionOnIdx.closest('.custom-select').querySelector('.custom-select__trigger span').textContent = optionOnIdx.textContent;
}
}
document.querySelector('button').addEventListener("click", function() {
selectOption(2);
});
template.css
*,
*:after,
*:before {
box-sizing: border-box;
}
.container .custom-select-wrapper {
display: flex;
text-align: center;
/* centeres the text horizontally */
width: 300px;
border-width: thick;
border-color: blue;
border-style: solid;
}
custom-select-wrapper>div {
display: inline-block;
position: relative;
max-width: 50%;
}
.container .selectName {
display: flex;
justify-content: center;
align-items: center;
position: relative;
user-select: none;
border-width: thick;
border-color: red;
border-style: none solid none none;
background-color: rgba(228, 228, 228, 0.39);
}
.custom-select-wrapper {
position: relative;
user-select: none;
}
.custom-select {
display: flex;
flex-direction: column;
border-width: 0;
}
.custom-select-wrapper>div {
display: inline-block;
/* blocks just line up without floats */
position: relative;
/* sets positioning context for 2nd level menu */
width: 50%;
height: 60px;
}
.custom-select__trigger {
position: relative;
display: flex;
align-items: center;
justify-content: space-between;
padding: 0 22px;
color: rgba(83, 83, 83, 1);
line-height: 60px;
background-color: rgba(228, 228, 228, 0.39);
cursor: pointer;
border-width: 0;
}
.custom-options {
position: absolute;
display: block;
top: 100%;
left: 0;
right: 0;
border: none;
background: white;
transition: all 0.5s;
opacity: 0;
visibility: hidden;
}
.custom-select.open .custom-options {
opacity: 1;
visibility: visible;
}
.custom-option {
position: relative;
display: block;
padding: 0 22px 0 22px;
color: rgba(83, 83, 83, 1);
line-height: 60px;
cursor: pointer;
}
.custom-option:hover {
cursor: pointer;
background-color: rgba(228, 228, 228, 0.39);
}
.custom-option.selected {
color: white;
background-color: rgb(149, 189, 204);
}
.arrow {
position: relative;
height: 15px;
width: 15px;
}
.arrow::before,
.arrow::after {
content: "";
position: absolute;
bottom: 0px;
width: 0.15rem;
height: 100%;
transition: all 0.5s;
}
.arrow::before {
left: -5px;
transform: rotate(45deg);
background-color: #394a6d;
}
.arrow::after {
left: 5px;
transform: rotate(-45deg);
background-color: #394a6d;
}
.open .arrow::before {
left: -5px;
transform: rotate(-45deg);
}
.open .arrow::after {
left: 5px;
transform: rotate(45deg);
}
template.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>the wall</title>
<link href="template.css" rel="stylesheet" type="text/css">
<script src="script.js" type="text/javascript"></script>
</head>
<body>
<div class="container">
<div class="custom-select-wrapper">
<div class="selectName"><span>Type</span></div>
<div class="custom-select">
<div class="custom-select__trigger"><span>Tesla</span>
<div class="arrow"></div>
</div>
<div class="custom-options">
<span class="custom-option selected" data-value="tesla">Tesla</span>
<span class="custom-option" data-value="volvo">Volvo</span>
<span class="custom-option" data-value="mercedes">Mercedes</span>
</div>
</div>
</div>
</div>
</body>
</html>
edit: I deleted the segment of js code starting at line 38 in jsfiddle and codepen and the dropdown worked the same, the way it’s supposed to, but when I got rid of it in the files to run on browser, although the error disappears, the dropdown still doesn’t work.
Put your script in a function like below
function Test(){
for (const dropdown of document.querySelectorAll(".custom-select-wrapper")) {
dropdown.addEventListener('click', function () {
this.querySelector('.custom-select').classList.toggle('open');
})
}
for (const option of document.querySelectorAll(".custom-option")) {
option.addEventListener('click', function () {
if (!this.classList.contains('selected')) {
this.parentNode.querySelector('.custom-option.selected').classList.remove('selected');
this.classList.add('selected');
this.closest('.custom-select').querySelector('.custom-select__trigger span').textContent = this.textContent;
}
})
}
window.addEventListener('click', function (e) {
for (const select of document.querySelectorAll('.custom-select')) {
if (!select.contains(e.target)) {
select.classList.remove('open');
}
}
});
function selectOption(index) {
var optionOnIdx = document.querySelector('.custom-option:nth-child('+index+')');
var optionSelected = document.querySelector('.custom-option.selected');
if (optionOnIdx !== optionSelected) {
optionSelected.parentNode.querySelector('.custom-option.selected').classList.remove('selected');
optionOnIdx.classList.add('selected');
optionOnIdx.closest('.custom-select').querySelector('.custom-select__trigger span').textContent = optionOnIdx.textContent;
}
}
}
and call this function from your HTML page
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>the wall</title>
<link href="template.css" rel="stylesheet" type="text/css">
<script src="script.js" type="text/javascript"></script>
</head>
<body>
<div class="container">
<div class="custom-select-wrapper">
<div class="selectName"><span>Type</span></div>
<div class="custom-select">
<div class="custom-select__trigger"><span>Tesla</span>
<div class="arrow"></div>
</div>
<div class="custom-options">
<span class="custom-option selected" data-value="tesla">Tesla</span>
<span class="custom-option" data-value="volvo">Volvo</span>
<span class="custom-option" data-value="mercedes">Mercedes</span>
</div>
</div>
</div>
</div>
<script>
Test();
</script>
</body>
</html>
and remove the following piece of code from your script.js page
document.querySelector('button').addEventListener("click", function() {
selectOption(2);
});

Remove CSS applied by a click event

So I'm having trouble toggling this switch to change the background color. Im not sure how to get it to remove the CSS that it applies to the document. I want it to toggle between to different colored backgrounds.
Here's my code:
<!Doctype html>
<html lang="en">
<head>
<link rel="stylesheet" href="styles.css">
</head>
<body>
<div class="container">
<label class="switch"><input id="input" type="checkbox" /><div></div></label>
</div>
<footer>
<script src="https://code.jquery.com/jquery-2.2.1.js"></script>
<script type="text/javascript" src="js.js"></script>
</footer>
</body>
</html>
The Styles:
html {
background: #878476;
}
.container {
position: absolute;
top: 0; right: 0; bottom: 0; left: 0;
height: 40px;
margin: auto;
text-align: center;
}
.switch input {
position: absolute;
opacity: 0;
}
.switch {
display: inline-block;
font-size: 20px; /* 1 */
height: 1em;
width: 2em;
background: #BDB9A6;
border-radius: 1em;
}
.switch div {
height: 1em;
width: 1em;
border-radius: 1em;
background: #FFF;
box-shadow: 0 0.1em 0.3em rgba(0,0,0,0.3);
transition: all 300ms;
transition: all 300ms;
transition: all 300ms;
}
.switch input:checked + div {
transform: translate3d(100%, 0, 0);
transform: translate3d(100%, 0, 0);
transform: translate3d(100%, 0, 0);
}
And the JS:
$(document).ready(function() {
console.log( "Coffee Isn't strong enough for me to remember how to toggle the OnClick" );
$(".switch").on("click", function() {
$("html").css("background", "blue");
});
});
You can use toggle class here is link for more information http://api.jquery.com/toggleclass/
$("#input").on("click", function() {
$("html").toggleClass("bck-change");
});
And also i've modified your code pls refer: https://jsfiddle.net/eLgqe2ya/

Categories

Resources