Navbar is not hiding on scroll using javascript - 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.

Related

How do I prevent elements with absolute position from overflowing?

I have attached a simple code snippet for a website. When hovering over the underlined words, images are supposed to appear. How can I prevent those images from "jumping out" of their container so that they will always be visible and don't leave the screen?
The images are supposed to appear at the position of the correlating word.
I hope you understand the problem I've described here.
#charset "UTF-8";
/* CSS Document */
html, body {
margin: 0;
background-color: black;
}
#wrapper {
margin: 0;
position: fixed;
width: 100%;
height: 100%;
overflow: scroll;
}
.section {
width: 100%;
height: 100%;
display: flex;
flex-direction: column;
align-content: center;
align-items: center;
justify-content: center;
text-align: left;
position: relative;
}
p {
color: white;
font-family: Helvetica, sans-serif;
font-size: 36px;
margin-left: 100px;
margin-right: 100px;
text-align: left;
display: block;
width: 50%;
}
.gallery-image {
position: absolute;
display: none;
transform: translate(0,calc(1em - 50%));
max-width: 50vw;
max-height: 75vh;
height: auto;
z-index: 1000;
}
.gallery-link {
position: relative;
text-decoration: underline;
}
.gallery-link:hover > .gallery-image{
display: flex;
z-index: 1000;
}
<!doctype html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
<link href="styles.css" rel="stylesheet" type="text/css">
</head>
<body>
<div id="wrapper">
<div class="section">
<p>Title<br>
Nor is there anyone who loves or pursues or desires to obtain pain of itself, because it is pain
<span class="gallery-link"><img class="gallery-image" src="https://upload.wikimedia.org/wikipedia/commons/a/a0/590_Madison_Ave_IBM_08.jpg" >
vulnerability </span> of any.<br>
The once <span class="gallery-link">colorful rug<img class="gallery-image" src="https://upload.wikimedia.org/wikipedia/commons/thumb/7/7c/Ornamentglas_B_-_Ansicht_1.jpg/1000px-Ornamentglas_B_-_Ansicht_1.jpg"></span> has been <span class="gallery-link">broken down<img class="gallery-image" src="https://upload.wikimedia.org/wikipedia/commons/4/4a/Cocooningâ“’Shin%2C_Kyungsub.jpg" ></span> but is there anyone who loves or pursues or desires to obtain pain of itself, because it is pain.<br>
End Quote
</p>
</div>
</div>
</body>
</html>
You can try to modify your .gallery-image with top and remove transform too. Your final CSS will be like this
.gallery-image {
position: absolute;
display: none;
max-width: 50vw;
max-height: 75vh;
height: auto;
z-index: 1000;
top: 100%; /*Here is the main change*/
}
You can check the sandbox here https://jsfiddle.net/kqoh2Lat/
The final result

Entire Nav disappearing on refresh for safari

My issue right now with this is on safari (yes, I know not many people will use this browser but I want maximum usability, and the nav disappearing is a weird problem), chrome and firefox work perfectly fine but it's just safari that is the oddball. What should be happening is what happens in the code snippet, but when I shorten the page (say so a mobile device size), refresh, and open it back up, my whole nav dissapears.
Picture of disappeared nav
$(document).ready(function() {
const ulNav = document.querySelector(".ul-navbar");
const navButt = document.querySelector(".nav-toggle");
//on click visibility is checked, if its "false", the data-visible attribute in css would be set to true and if its "true" it would be set to false.
navButt.addEventListener("click", () => {
const vis = ulNav.getAttribute("data-visible");
console.log(vis);
if (vis === "false") {
ulNav.setAttribute("data-visible", true);
} else {
ulNav.setAttribute("data-visible", false);
}
});
});
:root {
--background: rgba(50, 135, 242, 0.8);
}
*,
*::before,
*::after {
box-sizing: border-box;
}
body {
padding: 0;
margin: 0;
background-color: lightblue;
font-family: serif, sans-serif;
font-weight: 400;
display: grid;
grid-template-rows: min-content 1fr;
overflow-x: hidden;
}
/* logo-work */
.img {
height: 50px;
width: 50px;
}
.logo {
margin: 2rem;
}
/* nav starts here */
.ul-navbar {
display: block;
padding: 0;
margin: 0;
text-align: left;
position: relative;
width: 100%;
z-index: 999;
list-style: none;
background-color: hsl(0 0% 0%/ 0.3);
visibility: visible;
}
.nav-toggle {
display: none;
}
#supports (backdrop-filter: blur(1rem)) {
.ul-navbar {
background-color: hsl(0 0% 100%/ 0.1);
backdrop-filter: blur(1rem);
}
}
/* login */
.login {
position: absolute;
right: 30px;
top: -32px;
}
.formDiv {
position: absolute;
top: 50%;
left: 30%;
display: flex;
align-items: centeR;
}
/* rest of navbar */
.ul-navbar li {
margin-left: 1em;
}
.ul-navbar a {
color: darkgreen;
text-decoration: none;
font-size: 1.2rem;
text-transform: uppercase;
}
.ul-navbar a:hover,
.ul-navbar a:focus {
color: #222;
}
.flex {
display: flex;
}
/* p-head */
.primary-header {
align-items: center;
justify-content: space-between;
}
/* for mobile devices */
#media (max-width: 40em) {
.ul-navbar {
position: fixed;
z-index: 1000;
top: 0;
bottom: 0;
right: 0;
left: 30%;
flex-direction: column;
padding: min(30vh, 10rem) 2rem;
transform: translateX(100%);
}
/* what the javscript should be changing */
.ul-navbar[data-visible="true"] {
visibility: visible;
transform: translateX(0%);
}
.nav-toggle {
display: block;
position: absolute;
z-index: 9999;
background: lightgreen;
background-repeat: no-repeat;
width: 2rem;
height: 2rem;
top: 2rem;
right: 2rem;
}
.login {
position: absolute;
right: 500px;
}
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Jonathan's Homepage</title>
<meta name="viewport" content="width=device-width,initial-scale=1">
<link rel="stylesheet" type="text/css" href="index.css" />
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
<script src="nav.js" defer></script>
</head>
<body>
<header class="primary-header flex">
<div class="logo">
<a href="index.html">
<img class="img" src="./imges/beatlejuce.png" alt="logo">
</a>
</div>
<button class="nav-toggle" aria-controls="ul-nav" aria-expanded="false">=</button>
<nav>
<ul id="ul-nav" data-visible="false" class="ul-navbar flex">
<li>home</li>
<li>code</li>
<li>photography</li>
<li>random</li>
<li><button onclick="location.href = 'login.html';" id="login" class="login">Login</button></li>
</ul>
</nav>
</header>
</body>
</html>
You may need to use the correct vendor prefix for Safari. For Safari it is -webkit-. Here's a link to the MDN page on vendor prefixes:
https://developer.mozilla.org/en-US/docs/Glossary/Vendor_Prefix
Here's the correct media query that worked for me tested in JS fiddle:
#-webkit-media(){}

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;
}

How do I make two unordered list fade in and fade out when my menu is clicked depending on which is showing?

I have a menu made with 3 div's nested in one div, that I am trying to have two different unordered list fade in or fade out depending on which one is showing when it is clicked. It almost works, however after i click on the menu the first time, every other time both list fade in together instead of just one.
HTML and CSS are good, but in js I've tried several variations of code to get it working, but this is the closest I can get it to work.
$(document).on('click','.menu', function()
{
$(".pagelinks").fadeOut('slow', function(){
$(".homelinks").fadeIn('slow');
});
});
$(document).on('click','.menu', function()
{
$(".homelinks").fadeOut('slow', function(){
$(".pagelinks").fadeIn('slow');
});
});
html,body
{
margin:0;
width: 100%;
overflow:hidden;
box-sizing: border-box;
height: 100%;
}
body
{
background: url(best8.jpg);
background-repeat:no-repeat;
background-size:cover;
background-position: center;
}
header
{
width: 100%;
background-color: black;
height: 85px;
position: fixed;
}
h1
{
color:white;
position: relative;
align-content: center;
margin: 3em ;
top: 100px;
left: 595px;
}
.logo img
{
left: 0;
filter: brightness 100%;
position: fixed;
}
.menu
{
margin: auto;
margin-left: 77%;
display: block;
position: fixed;
top: 11px;
}
.nav div
{
height: 5px;
background-color: white;
margin: 4px 0;
border-radius: 25px;
transition: 0.3s;
}
.nav
{
width: 30px;
display: block;
margin: 1em 0 0
}
.one
{
width: 30px;
}
.two
{
width: 20px;
}
.three
{
width: 25px;
}
.nav:hover div
{
width: 30px;
}
.nav:hover{
cursor: pointer;
}
.pagelinks
{
margin: auto;
margin-left: 37%;
position: fixed;
top: -10px;
display: none;
}
.pagelinks ul
{
list-style-type: none;
}
.pagelinks ul li
{
float: left;
padding:30px;
margin: auto;
color: white;
font-size: 20px;
font-weight: bold;
padding-top: 40px;
opacity: 0.6;
}
.pagelinks ul li:hover
{
color: green;
transition: 0.6s;
}
.logo img:hover
{
opacity: 0.6;
}
.homelinks
{
margin: auto;
margin-left: 54%;
position: fixed;
top: -10px;
display: block;
}
.homelinks ul
{
list-style-type: none;
}
.homelinks ul li
{
display:inline-block;
padding:30px;
margin: auto;
color: white;
font-size: 20px;
font-weight: bold;
padding-top: 40px;
}
.homelinks ul li:hover
{
color: deepskyblue;
transition: 0.6s;
}
<!DOCTYPE html>
<html>
<head>
<title>Goesta Calculators</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link href="style.css" rel="stylesheet" type="text/css">
<script type="text/javascript" src="main.js" async></script>
<script src="https://use.typekit.net/axs3axn.js"></script>
<script>try{Typekit.load({ async: true});}catch(e){}</script>
<!-- Latest compiled and minified CSS -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css">
<!-- jQuery library -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<!-- Popper JS -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js"></script>
<!-- Latest compiled JavaScript -->
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js"></script>
</head>
<body>
<header>
<div class="container">
<div class="row">
<img src="NewLogo.PNG" >
<div class="menu">
<div class="nav">
<div class="one"></div>
<div class="two"></div>
<div class="three"></div>
</div>
</div>
<nav class="pagelinks">
<ul>
<li>Mortgage</li>
<li>Auto</li>
<li>Personal</li>
<li>Refinance</li>
<li>Investment</li>
</ul>
</nav>
</div>
<nav class="homelinks">
<ul>
<li>Home</li>
<li>About</li>
<li>Contact</li>
</ul>
</nav>
</div>
<script src="main.js"></script>
</header>
<div>
<h1>Estimate. Plan your future.</h1>
</div>
</body>
</html>
This looks like a situation in which you could use the toggleClass() function. Create and apply a .visible class on one of the <nav> elements. On the click event, do something like $('nav').toggleClass('visible'). See https://api.jquery.com/toggleClass/.
This is just the asynchronous nature of Javascript. What's happening is when you click the '.menu' for the first time two callback functions are called which get stacked in the event loop and when they execute '.homelinks' and '.pagelinks' both fade in.
What you need to do is simply give a class named 'visible' to any one of the two ('.homelinks' or '.pagelinks') and in your function just check for the element with visible class - fade this element out and fade the other one in and after that toggle visible class to the other element and remove visible class from original element.
For instance
initially - '.homelinks' has visible
'.pagelinks' does not have it
Now on click event
fadeout - element with visible class ('.homelinks')
fadein - the other element ('.pagelinks')
remove - visible class from '.homelinks'
add - visible class to '.pagelinks'
Here check this out in Codepen
$('.menu').click(function()
{
console.log("clickk");
let pl = $('.pagelinks');
let hl = $('.homelinks');
if(pl.hasClass('visible')){
pl.fadeOut('slow',function(){
hl.toggleClass('visible');
pl.toggleClass('visible');
hl.fadeIn('slow',function(){});
});
}else{
hl.fadeOut('slow',function(){
hl.toggleClass('visible');
pl.toggleClass('visible');
pl.fadeIn('slow',function(){});
});
}
});

Div and ul list side by side

I am trying to place a ul list at the side of a div. The ul should begin at the right side and at the top of the div, and end on the bottom side of the div.
The problem is that it starts at the bottom of the div, not at the top of it. How can I fix it?
This is my code:
$(document).ready(function() {
$("#map").prepend('<img src="images/d2.png">');
var width = $("#map > img").attr("width");
$("#actions").css("width", width);
});
body {
margin: 0;
padding: 0;
}
nav {
-webkit-transition: width 0.3s;
-moz-transition: width 0.3s;
-o-transition: width 0.3s;
transition: width 0.3s;
position: fixed;
height: 100%;
width: 60px;
background: blue;
z-index: 1;
}
nav:hover {
width: 200px;
}
div#painel {
padding-left: 60px;
background: red;
width: calc(100%-60px);
display: block;
z-index: 0;
text-align: center;
}
div#map-container {
padding: 20px 0 20px;
width: 100%;
background: green;
text-align: center;
}
#map-interface,
div#map {
display: inline-block;
border: 0;
padding: 0;
margin: 0;
}
#map-interface {
background: gray;
list-style: none;
margin-left: -4px;
height: 488px;
}
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" type="text/css" href="main.css">
</head>
<body>
<nav>
</nav>
<div id="painel">
<div id="map-container">
<div id="map">
</div>
<ul id="map-interface">
<li>asda</li>
<li>asd</li>
<li>asdsad</li>
</ul>
</div>
</div>
<script src="jquery-1.11.2.min.js"></script>
<script src="main.js"></script>
</body>
</html>
Inside the div#map, I have an image, and inside the list I will have a menu to interact with the image. The ul list should be a block with the same size as the image (or the div).
Try #map-interface { vertical-align:top; } to align inlined-block content to their tops.

Categories

Resources