Javascript Menu : Click on to extend & Click off to shorten - javascript

I created a menu for a web project, but I have a problem with the javascript side. I would like to extend the div container if it's clicked. And vice versa, I would like to shorten it if I click everywhere except on it. Actually, the program is able to shorten and extend the div menu but I can't manage the events :
if div is small -> extend it by clicking on it
if div is big -> shorten it by clicking everywhere except on it
There is my program :
const menu = document.querySelector('.wrapper')
const offClick = () => {
menu.classList.toggle('active')
document.removeEventListener('click', offClick)
}
const handleClick = (e) => {
e.stopPropagation()
menu.classList.toggle('.active')
if (menu.classList.contains('.active')){
document.addEventListener('click', offClick)
}
}
menu.addEventListener('click', handleClick)
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body{
display: flex;
justify-content: center;
align-items: center;
min-height: 100vh;
background-color: #10131c;
}
.wrapper{
position: absolute;
width: 105px;
height: 105px;
background-color: #212532;
border-radius: 10px;
cursor: pointer;
display: flex;
justify-content: center;
align-items: center;
transition: 0.5s;
transition-delay: 0.8s;
}
.wrapper.active{
width: 300px;
height: 300px;
transition-delay: 0s;
}
.wrapper span{
position: absolute;
width: 10.5px;
height: 10.5px;
display: flex;
justify-content: center;
align-items: center;
background-color: #fff;
border-radius: 50%;
transform: translate(calc(18px * var(--x)), calc(18px * var(--y)));
transition: transform 0.5s, width 0.5s, height 0.5s;
background-color: 0.5s;
transition-delay: calc(0.1s * var(--i));
}
.wrapper.active span{
width: 67.5px;
height: 67.5px;
background-color: #333849;
transform: translate(calc(90px * var(--x)), calc(90px * var(--y)))
}
.wrapper span ion-icon{
transition: 0.5s;
font-size: 0em
}
.wrapper.active span ion-icon{
font-size: 2.025em;
color: #fff;
}
.wrapper.active span:hover ion-icon{
color: #d33d32;
filter: drop-shadow(0 0 3px #d33d32)
}
<!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>WebSite</title>
<link rel="stylesheet" href="styles/style.css" type="text/css">
</head>
<body class="body">
<div class="wrapper">
<span style = "--i:0;--x:-1;--y:0;"><ion-icon name="code-outline"></ion-icon></span>
<span style = "--i:1;--x:1;--y:0;"><ion-icon name="moon-outline"></ion-icon></span>
<span style = "--i:2;--x:0;--y:-1;"><ion-icon name="bulb-outline"></ion-icon></span>
<span style = "--i:3;--x:0;--y:1;"><ion-icon name="chatbubbles-outline"></ion-icon></span>
<span style = "--i:4;--x:1;--y:1;"><ion-icon name="duplicate-outline"></ion-icon></span>
<span style = "--i:5;--x:-1;--y:-1;"><ion-icon name="duplicate-outline"></ion-icon></span>
<span style = "--i:6;--x:0;--y:0;"><ion-icon name="ribbon-outline"></ion-icon></ion-icon></span>
<span style = "--i:7;--x:-1;--y:1;"><ion-icon name="rocket-outline"></ion-icon></span>
<span style = "--i:8;--x:1;--y:-1;"><ion-icon name="stats-chart-outline"></ion-icon></span>
</div>
<script type="module" src="https://unpkg.com/ionicons#5.5.2/dist/ionicons/ionicons.esm.js"></script>
<script nomodule src="https://unpkg.com/ionicons#5.5.2/dist/ionicons/ionicons.js"></script>
<script src="script/script.js"></script>
</body>
</html>
Thank you for your help !

Firstly, note that amending event handlers within an event handler is normally a code smell. There is usually a much better way to do what you need to achieve.
In this case you need to attach each of your event handlers just the once. handleClick() should be attached to the .wrapper so that it expands when clicked, and offClick() should be attached to the document so that it contracts the .wrapper.
const menu = document.querySelector('.wrapper');
const offClick = () => menu.classList.remove('active');
const handleClick = (e) => {
e.stopPropagation();
menu.classList.add('active'); // or .toggle('active')
}
menu.addEventListener('click', handleClick);
document.addEventListener('click', offClick);
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
display: flex;
justify-content: center;
align-items: center;
min-height: 100vh;
background-color: #10131c;
}
.wrapper {
position: absolute;
width: 105px;
height: 105px;
background-color: #212532;
border-radius: 10px;
cursor: pointer;
display: flex;
justify-content: center;
align-items: center;
transition: 0.5s;
transition-delay: 0.8s;
}
.wrapper.active {
width: 300px;
height: 300px;
transition-delay: 0s;
}
.wrapper span {
position: absolute;
width: 10.5px;
height: 10.5px;
display: flex;
justify-content: center;
align-items: center;
background-color: #fff;
border-radius: 50%;
transform: translate(calc(18px * var(--x)), calc(18px * var(--y)));
transition: transform 0.5s, width 0.5s, height 0.5s;
background-color: 0.5s;
transition-delay: calc(0.1s * var(--i));
}
.wrapper.active span {
width: 67.5px;
height: 67.5px;
background-color: #333849;
transform: translate(calc(90px * var(--x)), calc(90px * var(--y)))
}
.wrapper span ion-icon {
transition: 0.5s;
font-size: 0em
}
.wrapper.active span ion-icon {
font-size: 2.025em;
color: #fff;
}
.wrapper.active span:hover ion-icon {
color: #d33d32;
filter: drop-shadow(0 0 3px #d33d32)
}
<body class="body">
<div class="wrapper">
<span style="--i:0;--x:-1;--y:0;"><ion-icon name="code-outline"></ion-icon></span>
<span style="--i:1;--x:1;--y:0;"><ion-icon name="moon-outline"></ion-icon></span>
<span style="--i:2;--x:0;--y:-1;"><ion-icon name="bulb-outline"></ion-icon></span>
<span style="--i:3;--x:0;--y:1;"><ion-icon name="chatbubbles-outline"></ion-icon></span>
<span style="--i:4;--x:1;--y:1;"><ion-icon name="duplicate-outline"></ion-icon></span>
<span style="--i:5;--x:-1;--y:-1;"><ion-icon name="duplicate-outline"></ion-icon></span>
<span style="--i:6;--x:0;--y:0;"><ion-icon name="ribbon-outline"></ion-icon></span>
<span style="--i:7;--x:-1;--y:1;"><ion-icon name="rocket-outline"></ion-icon></span>
<span style="--i:8;--x:1;--y:-1;"><ion-icon name="stats-chart-outline"></ion-icon></span>
</div>
<script type="module" src="https://unpkg.com/ionicons#5.5.2/dist/ionicons/ionicons.esm.js"></script>
<script nomodule src="https://unpkg.com/ionicons#5.5.2/dist/ionicons/ionicons.js"></script>
</body>

First of all it looks really nice :)
As far as the javascript code you could keep it simple by adding the event listener on the whole body and checking the target of your click event has a parent with a 'wrapper' class, by using the closest method.
document.addEventListener('click',(event)=>{
if(event.target.closest(".wrapper")){
menu.classList.add('active')
}else{
menu.classList.remove('active')
}
})

Related

How to not activate or to stop animation on small screen

So i have this animation where there is this a h1 and when i scroll down the image zoom out and the h1 follow the image animation, my problem is that when im on mobile or i resize the screen to tablet or mobile i want the animation on scroll to not activate.
i already tried to use the resize function or if screen is > than but it doesn't work i'm using scrollMagic cdn.
animation
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">
<title>Document</title>
<link rel="stylesheet" href="./Css/style.css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/ScrollMagic/2.0.8/ScrollMagic.min.js" integrity="sha512-8E3KZoPoZCD+1dgfqhPbejQBnQfBXe8FuwL4z/c8sTrgeDMFEnoyTlH3obB4/fV+6Sg0a0XF+L/6xS4Xx1fUEg==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/ScrollMagic/2.0.8/plugins/debug.addIndicators.min.js" integrity="sha512-RvUydNGlqYJapy0t4AH8hDv/It+zKsv4wOQGb+iOnEfa6NnF2fzjXgRy+FDjSpMfC3sjokNUzsfYZaZ8QAwIxg==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.9.1/gsap.min.js"></script>
<script src="https://code.jquery.com/jquery-3.6.0.js" integrity="sha256-H+K7U5CnXl1h5ywQfKtSj8PCmoN9aaq30gDh27Xc0jk=" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/ScrollMagic/2.0.8/plugins/animation.gsap.js" integrity="sha512-judXDFLnOTJsUwd55lhbrX3uSoSQSOZR6vNrsll+4ViUFv+XOIr/xaIK96soMj6s5jVszd7I97a0H+WhgFwTEg==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
</head>
<body class="contenet">
<div class="overflow-wrap">
<header id="header">
<img src="./Asset/Img/1.png" loading="lazy" alt="" id="hero-ui">
<div class="container container--hero">
<div class="hero__header">
<h1 class="hero-heading">The Webflow Expert.</h1>
</div>
</div>
</header>
</div>
<section class="section section--manifest">
<div class="section-header section-header--intro">
<h2 class="fluid-gradient-heading fluid-gradient-heading--hero cc-en">World-class Webflow<br>sites for ambitious<br>companies.</h2>
</div>
</section>
<script src="./JS/app.js"></script>
</body>
</html>
CSS
* {
margin: 0;
padding: 0;
box-sizing: border-box;
scroll-behavior: smooth;
}
*::-webkit-scrollbar {
display: none;
}
body {
background-color: #1d1d1f;
color: white;
font-family: Inter, sans-serif;
-ms-overflow-style: none;
/* IE and Edge */
scrollbar-width: none;
/* Firefox */
}
#header {
display: flex;
height: 100vh;
align-items: center;
position: sticky;
backface-visibility: hidden;
transform: translate3d(0, 0, 0) scale3d(1, 1, 1);
transform-style: preserve-3d;
}
.overflow-wrap {
overflow: hidden;
height: 100%;
}
#hero-ui {
position: relative;
left: 50%;
z-index: 1;
width: 16.9em;
max-width: none;
margin-top: 3.2em;
margin-left: -8.45em;
font-size: 10vw;
opacity: 0;
}
.hero-heading {
will-change: transform, opacity;
animation: fadeIn 0.8s ease;
animation-iteration-count: 1;
animation-fill-mode: backwards;
animation-delay: 0.5s;
font-size: 92px;
}
.container.container--hero {
position: absolute;
left: 0;
top: 0;
right: 0;
bottom: auto;
display: flex;
height: 100vh;
max-width: none;
padding-top: 100px;
padding-bottom: 100px;
flex-direction: column;
justify-content: center;
align-items: center;
text-align: center;
z-index: 2;
}
.section.section--manifest {
padding-top: 100px;
padding-bottom: 160px;
}
.section-header.section-header--intro {
position: relative;
max-width: 1050px;
margin-bottom: 0;
}
.section-header {
width: 90%;
max-width: 980px;
margin-right: auto;
margin-bottom: 142px;
margin-left: auto;
text-align: left;
}
.fluid-gradient-heading.fluid-gradient-heading--hero.cc-en {
font-size: 103px;
}
.fluid-gradient-heading.fluid-gradient-heading--hero {
margin-right: auto;
margin-left: auto;
line-height: 1.05;
text-align: center;
}
.fluid-gradient-heading {
background: linear-gradient(91.36deg, #ECA658 0%, #F391A6 13.02%, #E188C3 25.52%, #A58DE3 37.5%, #56ABEC 49.48%, #737EB7 63.02%, #C8638C 72.92%, #DD5D57 84.38%, #DF6C51 97.92%);
background-size: 200% 200%;
-webkit-background-clip: text;
background-clip: text;
-moz-background-clip: text;
-webkit-animation: intro-gradient 10s infinite ease both;
-moz-animation: intro-gradient 10s infinite ease both;
animation: intro-gradient 10s infinite ease both;
}
.fluid-gradient-heading {
margin-top: 0;
padding-top: 8px;
padding-bottom: 8px;
font-size: 92px;
line-height: 1.1;
letter-spacing: -.045em;
-webkit-background-clip: text;
background-clip: text;
-webkit-text-fill-color: transparent;
}
h2 {
margin-top: 20px;
margin-bottom: 10px;
font-size: 32px;
line-height: 36px;
font-weight: 600;
}
JAVASCRIPT
/*==================== zoom out image ====================*/
let controller = new ScrollMagic.Controller();
let zoomHeader = TweenMax.to("#header", 0.9, { opacity: 1, scale: 0.35, ease: Circ.EaseIn });
let headerZoom = new ScrollMagic.Scene({
triggerElement: "#header",
triggerHook: 0,
duration: "3000ms"
})
.setPin('#header')
.setClassToggle('#header')
.setTween(zoomHeader)
.addTo(controller);
/*==================== smooth link scrooling====================*/
let $root = $('html, body');
$('a[href^="#"]').click(function() {
$root.animate({
scrollTop: $($.attr(this, 'href')).offset().top
}, 500);
return false;
});
/*==================== Change opacity image ====================*/
$(window).scroll(function() {
let scrollTop = $(this).scrollTop();
$('#hero-ui').css({
opacity: function() {
let elementHeight = $(this).height();
return 1 - (elementHeight - scrollTop) / elementHeight;
}
});
});
In your scroll event listener you may check actual device width.
Then you can disable animation when it is mobile.
Smth like
$(window).scroll(function() {
if($(window).width() < 500) return
.....
}
You can apply the same check for click event.
Also it will be good if you handle resize/load events as well.

How to hide a div with javascript depending on screen size after scrolling

I have a fixed div element and I want to hide it after scrolling for a width smaller than 767px. With media queries, I can do this when the width is smaller than 767px but I want to trigger the display: hidden after scrolling.
How can I do it?
body {
background: #000;
}
#magic {
position: fixed;
z-index: 999999;
top: 50px;
margin-bottom: 20px;
margin-right: 50px;
display: flex;
}
#music {
position: fixed;
z-index: 999999;
top: 50px;
margin-bottom: 20px;
margin-right: 300px;
display: flex;
}
.play {
display: flex;
min-width: 5px;
height: 31px;
width: 11px;
text-align: left;
padding: 0px 10px;
background: #fff;
/* player background */
border-left: 3px solid #16090F;
/* player border */
color: #B5A7BA;
opacity: 1;
-webkit-transition: all .4s ease;
-moz-transition: all .4s ease;
-o-transition: all .4s ease;
transition-delay: .4s;
-webkit-transition-delay: .4s;
border-radius: 100%;
}
#media (max-width: 767px) {
#music {
top: -550px;
margin-bottom: 20px;
margin-right: 350px;
display: flex;
}
#magic {
margin-right: 30px;
}
}
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1">
<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.css" rel="stylesheet">
</head>
<body>
<div id="magic">
<a href="#" style="text-decoration: none; color: #fff; font-size: 10px;">
<i class="fa fa-snowflake-o fa-2x" style="color:#eee" aria-hidden="true"></i> Magic</a>
</div>
<div id="music">
<div class="roundthing">
</div>
<div class="play"></div>
</div>
</body>
</html>
I wrote the part of the code related to those fixed elements but feel free to use anything.
Thanks in advance!
You can listen to a scroll event and run the check below
if (window.matchMedia('screen and (max-width: 767px)').matches) {
// hide the element here
}
Take a look at How to hide a div wih jQuery dependant on screen size
You can use innerWidth and write a statement that if the width of the client is lower equal to 768, after scrolling, hide the element. else(width more equal to 769): show element.
I also used IIFE Function. That helps us after loading the page, it runs immediately and you won't need any other action or call to run the function.
(function () {
const section = document.querySelector('section');
window.addEventListener('scroll', () => {
window.innerWidth <= 768 ? section.style.opacity = 0 : section.style.opacity = 1;
}
)
})();
body {
height: 200vh
}
section {
width: 300px;
height: 200px;
background-color: orange;
}
<section></section>
It can be quite overheady listening for the scroll event, especially as in this case we are only interested when the user has moved down from (or back up to) the top.
This snippet uses a different method. It places a tiny div at the top of the page and sets an intersection observer on it. When it is in the viewport we know that we want to show magic whatever the width of the viewport so we set the visibility of magic to visible.
However, when it goes out of the viewport that means the user has scrolled and we set the visibility of magic to var(--visibility). --visibility is set to visible for larger viewport widths, and through a media query is set to hidden for widths under 768 - so magic will disappear. It will reappear if the user scrolls to the top or the viewport is widened (e.g. by the user altering the window size or maybe going to landscape mode on some devices).
This way we avoid the overhead of having to look at all scroll events and there is no need to look for the resize event either.
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1">
<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.css" rel="stylesheet">
<style>
body {
background: #000;
height: 300vh;
/* just so we can scroll for the testing */
}
#sensor {
/* when this goes out of view we are deemed to have scrolled */
position: absolute;
top: 0;
left: 0;
width: 1px;
height: 20px;
}
#magic {
position: fixed;
z-index: 999999;
top: 50px;
margin-bottom: 20px;
margin-right: 50px;
display: flex;
visibility: visible;
/* this will get changed to var(--visibility) after a scroll on any width of device */
--visibility: visible;
/* this will get changed by CSS stylesheet media query on a narrow device */
}
#music {
position: fixed;
z-index: 999999;
top: 50px;
margin-bottom: 20px;
margin-right: 300px;
display: flex;
}
.play {
display: flex;
min-width: 5px;
height: 31px;
width: 11px;
text-align: left;
padding: 0px 10px;
background: #fff;
/* player background */
border-left: 3px solid #16090F;
/* player border */
color: #B5A7BA;
opacity: 1;
-webkit-transition: all .4s ease;
-moz-transition: all .4s ease;
-o-transition: all .4s ease;
transition-delay: .4s;
-webkit-transition-delay: .4s;
border-radius: 100%;
}
#media (max-width: 767px) {
#music {
top: -550px;
margin-bottom: 20px;
margin-right: 350px;
display: flex;
}
#magic {
margin-right: 30px;
--visibility: hidden;
}
}
</style>
</head>
<body>
<div id="sensor"></div>
<div id="magic">
<a href="#" style="text-decoration: none; color: #fff; font-size: 10px;">
<i class="fa fa-snowflake-o fa-2x" style="color:#eee" aria-hidden="true"></i> Magic</a>
</div>
<div id="music">
<div class="roundthing">
</div>
<div class="play"></div>
</div>
<script>
let callback = (entries, observer) => {
entries.forEach(entry => {
if (entry.isIntersecting) {
// we are at the top of the page so haven't scrolled (or have scrolled right back up)
magic.style.visibility = 'visible'; //make magic element visible
} else {
magic.style.visibility = 'var(--visibility)';
}
});
};
const sensor = document.querySelector('#sensor');
const observer = new IntersectionObserver(callback);
const magic = document.querySelector('#magic');
observer.observe(sensor);
</script>
</body>
</html>
There are two options.
Listen to scroll event and then check the screen size
Listen to resize event, check the screen size and then listen to scroll event.
It is better to use the second option as resize triggers less frequently than scroll.
let element = document.querySelector('#magic')
window.addEventListener('resize', check)
check()
function check() {
if (window.matchMedia('screen and (max-width: 767px)').matches)
document.addEventListener('scroll', hide)
}
function hide() {
element.style.display = 'none'
}
body {
height: 1000px;
background: #000;
}
#magic {
position: fixed;
z-index: 999999;
top: 50px;
margin-bottom: 20px;
margin-right: 50px;
display: flex;
}
#music {
position: fixed;
z-index: 999999;
top: 50px;
margin-bottom: 20px;
margin-right: 300px;
display: flex;
}
.play {
display: flex;
min-width: 5px;
height: 31px;
width: 11px;
text-align: left;
padding: 0px 10px;
background: #fff;
/* player background */
border-left: 3px solid #16090F;
/* player border */
color: #B5A7BA;
opacity: 1;
-webkit-transition: all .4s ease;
-moz-transition: all .4s ease;
-o-transition: all .4s ease;
transition-delay: .4s;
-webkit-transition-delay: .4s;
border-radius: 100%;
}
#media (max-width: 767px) {
#music {
top: -550px;
margin-bottom: 20px;
margin-right: 350px;
display: flex;
}
#magic {
margin-right: 30px;
}
}
<head>
<meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1">
<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.css" rel="stylesheet">
</head>
<body>
<div id="magic">
<a href="#" style="text-decoration: none; color: #fff; font-size: 10px;">
<i class="fa fa-snowflake-o fa-2x" style="color:#eee" aria-hidden="true"></i> Magic</a>
</div>
<div id="music">
<div class="roundthing">
</div>
<div class="play"></div>
</div>
</body>

How to cut exceeded content of div inside another div?

I'm trying to create a "bubble" which gets bigger in order to change its parent color with a nice animation. I like my approach, but I only need to put it inside the parent div.
This is what I have:
HTML
<html>
<body>
<div class="nav-menu" style="top: -64px;">
<div class="test"></div>
<div class="brand" onclick="test();">
<h1>App</h1>
</div>
<ul class="menu-list">
<li class="menu-item">Item</li>
</ul>
</div>
</body>
</html>
CSS
#import url('https://fonts.googleapis.com/css2?family=Satisfy&display=swap');
* {
margin: 0;
padding: 0;
}
.nav-menu {
z-index: 1000;
padding: 0 16px;
display: flex;
justify-content: space-between;
background-color: #B67171;
color: white;
position: fixed;
width: 100%;
transition: background-color .5s, top .2s;
}
.test {
background-color: blue;
position: absolute;
border-radius: 50%;
z-index: -1;
width: 32px;
height: 32px;
left: 50%;
top: 50%;
transform: scale(0) translate(-50%, -50%);
transform-origin: top left;
transition: transform .25s;
}
.nav-menu .brand h1 {
margin: 0;
padding: 0;
line-height: 64px;
font-family: 'Satisfy', cursive;
}
.nav-menu .menu-list {
list-style: none;
margin: 0;
}
.nav-menu .menu-list a {
display: inline-block;
margin: 0;
padding: 0 16px;
line-height: 64px;
font-size: 21px;
vertical-align: middle;
transition: background-color .2s;
color: white;
text-decoration: none;
}
.nav-menu .menu-list a:hover {
background-color: #D8C292;
}
(And a .js just for testing)
let navMenu = document.getElementsByClassName("nav-menu")[0];
window.addEventListener('load', function (e) { navMenu.style.top = "0"; });
var showing = false;
function test () {
document.getElementsByClassName("test")[0].style = "transform: scale(" + (showing ? 0 : 4) + ") translate(-50%, -50%);";
showing = !showing;
}
Here you have a demo in which you can press the "App" text and it would scale the "bubble" just a little bit. I want to remove the following stuff:
Can anybody give me a hint? However if you know any better solution for this "feature", I will appreciate it.
Thank you in advance!
Adding overflow:hidden property to your navigation div would work. Try this code.
.nav-menu {
z-index: 1000;
padding: 0 16px;
display: flex;
justify-content: space-between;
background-color: #B67171;
color: white;
position: fixed;
width: 100%;
transition: background-color .5s, top .2s;
overflow: hidden;
}
Add to .navmenu property overflow
DOC: overflow
nav-menu {
...
overflow: hidden;
}
Simply add overflow: hidden; to your div with class nav-menu.
Here is your edited example: https://jsfiddle.net/4r1n2cux/2/
use overflow: hidden; in style of first <div>

Navigation bar isn't being responsive in the phone view

I am a beginner in web design and development and I am trying to make the navigation bar be more responsive when it is viewed on phones and tablets but for some reason it appears really buggy on the phone, I have used a meta tag so that the browser renders it correctly but it doesn't, it comes out all buggy like the picture below:
Click on the link to see picture -> As you can see it's coming out half and half
I have enabled overflow-x:hidden but some how am still able to browse towards the right and see the nav bar which isn't meant to be visible unless clicked, I don't understand why that's happening.
Click on the link to see picture -> This is how it is when you load it.
I have also tried to put the screen resolution as follows:
`#media screen and (max-width:1024px){
.nav-links
{
width:48%;
}
}
#media screen and (max-width:768px)`
This is also running on my firebase server and is available to view through this link:https://test-response-5f60c.web.app/PAGES/quotes.html
I am sorry for any code inconsistencies and mistakes, please help me out, I don't understand what I am doing wrong in the CSS. This is the tutorial I followed: Click on the link -> Tutorial
Following is my code:
function navSlide() {
const burger = document.querySelector(".burger");
const nav = document.querySelector(".nav-links");
const navLinks = document.querySelectorAll(".nav-links li");
burger.addEventListener("click", () => {
//Toggle Nav
nav.classList.toggle("nav-active");
//Animate Links
navLinks.forEach((link, index) => {
if (link.style.animation) {
link.style.animation = ""
} else {
link.style.animation = `navLinkFade 0.5s ease forwards ${index / 7 + 0.5}s`;
}
});
//Burger Animation
burger.classList.toggle("toggle");
});
}
navSlide();
*{
margin: 0;
padding: 0;
box-sizing: border-box;
}
body{
margin: 0;
}
nav{
display: flex;
justify-content: space-around;
align-items: center;
min-height: 8vh;
background-color: #000000;
color: #f9f9f9;
font-family: 'Open Sans', sans-serif;
font-size: large;
}
.logo{
text-transform: uppercase;
letter-spacing: 3px;
font-size: 20px;
}
.nav-links {
list-style-type: none;
padding: 1.2%;
margin:0;
overflow: hidden;
background-color: #000000;
display: flex;
align-items: center;
justify-content: center;
}
.nav-links li a {
font-size: 18px;
font-weight: bold;
display: inline-block;
color: white;
text-align: center;
padding: 26px 26px;
text-decoration: none;
transition: 0.3s;
}
li a:hover {
background-color: #3498DB ;
}
.burger{
display: none;
cursor: pointer;
}
.burger div{
width: 25px;
height: 4px;
background-color: #f9f9f9;
margin: 5px;
}
.head {
font-family: sans-serif;
font-weight: bold;
margin: auto;
width: 60%;
border: 3px solid #3498DB ;
padding: 40px;
text-align: center;
opacity: 5.9;
animation-duration: 3s;
animation-name: fadein;
}
#media screen and (max-width:1024px){
.nav-links{
width:48%;
}
}
#media screen and (max-width:768px){
body {
overflow-x: hidden !important;
}
.nav-links{
position: absolute;
right: 0;
height: 92vh;
top: 8vh;
background-color: #000000;
display: flex;
flex-direction: column;
align-items:center;
width: 50%;
transform: translate(100%);
transition: transform 0.5s ease-in;
}
.nav-links li{
opacity: 0;
}
.burger{
display: block;
}
.nav-active {
transform: translate(0%);
}
}
#keyframes navLinkFade {
from{
opacity: 0;
transform: translateX(50px);
}
to{
opacity: 1;
transform: translateX(0px);
}
}
.toggle .line1 {
transform: rotate(-45deg) translate(-5px, 6px);
}
.toggle .line2 {
opacity: 0;
}
.toggle .line3 {
transform: rotate(45deg) translate(-5px, -6px);
}
#googleForm {
margin-left: 20px;
text-align: center;
margin-top: 20px;
}
<!doctype html>
<html>
<head>
<style>
body {
background-image: url('../IMG/land2.jpg');
height: 100%;
background-position: center;
background-repeat: no-repeat;
background-size: auto ;
}
</style>
<title> Quotes </title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" type="text/css" href="../CSS/style.css">
<link rel="preconnect" href="https://fonts.gstatic.com">
<link href="https://fonts.googleapis.com/css2?family=Open+Sans&display=swap" rel="stylesheet">
</head>
<body>
<nav>
<div class="logo">
<h4> Edge Concreting and Landscaping </h4>
</div>
<ul class="nav-links">
<li>Home</li>
<li>Quotes</li>
<li>Contact</li>
</ul>
<div class="burger">
<div class="line1"></div>
<div class="line2"></div>
<div class="line3"></div>
</div>
</nav>
<div id="googleForm">
<iframe src="https://docs.google.com/forms/d/e/1FAIpQLSd5uy_5vc6ozsY1kcGRliC8hYH9w_WqEU1acN0tJQ6rrqEJmg/viewform?embedded=true" width="640" height="1427" frameborder="0" marginheight="0" marginwidth="0">Loading…</iframe>
</div>
<script src="../JS/app.js"></script>
</body>
</html>
Set your media queries to a lower max width and position absolute.
For example.
#media (max-width: 768px){.logo h4 {position: absolute;
right: 50px;}}
That should enable you to select your logo and adjust it for mobile device.
#media (max-width: 768px){.nav-links{position: absolute;
right: 50px;}}
Should enable you to select and adjust your dropdown. You can change or substitute rightor left or top or bottom or width within the same media query.
Try reducing the width of nav-links.
This worked for me:
html, body {
overflow-x: hidden;
}
body {
position: relative;
}

Navbar is not hiding on scroll using javascript

I'm struggling to hide the navbar on scroll down. I know how to do it, but just because of some silly mistake I'm unable to do so, and can't figure out what the issue is.
Here's the html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="style.css">
<title>Document</title>
</head>
<body>
<div id="navbar">
<div id="logo">
<a href="#">
<h1>My logo</h1>
</a>
</div>
<ul id="menu">
<li><a class="link-button" href="#">HOME</a></li>
<li><a class="link-button" href="#">ARTICLES</a></li>
<li><a class="link-button" href="#">PROJECTS</a></li>
<li><a class="link-button" href="#">AUTHOR</a></li>
<li><a class="link-button" href="#">CONTACT</a></li>
</ul>
</div>
<div id="welcome">
<h1 id="welcome-text">My Portfolio</h1>
</div>
<div class="container">
</div>
<!-- Here script for hidding navbar on scroll down -->
<script>
window.addEventListener("scroll", function(){
let Navbar = document.getElementById('navbar');
if(window.pageYOffset > 0){
Navbar.classList.add("navbar-scroll");
}else{
Navbar.classList.remove("navbar-scroll");
}
});
</script>
</body>
</html>
And here's the full css
*{
margin: 0;
padding: 0;
box-sizing: border-box;
font-family: sans-serif;
}
body{
height: 100vh;
perspective: 1px;
transform-style: preserve-3d;
overflow-x: hidden;
overflow-y: auto;
}
html{
overflow: hidden;
}
#navbar{
position: sticky;
width: 100%;
top: 0;
transition: background 0.5s;
background-color: transparent;
z-index: 2;
}
#navbar #logo{
float: left;
margin: 10px;
}
#navbar #logo a{
font-size: 155%;
color: #ffffff;
text-decoration: none;
}
#navbar ul{
float: right;
justify-content: space-around;
list-style: none;
align-items: center;
padding: 20px;
}
#navbar ul li{
display: inline-block;
}
/* === Here I'm changing the display property of the navbar to none to make it disappear. === */
#navbar.navbar-scroll{
display: none;
}
.link-button{
display: block;
text-align: center;
margin: 0 15px;
font-size: 89%;
color: #ffffff;
text-decoration: none;
}
.link-button::after{
content: '';
display: block;
width: 0;
height: 2px;
margin-top: 2px;
background: #ffffff;
transition: width .3s;
}
.link-button:hover::after{
width: 100%;
transition: width .3s;
}
#welcome{
height: 100vh;
width: 100vw;
box-sizing: border-box;
}
#welcome::before{
content: "";
height: 100vh;
width: 100vw;
top: 0;
left: 0;
background: linear-gradient(#0000008e, #0000008e), url('static/bc22.jpg');
background-position: center;
-webkit-background-size: cover;
-moz-background-size: cover;
-o-background-size: cover;
background-size: cover;
position: absolute;
z-index: -1;
transform: translateZ(-2px) scale(3);
}
#welcome-text{
color: #ffffff;
position: absolute;
top: 50%;
left: 26%;
transform: translate(-50%, -50%);
/* text-align: center; */
font-size: 600%;
}
.container{
background-color: #1f1f1f;
height: 1000px;
}
In the CSS I've also tried changing the background colour of the navbar on scroll (in the #navbar.navbar-scroll), but it ain't working as well. So most probably the error is in the javascript I think.
If there's a better way of hiding the navbar on scroll then that's welcomed as well.
Thanks for your time.
Actually the problem lies under your HTML overflow: hidden;. So when you set your HTML overflow to hidden, the window.addEventListener("scroll", function () {}) will never invoke, because window will never scroll at all. So to fix this you should either remove html{overflow: hidden;} from your styles or add your event listener to listen to your body element instead, which is not recommended.
From your CSS, it seems your goal is to have the body as the scroll container and not <HTML> itself.
Something like this should work as your JavaScript:
document.body.addEventListener("scroll", function(){
let Navbar = document.getElementById('navbar');
if(document.body.scrollTop > 0){
Navbar.classList.add("navbar-scroll");
}else{
Navbar.classList.remove("navbar-scroll");
}
});
Pretty much every tag which can have children can be scrollable if you define it in your CSS. That means you will have to listen to the right element in JS too.

Categories

Resources