scroll step is different in Firefox - with mouse wheel - javascript

I'm making a website with huge text on screen & I would like to be able to scroll two divs at the same time. So this part is working.
I'm actually able to scroll the divs but the jumps are really too huge on the #back div. (they seems to actually be the same as the window height (so maybe you need to have the snipped full screen to fully understand what I mean)).
UPDATE: after a bit of testing with a friend, the issue appears to be with firefox on windows. It's working just fine on mac & linux.
here is a fiddle so you can see with a increased height
Here are two gif so maybe you see the weird effet.
each page movement = one scrollwheel down on my mouse (also it's working just fine with a trackpad since it's not a mouse wheel).
VS when I remove one of the two overflow in my css, my following black square stops working, but the scroll is normal again :
IMPORTANT EDIT : This is an issue in firefox but it seems to be working correctly in chrome & Brave. I'm still looking for a way to make it work nonetheless.
So, I noticed that this happens when I set two overflows in the css, actually, if you remove one, the script doesn't work anymore but the scroll bug is stopping too.
Here is the example with the bug:
let back_innerHeight = $("#back").height()
let back_scrollHeight = document.querySelector("#back").scrollHeight
let front_innerHeight = $("#front").innerHeight()
let front_scrollHeight = $("#front")[0].scrollHeight
$("#back").on("scroll", function () {
// Get how many pixels were scrolled on #back
let back_scrolled = $(this).scrollTop()
// Calculate the scrolled percentage
let percentage_back = back_scrolled / (back_scrollHeight - back_innerHeight)
// Calculate how many pixels to scroll on #front
let scrollIT = (percentage_back * (front_scrollHeight - front_innerHeight))
// Just to validate that the percentage is applied correctly...
let percentage_front = scrollIT / (front_scrollHeight - front_innerHeight)
// Apply the scroll
$("#front").scrollTop(scrollIT);
});
window.onresize = function(){
back_innerHeight = $("#back").height()
back_scrollHeight = document.querySelector("#back").scrollHeight
front_innerHeight = $("#front").innerHeight()
front_scrollHeight = $("#front")[0].scrollHeight
}
.scroll {
position: absolute;
display: block;
top: 0;
height: 100%;
}
#front {
overflow: hidden;
position: absolute;
background-color: black;
color: white;
right: 0;
left: 0;
bottom: 0;
top: 0;
margin: auto auto auto auto;
width: 25%;
height: 35%;
font-size: 3rem;
}
#back {
overflow: auto;
font-size: 8rem;
}
p {
margin: 0;
padding: 0;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class ="scroll" id="back">
<p>Lorem ipsum dolor sit amet consectetur, adipisicing elit. Autem, quam similique quibusdam libero voluptatum laboriosam, sunt possimus non nobis recusandae, excepturi ex voluptates! Neque veniam, sapiente magnam fuga unde autem.
Lorem ipsum dolor sit amet, consectetur adipisicing elit. Fugiat consequatur consectetur laudantium voluptatibus, iusto molestiae fugit inventore rerum, sit sed dolor ratione perferendis beatae molestias. Asperiores odio mollitia quisquam voluptates.</p>
</div>
<div class ="scroll" id="front">
<p>Lorem ipsum dolor sit amet consectetur, adipisicing elit. Autem, quam similique quibusdam libero voluptatum laboriosam, sunt possimus non nobis recusandae, excepturi ex voluptates! Neque veniam, sapiente magnam fuga unde autem.
Lorem ipsum dolor sit amet, consectetur adipisicing elit. Fugiat consequatur consectetur laudantium voluptatibus, iusto molestiae fugit inventore rerum, sit sed dolor ratione perferendis beatae molestias. Asperiores odio mollitia quisquam voluptates.</p>
</div>

EDIT
What is below is not an answer to the question, which is now more specific about a FF behavior more than a scroll sync between the two divs.
For scroll sync
That is more about some maths... And also which values to use.
You have to calculated a percentage of what has been scrolled from what is scrollable. Here is the key! What is scrollable is not the whole height of the element because there is always a part that is visible.
That make three values to consider about #back:
A: the visible part of the div, which you get using .innerHeight()
B: the amount of scrolled pixels, which you get with .scrollTop()
C: the full height of the div, including the parts already scrolled (above the top) and the one to be scrolled (below the bottom). That is the scrollHeight property.
So to obtain the right percentage, the formula is: B/(C-A).
Then, use this percentage on the #front "scrollable pixels", which again, is the full height minus the visible height.
And there you go!
let back_innerHeight = $("#back").height()
let back_scrollHeight = document.querySelector("#back").scrollHeight
let front_innerHeight = $("#front").innerHeight()
let front_scrollHeight = $("#front")[0].scrollHeight
$("#back").on("scroll", function () {
// Get how many pixels were scrolled on #back
let back_scrolled = $(this).scrollTop()
// Calculate the scrolled percentage
let percentage_back = back_scrolled / (back_scrollHeight - back_innerHeight)
// Calculate how many pixels to scroll on #front
let scrollIT = (percentage_back * (front_scrollHeight - front_innerHeight))
// Just to validate that the percentage is applied correctly...
let percentage_front = scrollIT / (front_scrollHeight - front_innerHeight)
console.log("Scrolled % BACK:", percentage_back, "FRONT:", percentage_front)
// Apply the scroll
$("#front").scrollTop(scrollIT);
});
window.onresize = function(){
back_innerHeight = $("#back").height()
back_scrollHeight = document.querySelector("#back").scrollHeight
front_innerHeight = $("#front").innerHeight()
front_scrollHeight = $("#front")[0].scrollHeight
}
div {
}
#front {
overflow: hidden;
position: fixed;
background-color: black;
color: white;
right: 0;
left: 0;
bottom: 0;
top: 0;
margin: auto auto auto auto;
width: 25%;
height: 35%;
font-size: 3rem;
}
#back {
height: 95vh;
overflow: auto;
overflow-x: hidden;
overflow-y: auto;
font-size: 8rem;
}
p{
margin:0;
padding:0;
}
/* Just for this demo here... to limit the SO console's height */
.as-console-wrapper{
height: 1.4em;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="back">
<p>Lorem ipsum dolor sit amet consectetur, adipisicing elit. Autem, quam similique quibusdam libero voluptatum laboriosam, sunt possimus non nobis recusandae, excepturi ex voluptates! Neque veniam, sapiente magnam fuga unde autem.
Lorem ipsum dolor sit amet, consectetur adipisicing elit. Fugiat consequatur consectetur laudantium voluptatibus, iusto molestiae fugit inventore rerum, sit sed dolor ratione perferendis beatae molestias. Asperiores odio mollitia quisquam voluptates.</p>
</div>
<div id="front">
<p>Lorem ipsum dolor sit amet consectetur, adipisicing elit. Autem, quam similique quibusdam libero voluptatum laboriosam, sunt possimus non nobis recusandae, excepturi ex voluptates! Neque veniam, sapiente magnam fuga unde autem.
Lorem ipsum dolor sit amet, consectetur adipisicing elit. Fugiat consequatur consectetur laudantium voluptatibus, iusto molestiae fugit inventore rerum, sit sed dolor ratione perferendis beatae molestias. Asperiores odio mollitia quisquam voluptates.</p>
</div>
Some documentation:
.innerHeight()
.scrollHeight

Related

Question: Intersection Observer - Animation

I spent the weekend trying to get my head around the Intersection Observer Animation for an animation that I'm trying to achieve. From my understanding of the intersection observer my code should work as I intended but the reality is it doesn't 🥲
My goal is that the scroll animation starts when the element reaches a certain point within the viewport. In my codepen, I've marked the point where the animation should start with a border. However, the animation starts as soon as the div enters the viewport.
Also, when the element gets below the border again, the animation should stop.
I would very much appreciate any help to achieve my goal.
Code example: https://codepen.io/aki-sol/pen/RwJPJrW?editors=1111
Also, if you have any feedback on my animation approach I'm very happy to receive criticism/ better way of approaching this.
<div class="text">
Lorem ipsum, dolor sit amet consectetur adipisicing elit. Expedita provident unde, sequi aliquid porro ipsa vitae nulla dolor neque aliquam quisquam nam magnam architecto, consequuntur est in beatae, nihil optio.
Lorem ipsum dolor sit amet, consectetur adipisicing elit. Et, architecto eveniet assumenda praesentium in laboriosam vitae atque, sunt minima aliquid quam distinctio voluptatum commodi veniam iure officia provident voluptas ea?
Lorem ipsum dolor sit amet consectetur adipisicing elit. Eveniet quo commodi laborum perspiciatis nemo voluptates quod odio quis necessitatibus perferendis? Ipsum, quasi nesciunt. Debitis omnis consequuntur laboriosam veniam, non impedit!
</div>
<div class="box">
<div class="box-content"></div>
<div class="box-content"></div>
<div class="box-content"></div>
<div class="box-content"></div>
<div class="box-content"></div>
<div class="box-content"></div>
<div class="box-content"></div>
<div class="box-content"></div>
<div class="box-content"></div>
<div class="box-content"></div>
<div class="box-content"></div>
<div class="box-content"></div>
</div>
<div class="text">
Lorem ipsum, dolor sit amet consectetur adipisicing elit. Expedita provident unde, sequi aliquid porro ipsa vitae nulla dolor neque aliquam quisquam nam magnam architecto, consequuntur est in beatae, nihil optio.
Lorem ipsum dolor sit amet, consectetur adipisicing elit. Et, architecto eveniet assumenda praesentium in laboriosam vitae atque, sunt minima aliquid quam distinctio voluptatum commodi veniam iure officia provident voluptas ea?
Lorem ipsum dolor sit amet consectetur adipisicing elit. Eveniet quo commodi laborum perspiciatis nemo voluptates quod odio quis necessitatibus perferendis? Ipsum, quasi nesciunt. Debitis omnis consequuntur laboriosam veniam, non impedit!
</div>
body {
position: relatvie;
heig;
}
body:after {
content: '';
position: fixed;
bottom: 40%;
height: 1px;
width: 100%;
border-bottom: 1px solid blue;
}
.text {
background-color: brown;
color: white;
height: 150vh;
}
.box {
display: flex;
position: relative;
}
.box-content {
width: 200px;
height: 200px;
background-color: greenyellow;
margin-right: 50px;
}
const boxElement = document.querySelector(".box");
//this function calls the aniamtion function and observes the window scroll position
function getWindowScrollPos() {
let windowPosition = window.scrollY;
window.addEventListener("scroll", () => {
windowPosition = window.scrollY;
animateBox(boxElement, windowPosition);
});
}
function animateBox(box, scrollPosition) {
let boxOffsetPosition = scrollPosition;
box.style.left = `${-boxOffsetPosition}px `;
}
function boxObserver(element) {
const observer = new IntersectionObserver(
(entries, observer) => {
entries.forEach((entry) => {
if (entry.isIntersecting) {
getWindowScrollPos();
}
});
},
{ rootMargin: "0% 0% 60% 0%" }
);
observer.observe(element);
}
boxObserver(boxElement);
Thanks a lot!
There are two things to note here, I guess.
First, the Intersection Observer (along with Resize Observer) is not the best thing to test in online sandboxes, because they run code in an iframe, which leads to such a behavior. You should try to run your code in a browser.
There are questions related to this problem. E.g.: In codepen, Intersection observer has different behavior from browser window
Second, you're probably misunderstanding rootMargin. You set it to 0% 0% 60% 0% which means “add 60% of the height of the root to the very root, and use it as a bottom border for intersection”.
What you actually want to is to decrease the bottom border, not to increase. So, just set it to 0% 0% -40% 0% and it will work.
The Intersection Observer tutorial that helped me a bit to understand the rootMargin weirdness. Maybe it will be useful for you too.
Demo
Here's your snippet that I changed a bit to make it work inside an iframe. I've added a container node and use it instead of window.
const boxElement = document.querySelector('.box');
const container = document.getElementById('container');
function setupListener() {
let scrollPosition = container.scrollTop;
animateBox(boxElement, scrollPosition);
container.addEventListener('scroll', () => {
scrollPosition = container.scrollTop;
animateBox(boxElement, scrollPosition);
});
}
function animateBox(box, scrollPosition) {
let boxOffsetPosition = scrollPosition;
box.style.left = `${-boxOffsetPosition}px`;
}
function boxObserver(element) {
const observer = new IntersectionObserver(
(entries, observer) => {
entries.forEach((entry) => {
if (entry.isIntersecting) {
setupListener();
}
});
},
{
root: document.getElementById('container'),
rootMargin: `0px 0px -40% 0px`
}
);
observer.observe(element);
}
boxObserver(boxElement);
body {
margin: 0;
overflow: hidden;
}
body:after {
content: "";
position: fixed;
bottom: 40%;
height: 1px;
width: 100%;
border-bottom: 1px solid blue;
}
.container {
overflow: scroll;
max-height: 100vh;
}
.text {
background-color: brown;
color: white;
height: 150vh;
}
.box {
display: flex;
position: relative;
}
.box-content {
width: 200px;
height: 200px;
background-color: greenyellow;
margin-right: 50px;
}
<div class="container" id="container">
<div class="text">
Lorem ipsum, dolor sit amet consectetur adipisicing elit. Expedita provident unde, sequi aliquid porro ipsa vitae nulla dolor neque aliquam quisquam nam magnam architecto, consequuntur est in beatae, nihil optio.
Lorem ipsum dolor sit amet, consectetur adipisicing elit. Et, architecto eveniet assumenda praesentium in laboriosam vitae atque, sunt minima aliquid quam distinctio voluptatum commodi veniam iure officia provident voluptas ea?
Lorem ipsum dolor sit amet consectetur adipisicing elit. Eveniet quo commodi laborum perspiciatis nemo voluptates quod odio quis necessitatibus perferendis? Ipsum, quasi nesciunt. Debitis omnis consequuntur laboriosam veniam, non impedit!
</div>
<div class="box">
<div class="box-content"></div>
<div class="box-content"></div>
<div class="box-content"></div>
<div class="box-content"></div>
<div class="box-content"></div>
<div class="box-content"></div>
<div class="box-content"></div>
<div class="box-content"></div>
<div class="box-content"></div>
<div class="box-content"></div>
<div class="box-content"></div>
<div class="box-content"></div>
</div>
<div class="text">
Lorem ipsum, dolor sit amet consectetur adipisicing elit. Expedita provident unde, sequi aliquid porro ipsa vitae nulla dolor neque aliquam quisquam nam magnam architecto, consequuntur est in beatae, nihil optio.
Lorem ipsum dolor sit amet, consectetur adipisicing elit. Et, architecto eveniet assumenda praesentium in laboriosam vitae atque, sunt minima aliquid quam distinctio voluptatum commodi veniam iure officia provident voluptas ea?
Lorem ipsum dolor sit amet consectetur adipisicing elit. Eveniet quo commodi laborum perspiciatis nemo voluptates quod odio quis necessitatibus perferendis? Ipsum, quasi nesciunt. Debitis omnis consequuntur laboriosam veniam, non impedit!
</div>
</div>
What may be improved
Also, if you have any feedback on my animation approach I'm very happy to receive criticism/ better way of approaching this.
Well, you surely should think about the scroll listener you will have after the intersection started. If you don't remove it, it will hang. Or even worse, they will be increasing during each intersection. Not a good thing.
Also it's better to animate transform, not left. It's good for optimization. Otherwise you'll get junky animation which will freeze the whole site. Check this set of articles by Google: web.dev/animations/.

Sticky header and hidden content with box-shadow

I'm new to coding and on my way to becoming a Junior Dev. This is also my first post on Stack Overflow.
Situation:
I have made a sticky header that has a box-shadow property intended to uncover content when scrolling down and hover on the body section. The box-shadow values are set to make the content hidden and only the nav header appears as visible. The header has position: fixed;
Question:
I was wondering if it's possible to make my content still be as hidden when the browser is open (just at the moment of opening, but unhide it when scrolled on the body section. If so, where could I apply the box-shadow property or is there a better way to do it? My knowledge is limited but so I'm looking for ways.
Code
window.addEventListener("scroll", function() {
const header = document.querySelector("header");
header.classList.toggle("sticky", window.scrollY > 0);
})
/* experimental start */
.wrapper-nav {
position: fixed;
top: 0%;
left: 0%;
width: 100%;
display: flex;
transition: 3s;
padding: 20px 40px;
justify-content: space-around;
background-color: goldenrod;
box-shadow: 0px 400px 300px 1000px;
color: blueviolet;
z-index: 1;
}
.wrapper-nav:hover {
box-shadow: none;
transition: 0.6s;
}
<header>
<nav>
<div class="container-nav">
<div class="wrapper-nav">
</div>
</div>
</nav>
</header>
<main>
<h1>Lorem</h1>
<p>Lorem ipsum dolor sit amet consectetur adipisicing elit. At impedit architecto, obcaecati eligendi, iste laborum est, nobis quibusdam magni ratione eum odio ut voluptatem quo adipisci repellendus? Consectetur, possimus perferendis.
</p>
<h1>Lorem</h1>
<p>Lorem ipsum dolor sit amet consectetur adipisicing elit. At impedit architecto, obcaecati eligendi, iste laborum est, nobis quibusdam magni ratione eum odio ut voluptatem quo adipisci repellendus? Consectetur, possimus perferendis.
</p>
<h1>Lorem</h1>
<p>Lorem ipsum dolor sit amet consectetur adipisicing elit. At impedit architecto, obcaecati eligendi, iste laborum est, nobis quibusdam magni ratione eum odio ut voluptatem quo adipisci repellendus? Consectetur, possimus perferendis.
</p>
<h1>Lorem</h1>
<p>Lorem ipsum dolor sit amet consectetur adipisicing elit. At impedit architecto, obcaecati eligendi, iste laborum est, nobis quibusdam magni ratione eum odio ut voluptatem quo adipisci repellendus? Consectetur, possimus perferendis.
</p>
</main>
Additional: Any improvements on how to write a better code or create a better inquiry on StackOverflow are welcome.
Thank you for your time.
Realized I need to change some CSS after receiving help. Thank you!
.wrapper-nav {
position: fixed;
top: 0%;
left: 0%;
width: 100%;
display: flex;
transition: 2s;
padding: 20px 40px;
justify-content: space-around;
background-color: goldenrod;
}
.wrapper-nav:hover {
box-shadow: none;
transition: 2s;
box-shadow: 0px 400px 300px 1000px;
color: blueviolet;
z-index: 1;
}
Welcome!
const main= document.querySelector("main");
window.addEventListener("scroll", function() {
const header = document.querySelector("header");
main.style.boxshadow=none;
header.classList.toggle("sticky", window.scrollY > 0);
})
window.addEventListener("DOMContentLoaded"),function(){
main.style.boxshadow= 0px 400px 300px 1000px;
}
Due to short time, I didn't run it but tried to answer the question on DOMload event the content is hidden on scroll I change the style to none to make it visible.

How to detect a div box on scroll

I want to positioned a div box fixed every time I scroll down the page as touch that box and keep scrolling down so that it never disappears after a user sees it.
$(window).scroll(function() {
if($('section#top_casino_offer').scrollTop() +
$('section#top_casino_offer').innerHeight() >= $('section#top_casino_offer')[0].scrollHeight) {
console.log('show');
} else {
console.log('hide');
}
});
I made a quick snippet for it here
I tried the code above but it does not work.
you could specify a scrolling value like this, Check the following snippet :
$(window).scroll(function() {
var y_scroll_pos = window.pageYOffset;
var scroll_pos_test = 90;
// set to whatever you want it to be
if(y_scroll_pos > scroll_pos_test) {
$("#top_casino_offer").css("position","fixed");
}
else
{
$("#top_casino_offer").css("position","relative");
}
});
.outer{
height: 1100px;
background: green;
width: 100%;
}
#yellow{background: yellow;
}
#top_casino_offer {
top: 0;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="outer">
<p>Paragraph</p>
<section id="yellow">
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Aut doloremque repellendus eligendi, dolorem vel sapiente harum repellat voluptatum hic, officiis perspiciatis dolor labore maiores cumque eos necessitatibus non ex, fuga.</p>
</section>
<section id="top_casino_offer">
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Aut doloremque repellendus eligendi, dolorem vel sapiente harum repellat voluptatum hic, officiis perspiciatis dolor labore maiores cumque eos necessitatibus non ex, fuga.</p>
</section>
</div>
hope this helps :)

Hardcode element position in CSS for non-JavaScript-users

I have a HTML-Document which is structured as shown in the following figure:
The red blocks which represent the text of the sidenotes are placed relatively to the footnote numbers in the text using CSS. If the text has many sidenotes and/or the texts of the sidenotes are long, the sidenotes overlap. To prevent such a behaviour I am using JavaScript to set the top margin of these elements in order to shift them downwards.
To prevent that the website is not usable without JavaScript enabled, I would like to hardcode the top margin value of the elements that need shifting down in the CSS-file. To take into account the different screen resolutions, I thought of using the CSS #media-query to set different top margins for other screen resolutions.
Example:
#media(min-width: 80em) {
.container { width: 40em; }
#sidenote-45 { margin-top: 15px; }
[...]
}
#media(min-width: 60em) {
.container { width: 30em; }
#sidenote-56 { margin-top: 28px; }
#sidenote-89 { margin-top: 12px; }
[...]
}
[maybe more #media-queries for other screen sizes]
What do you think about this approach?
You can use absolute position relative to the container to place the notes at the left or right of the div and if you don't set top property the box maintains in its position aligned with the number. Something like this:
.container {
border: solid 2px black;
background: white;
width: 30%;
margin: 20px auto;
position: relative;
}
sup {
color: red;
}
.notes {
position: absolute;
left: -220px;
color: black;
display: block;
background: #8ac88a;
width: 200px;
font-size: 14px;
padding: 5px;
margin-top: -10px;
}
.right {
left: auto;
right: -220px;
}
<div class="container">
Lorem ipsum dolor sit amet, consectetur adipisicing elit. In dolorum voluptate provident doloremque aperiam laboriosam ea, vel nihil illum, beatae nemo mollitia possimus, velit<sup>1<span class="notes">Lorem ipsum dolor sit amet, consectetur adipisicing elit. Delectus, et!</span></sup> sapiente nobis! Expedita possimus incidunt nam laudantium corrupti eaque, eveniet fuga perferendis, enim praesentium vero voluptatibus adipisci, dicta blanditiis aliquid asperiores accusantium. Provident voluptate explicabo necessitatibus eos sequi
modi non in nesciunt, debitis alias architecto doloremque sed<sup>2<span class="notes right">Lorem ipsum dolor sit amet, consectetur adipisicing elit. Delectus, et!</span></sup> quam voluptatem aut dolorem officia ipsa eum dicta optio delectus ullam
aliquam! Dicta rerum praesentium, laudantium suscipit earum, voluptates placeat totam aperiam non atque consequatur cupiditate neque! Reiciendis consectetur quo, alias facilis officia totam illo minus? Vitae distinctio culpa nesciunt voluptate tempore!
Error enim aperiam odio debitis culpa excepturi, minus molestias inventore amet recusandae<sup>3<span class="notes">Lorem ipsum dolor sit amet, consectetur adipisicing elit. Delectus, et!</span></sup> fugit sit quasi qui ipsum. Aperiam quaerat tenetur,
voluptatibus eaque. Voluptatum veniam, nihil accusamus nesciunt nobis dolore cumque amet asperiores qui, ducimus iusto voluptatibus.

Floating menu fixed [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 7 years ago.
Improve this question
I want to create a floating menu that will stay on top when scrolling. I found some examples and was able to replicate them and it now works.
However, the problem is that as you can see in the example, when I scroll, the text below the menu when scrolling "jumps up", it is difficult to explain what I mean, but if you look at it, you will immediately see what the problem is. Could anyone help me with fixing this?
Add .sectionHeading a dynamic margin:top equal to the height of the menu, with the same event that triggers the fixed class.
You need to do this on a trial and error basis. And you need to change a static parent. Check this example and follow it.
Snippet
$(function () {
$(window).scroll(function () {
if ($(window).scrollTop() > 125)
$("body").addClass("fixed");
else
$("body").removeClass("fixed");
});
});
* {font-family: 'Segoe UI'; margin: 0; padding: 0; list-style: none;}
h1, h2 {font-weight: normal;}
h1 {font-size: 1.5em;}
h2 {font-size: 1.25em;}
h1, h2, p {margin: 0 0 15px;}
.fixed {padding-top: 42px;}
.fixed .static {position: fixed; top: 0; width: 100%; background: #fff; padding-bottom: 15px;}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<h1>Static Header Example</h1>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. At, cumque inventore laudantium quod, vel pariatur dolore obcaecati veniam aspernatur aliquam ad dolorum possimus illo facilis et totam nam unde, sint?</p>
<h2 class="static">This is gonna be Static!</h2>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Officiis tempore praesentium eos odio nobis dignissimos labore expedita corrupti sapiente perferendis consequuntur, in, eveniet error! Officiis iste architecto eos? Deserunt, delectus!</p>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Velit, blanditiis dolore ipsum odit sint delectus assumenda excepturi dolor rem aperiam magni eligendi quidem suscipit nam ullam porro tenetur tempora ut!</p>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Officiis tempore praesentium eos odio nobis dignissimos labore expedita corrupti sapiente perferendis consequuntur, in, eveniet error! Officiis iste architecto eos? Deserunt, delectus!</p>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Velit, blanditiis dolore ipsum odit sint delectus assumenda excepturi dolor rem aperiam magni eligendi quidem suscipit nam ullam porro tenetur tempora ut!</p>
When you're changing the class of the your menu from default to fixed the height of your document will reduce by the height of your menu because you have changed the display of your menu.
The solution is that when you change the class of the menu from default to fixed you can add some padding to your document's body (the height of the menu element is fine) and remove the padding when changing the class of the menu from fixed to default.
$(function(){
var menu = $('#menu'),
pos = menu.offset();
$(window).scroll(function(){
if($(this).scrollTop() > pos.top && menu.hasClass('default')){
menu.hide(1, function(){
$(this).removeClass('default').addClass('fixed').show(1);
$('body').css('padding-top', '111px');
});
} else if($(this).scrollTop() <= pos.top && menu.hasClass('fixed')){
menu.hide(1, function(){
$(this).removeClass('fixed').addClass('default').show(1);
$('body').css('padding-top', '0');
});
}
});
});
You can add another div like your menu but with class="fixed" and display: none, when the scroll reaches the top of the page, you can show that div and change the visibility of the #menu from visible to hidden.

Categories

Resources