Issues with multiple sticky / fixed headers/divs? (Jittering and positioning on scroll) - javascript

I'm trying to make a site with multiple sections. There are logos, that should take up the full screen. Then, as the user scrolls down, the logos should get smaller and shrink to the top of the screen, staying fixed to the top. They should push the section contents down so that they are fully visible.
The user can continue scrolling down to the next section. It should once again be the full page height, taking up the user's entire screen. It should push the previous logo header up out of the way, and repeat the same process, as the user scrolls down, it should get smaller, moving to the top of the screen, leaving space for the contents of the section.
However, unfortunately, the headers seem to be very jittery when I try to scroll down. The scrolling can even get stuck without moving the scrollbar with the mouse.
I have also found that after I scroll down past the second section, the first header pops up again.
Here is my site, with the minimal code to reproduce this problem:
The Site
The code is mainly copied from two w3schools tutorials, I have been trying to combine the two:
https://www.w3schools.com/howto/howto_js_sticky_header.asp
https://www.w3schools.com/howto/howto_js_shrink_header_scroll.asp
Any help would be greatly appreciated, and if anyone has any ideas on how this could be fixed, please, let me know!
Update: I've figured out that the issue seems to be that the scroll offset, once the header shrinks, ends up being lower than the offset required to shrink the header. So it cycles and jitters between shrunk and not shrunk. How do I fix this?
Code (No images, please open site link to test):
// When the user scrolls down 50px from the top of the document, resize the header's font size
window.onscroll = function() {scrollFunction()};
function scrollFunction() {
console.log(document.documentElement.scrollTop);
if (document.body.scrollTop > 500 || document.documentElement.scrollTop > 500) {
document.getElementById("title").style.fontSize = "24px";
document.getElementById("title").style.height = "25vh";
document.getElementById("title").style.position = "fixed";
} else {
document.getElementById("title").style.fontSize = "96px";
document.getElementById("title").style.height = "100vh";
document.getElementById("title").style.position = "sticky";
}
if (document.body.scrollTop > 100 || document.documentElement.scrollTop > 100) {
document.getElementById("title").classList.add("sticky");
document.getElementById("title").style.fontSize = "12px";
document.getElementById("title").style.height = "10vh";
} else {
document.getElementById("title").classList.remove("sticky");
document.getElementById("title").style.fontSize = "96px";
document.getElementById("title").style.height = "100vh";
}
if (document.body.scrollTop > 960 || document.documentElement.scrollTop > 960) {
document.getElementById("title1").classList.add("sticky");
document.getElementById("l2").style.height = "50px";
document.getElementById("title1").style.height = "10vh";
} else {
document.getElementById("title1").classList.remove("sticky");
document.getElementById("l2").style.height = "500px";
document.getElementById("title1").style.height = "100vh";
}
}
:root{
--acol: #ffffff;
--bcol: #eeeeee;
--ccol: #dddddd;
--dcol: #999999;
}
html, body{
margin: 0px;
padding: 0px;
height: 100%;
text-align: center;
}
#bodycontainer{
display: flex;
}
#main{
width: 95vw;
height: 100%;
}
/* CARDS AND MAIN SCREEN*/
.title, #title, #title1{
background: var(--bcol);
width: 95vw;
overflow: visible;
display: flex;
justify-content: center;
margin: 0;
align-items: center;
position: sticky;
top: 0;
transition: 0.25s;
}
section{
width: 95vw;
}
#container{
background: var(--acol);
width: 100%;
display: flex;
flex-wrap: wrap;
}
.card{
flex: 1 0 21%;
max-width: 250px;
margin: 5px;
cursor: help;
}
.logo.two, #l2{
width: 50%;
height: 50px;
position: sticky;
position: -webkit-sticky;
display: flex;
top: 70px;
}
/*SIDEBAR*/
#sidebar{
background: var(--ccol);
position: fixed;
margin-left: 95vw;
width: 5vw;
height: 100%;
text-align: center;
font-family: "Helvetica";
display: flex;
align-items: center;
}
#circ{
width: 25px;
height: 25px;
background: var(--acol);
border-radius: 100px;
margin-left: auto;
margin-right: auto;
z-index: 999;
}
#tabs{
background: var(--bcol);
width: 25px;
margin-left: auto;
margin-right: auto;
height: fit-content;
border-radius: 25px;
}
.tab{
display: block;
width: 100%;
line-height: 25px;
z-index: 1;
}
#wrap{
position: absolute;
width: 5vw;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link href="style.css" rel="stylesheet">
<script src="script.js"></script>
</head>
<body>
<!--MAIN CONTENT-->
<div id="bodycontainer">
<div id="main">
<!--ROLAND-->
<section>
<h1 class="title" id="title">Roland PN-D10 Series</h1>
<div id="container">
<img src="PN-D10-01_Vector_2X.png" class="card">
<img src="PN-D10-01_Vector_2X.png" class="card">
<img src="PN-D10-01_Vector_2X.png" class="card">
</div>
</section>
<!--DAVID GARFIELD-->
<section>
<h1 class="title" id="title1"><img class="logo two" id="l2" src="DGT.svg"></h1>
<div id="container">
<img src="David_Garfield_Vector_2X.png" class="card">
<img src="David_Garfield_Vector_2X.png" class="card">
<img src="David_Garfield_Vector_2X.png" class="card">
</div>
</section>
<img src="David_Garfield_Vector_2X.png" class="card">
<img src="David_Garfield_Vector_2X.png" class="card">
<img src="David_Garfield_Vector_2X.png" class="card">
<img src="David_Garfield_Vector_2X.png" class="card">
<img src="David_Garfield_Vector_2X.png" class="card">
<img src="David_Garfield_Vector_2X.png" class="card">
<img src="David_Garfield_Vector_2X.png" class="card">
<img src="David_Garfield_Vector_2X.png" class="card">
<img src="David_Garfield_Vector_2X.png" class="card">
<img src="David_Garfield_Vector_2X.png" class="card">
<img src="David_Garfield_Vector_2X.png" class="card">
<img src="David_Garfield_Vector_2X.png" class="card">
<img src="David_Garfield_Vector_2X.png" class="card">
</div>
<!--SIDEBAR-->
<div id="sidebar">
<div id="wrap">
<div id="circ"></div>
</div>
<div id="tabs">
<a class="tab" href="#a">A</a>
<a class="tab" href="#b">B</a>
<a class="tab" href="#c">C</a>
<a class="tab" href="#d">D</a>
</div>
</div>
</body>
</html>
Thanks!

Related

At a road block with scroll section for my featured items on site

On my site I have a scroll section that will display watches and allow you to scroll on the section similar to what rolex does on their homepage. I created div container for the section and added a wrapper container that I was using to control the items. I also was trying to add arrows that can be used as an option to scroll just like how rolex does on theirs. Nothing is working. The items are there but the functionality isnt. Take a look at Rolex website and scroll down to their watches section on the home page. I want to do exactly that.
I tried adding JavaScript to make it functional but that did nothing for me. I even added a console.log() to see if anything would print in the browser console and got nothing. Please help.
// Select the left and right arrow buttons
const leftButton = document.querySelector('.arrow-button.left');
const rightButton = document.querySelector('.arrow-button.right');
// Select the watch items wrapper element
const watchItemsWrapper = document.querySelector('.watch-items-wrapper');
// Scroll the watch items wrapper element to the left or right when the arrow buttons are clicked
leftButton.addEventListener('click', () => {
watchItemsWrapper.scrollBy({
left: watchItemsWrapper.scrollLeft - 200, // Scroll 200 pixels to the left
behavior: 'smooth' // Use a smooth scroll transition
});
});
rightButton.addEventListener('click', () => {
watchItemsWrapper.scrollBy({
left: watchItemsWrapper.scrollLeft + 200, // Scroll 200 pixels to the right
behavior: 'smooth' // Use a smooth scroll transition
});
});
/* Watch Reel Section */
.watch-reel-container {
display: flex;
position: relative;
flex-wrap: nowrap;
overflow: scroll;
scroll-behavior: smooth;
margin-left: 230px;
}
.watch-items-wrapper {
display: flex;
flex-wrap: nowrap;
}
.watch-reel-item {
flex: 0 0 200px;
padding: 20px;
cursor: pointer;
}
.watch-reel-container img {
width: 400px;
height: 400px;
object-fit: cover;
border-radius: 10px;
box-shadow: 0 0 10px rgba(0, 0, 0, 0.3);
}
.watch-name {
margin-top: 10px;
font-size: 18px;
font-weight: bold;
text-align: center;
color: #333;
text-transform: uppercase;
}
.watch-reel-h2 {
margin-top: 150px;
margin-left: 250px;
}
.watch-reel-h2 a {
text-decoration: none;
color: #375ea1;
}
.watch-reel-h2 a:hover {
opacity: 70%;
}
.scroll-bar {
position: absolute;
bottom: 0;
left: 0;
right: 0;
height: 8px;
background: #ccc;
border-radius: 4px;
}
.arrow-container {
position: absolute;
top: 50%;
transform: translateY(-100%);
display: flex;
justify-content: space-between;
width: 100%;
}
.arrow-button {
display: flex;
align-items: center;
justify-content: center;
width: 40px;
height: 40px;
border-radius: 50%;
background-color: black;
color: white;
font-size: 20px;
cursor: pointer;
}
.arrow-button::before {
left: 0;
content: '>';
}
.arrow-button.left::before {
right: 0;
content: '<';
}
.arrow-button:hover {
background: #333;
cursor: pointer;
}
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.2.1/css/all.min.css" />
<!-- Beginning of Watch Reel -->
<div class="watch-reel-h2">
<h2>Featured Watches - View all</h2>
</div>
<div class="watch-reel-container">
<div class="watch-items-wrapper">
<div class="watch-reel-item">
<img src="/images/rolex-panda.png" alt="Watch 1">
<p class="watch-name">Rolex Panda</p>
</div>
<div class="watch-reel-item">
<img src="/images/ap-1.png" alt="Watch 2">
<p class="watch-name">AP Royal Oak Offshore</p>
</div>
<div class="watch-reel-item">
<img src="/images/patek-1.png" alt="Watch 3">
<p class="watch-name">Patek Phillipe</p>
</div>
<div class="watch-reel-item">
<img src="/images/patek-1.png" alt="Watch 3">
<p class="watch-name">Patek Phillipe</p>
</div>
<div class="watch-reel-item">
<img src="/images/patek-1.png" alt="Watch 3">
<p class="watch-name">Patek Phillipe</p>
</div>
<div class="watch-reel-item">
<img src="/images/patek-1.png" alt="Watch 3">
<p class="watch-name">Patek Phillipe</p>
</div>
<div class="watch-reel-item">
<img src="/images/patek-1.png" alt="Watch 3">
<p class="watch-name">Patek Phillipe</p>
</div>
</div>
<div class="scroll-bar"></div>
<div class="arrow-container">
<button class="arrow-button left">
<i class="fa fa-arrow-left"></i>
</button>
<button class="arrow-button right">
<i class="fa fa-arrow-right"></i>
</button>
</div>
</div>
<!-- End of Watch Reel -->
Add overflow: scroll to your .watch-items-wrapper:
.watch-items-wrapper {
display: flex;
flex-wrap: nowrap;
overflow: scroll;
}
You can remove the overflow: scroll; from your .watch-reel-container, it's not needed. If you want the container to span full width then add overflow: hidden to your .watch-reel-container.
Next adjust both your scroll functions as such:
Left:
leftButton.addEventListener('click', () => {
watchItemsWrapper.scrollBy({
left: -200,
behavior: 'smooth'
});
});
Right:
rightButton.addEventListener('click', () => {
watchItemsWrapper.scrollBy({
left: 200,
behavior: 'smooth'
});
});
I think this will give you the functionality you're looking for.
If you'd like to hide the scrollbar but keep the functionality, check our this doc from w3schools.
I hope this helps!

Sticky section scrolling effect HTML

In the following pen I would like to create an effect where you have to scroll (by scrolling, not with mouse movement), all the way down until the top image is revealed, until we move to the next section.
The effect I'm trying to re-create, in case the explanation is too confusing can be found on Apple's website here
As you scroll down you'll understand.
let wrapper = document.querySelector('#wrapper');
let topLayer = wrapper.querySelector('.top');
let handle = wrapper.querySelector('.handle');
wrapper.addEventListener('mousemove', e => {
handle.style.top = e.clientY + 'px';
topLayer.style.height = e.clientY + 'px';
});
});
Here is an example using the CSS position: sticky
body {
font-family: georgia;
height: 1000px;
}
img {
display: block;
margin: 0 auto;
}
.sticky {
position: sticky;
position: -webkit-sticky;
width: 100%;
top: 25vh;
justify-content: center;
align-items: center;
color: #fff;
}
.wrapper {
width: 75%;
margin: auto;
background-color: silver;
padding: 15px;
}
.wrapper {
height: 200vh;
}
<link href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.6.0/css/bootstrap.css" rel="stylesheet"/>
<div class="wrapper bg-primary">
<div class="sticky">
<img src='https://dummyimage.com/400x100.png?text=image-1' alt='' />
</div>
</div>
<br>
<div class="wrapper bg-success">
<div class="sticky">
<img src='https://dummyimage.com/400x100.png?text=image-2' alt='' />
</div>
</div>
<br>
<div class="wrapper bg-warning">
<div class="sticky">
<img src='https://dummyimage.com/400x100.png?text=image-3' alt='' />
</div>
</div>

how to slide my content one by one clicking button(prev/next) or arrow in jquery?

I want to slide my bx-content(div) when i click prev or next button. I have 3 content is visible when others are hidden. i have more than 10 bx-content(div) and if prev or next button is clicked then i want to slide one by one bx-content(div) and if all content is finishes and get clicked next button then show from the beginning again like cycle. could somebody help me please ? my html code is here
<!DOCTYPE html>
<html>
<head>
<title></title>
<link rel="stylesheet" type="text/css" href="style.css">
</head>
<body>
<section class="bx-feature">
<h3>Feature</h3>
<button class="next">Next</button>
<button class="previous">Prev</button>
<hr style="clear: both;">
<div class="bx-slider">
<div class="bx-content">
<img src="https://media-cdn.tripadvisor.com/media/photo-s/0c/f0/1e/2d/mt-everest-base-camp.jpg" alt="">
<h3>Mount Everest</h3>
</div>
<div class="bx-content">
<img src="https://www.wallpaperup.com/uploads/wallpapers/2013/03/23/58533/a2e7390e04f5ed3b6bba3576f75436bb.jpg" alt="">
<h3>Mount Everest sunset</h3>
</div>
<div class="bx-content">
<img src="https://media-cdn.tripadvisor.com/media/photo-s/0c/f0/1e/2d/mt-everest-base-camp.jpg" alt="">
<h3>Mount Everest</h3>
</div>
<div class="bx-content">
<img src="https://media-cdn.tripadvisor.com/media/photo-s/0c/f0/1e/2d/mt-everest-base-camp.jpg" alt="">
<h3>Mount Everest</h3>
</div>
<div class="bx-content">
<img src="https://media-cdn.tripadvisor.com/media/photo-s/0c/f0/1e/2d/mt-everest-base-camp.jpg" alt="">
<h3>Mount Everest</h3>
</div>
</div>
</section>
and my css code is here
.bx-feature{ background-color: #e9e9e9; height: 360px; width: 90%; overflow:
hidden; margin: auto; margin-top: 100px;}
.bx-feature h3{ float: left; }
button{ float: right; border-radius: 5px; padding: 7px; margin: 10px 5px
0 5px; }
.bx-slider{ margin: 10px 20px; }
.bx-content{ height: 250px; width: 320px; overflow: hidden; float: left;
margin: 20px;}
.bx-content img{ width: 100%; height: 200px; }
You have to get your button in jquery and add a listener on the click event after that just select your container and change play with the transform : translateX css properties.
Something like that :
var width = $(".bx-slider").width();
var numberChild = $(".bx-slider").children().length;
var move = width / numberChild;
var position = 0;
$(".next").click(
() => {
position -= move;
$(".bx-slider").css({'transform' : 'translateX(' + position + 'px)'}
}
);
just change minus to sum for the prev button
and btw put your code in a script tag

Set width of child div in flex container

I have 4 divs with the class .piece-slide that horizontally scroll across the page within the the div #work, which is a flex element. Within the third .piece-slide div the 3 nested elements are absolutely positioned, this renders the width of the third .piece-slide div to 0, so now I want to programmatically set the width of the third .piece-slide div so that it covers the 3 nested elements.
For some reason I am unable to set this width through CSS. I have also tried through jQuery. It would be much appreciated if some pointed me in the right direction as how to rectify this. Here is a jsfiddle as well as the embedded code below.
$("#third-div").outerWidth("100vw");
#wrapper {
display: flex;
flex-direction: column;
height: 100vh;
}
.content {
flex: 1;
}
#work {
height: 100%;
overflow-x: scroll;
display: flex;
background-color: red;
}
.piece-slide {
display: flex;
align-items: center;
position: relative;
padding-right: 5em;
box-sizing: border-box;
border-right: 1px solid black;
}
.piece {
width: 25vw;
margin: 10px;
}
.piece img {
max-width: 100%;
}
#third-div {
/* D0ES NOT WORK */
width: 100vw;
background-color: green;
}
#third-div a {
position: absolute;
}
#third-div a:nth-child(1) {
top: 0;
left: 0;
}
#third-div a:nth-child(2) {
top: 25vw;
left: 25vw;
}
#third-div a:nth-child(3) {
left: 60vw;
}
<div id="wrapper">
<div class="content">
<div id="work">
<div class="piece-slide">
<a class="piece">
<img src="https://athlonecommunityradio.ie/wp-content/uploads/2017/04/placeholder.png">
</a>
</div>
<div class="piece-slide">
<a class="piece">
<img src="https://dummyimage.com/hd1080https://dummyimage.com/hd1080">
</a>
<a class="piece">
<img src="https://dummyimage.com/hd1080https://dummyimage.com/hd1080">
</a>
</div>
<!-- THIRD DIV WHERE WIDTH SHOULD BE SET -->
<div id="third-div" class="piece-slide">
<a class="piece" num="1">
Nested Element 1<img src="http://i.stack.imgur.com/yZlqh.png">
</a>
<a class="piece" num="2">
Nested Element 2<img src="http://www.jennybeaumont.com/wp-content/uploads/2015/03/placeholder.gif">
</a>
<a class="piece" num="3">
Nested Element 3<img src="http://suplugins.com/podium/images/placeholder-02.jpg">
</a>
</div>
<div class="piece-slide">
<a class="piece">
<img src="https://athlonecommunityradio.ie/wp-content/uploads/2017/04/placeholder.png">
</a>
</div>
</div>
</div>
</div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
Try to remove
flex-direction: column;
from #wrapper.
Or change it to
flex-direction: row;

Javascript CSS3: Move div container

I've been messing with this code for awhile now and I'm stuck. I've done a lot of coding by hand but just now ramping up on the new things with HTML5, CSS3, and Javascript.
I'm trying to make a simple menu that slides up and down. I have a div that contains everything. The div has overflow set to hidden so when the menu is out of the viewing box, it can't be seen. It can then animate in and out of the view box.
I've been trying to do it with a Javascript function but it sounds like it's easier to just use CSS3 transitions? Any advice?
My Javascript code is below. I can't quite figure out how to do it with CSS3 transitions. Any advice would be much appreciated.
Html
<header>
<nav>
<div id="mobileMenu" class="mobileMenu">
<div id="mobileMenuWrapper" class="mobileMenuWrapper">
<div style="height: 100px; width: 100%;">
<div style="height: 100px; width: 100%; background-color: black; color: white;">
Menu option<br>Menu option<br>Menu option
</div>
</div>
<div style="position: relative; height: 50px; width: 100%; left: 50px;">
<div style="height: 50px; width: 125px; background-color: black; color: white; text-align: center;">Menu</div>
</div>
</div>
</div>
</nav>
</header>
Javascript
var startPosition = -100;
var endPosition = 0;
var speed = 2;
function moveMenuDown(){
// Get the element
menu = document.getElementById("mobileMenuWrapper");
// Grab the element's current CSS top position
currentPosition = Number(menu.style.top.substr(0,(menu.style.top.length-2)));
// Compare the position and move it
if(currentPosition <= endPosition){
// I'm stuck about the line below...how can I attach a CSS3 transition here? Or should I?
menu.style.MozTransition = ???;
// Here's my original code where I move the element manually
menu.style.top = (currentPosition + speed) + 'px';
moveMenuDown();
}else{
}
}
Updated entire HTML/CSS/JavaScript
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>Menu test</title>
<meta name="viewport" content="width=device-width, initial-scale=1" />
<style>
.mobileMenu {
position: absolute;
height: 150px;
width: 250px;
top: 0px;
left: 50px;
overflow: hidden;
}
#mobileMenuWrapper {
margin-top:-100px;
transition: margin-top 0.5s ease;
}
#mobileMenuWrapper.show {
margin-top:0px;
}
</style>
<script type="text/javascript">
function moveMenuDown(){
menu = document.getElementById("mobileMenuWrapper hide");
if(menu.className=="mobileMenuWrapper hide"){
menu.className = menu.className.replace('hide','show');
}else{
menu.className = "mobileMenuWrapper hide";
}
}
</script>
</head>
<body>
<header>
<nav>
<div id="mobileMenu" class="mobileMenu">
<div id="mobileMenuWrapper" class="mobileMenuWrapper hide">
<div style="height: 100px; width: 100%;">
<div style="height: 100px; width: 100%; background-color: black; color: white;">
Menu option<br>Menu option<br>Menu option
</div>
</div>
<div style="position: relative; height: 50px; width: 100%; left: 50px;">
<div style="height: 50px; width: 125px; background-color: black; color: white; text-align: center;">Menu</div>
</div>
</div>
</div>
</nav>
</header>
</body>
</html>
HTML: one additional class:
<header>
<nav>
<div id="mobileMenu" class="mobileMenu">
<div id="mobileMenuWrapper" class="mobileMenuWrapper hide">
<div style="height: 100px; width: 100%;">
<div style="height: 100px; width: 100%; background-color: black; color: white;">
Menu option<br>Menu option<br>Menu option
</div>
</div>
<div style="position: relative; height: 50px; width: 100%; left: 50px;">
<div style="height: 50px; width: 125px; background-color: black; color: white; text-align: center;"><a id="move" href="javascript:moveMenuDown();">Menu</a></div>
</div>
</div>
</div>
</nav>
</header>
CSS: (very simple)
#mobileMenuWrapper{
margin-top:-100px;
transition: margin-top 0.5s ease;
}
#mobileMenuWrapper.show{
margin-top:0px;
}
*just added class and transition.
JS, much simpler:
function moveMenuDown(){
menu = document.getElementById("mobileMenuWrapper");
if(menu.className=="mobileMenuWrapper hide"){
menu.className = menu.className.replace('hide','show');
}
else {
menu.className = "mobileMenuWrapper hide";
}
}
('toggle' functionality added)
Fiddle: http://jsfiddle.net/8u0eka5x/

Categories

Resources