I want mynavbar to be transparent when the page is scrolled to the top, however when the user scrolls I would like it to be made opaque. I tried this with javascript, but something still isn't working.
http://jsfiddle.net/6A6qy/
function myFunction() {
if ($(window).scrollTop() < 50) {
document.getElementById("masthead").style.opacity = "0.5";
}
}
#masthead {
position: fixed;
top: 0;
left: 0;
z-index: 9999;
width: 100%;
height: 50px;
background-color: #00a087;
opacity: 1;
}
#container {
background-color: blue;
height: 1000px;
display: block;
margin-top: -50px;
}
<body onload="myFunction()">
<nav id="masthead">
<!-- Fixed navigation bar content -->
</nav>
<div id="container"></div>
</body>
How about this:
JS:
// listen for scroll
$(window).scroll( function() {
// apply css classes based on the situation
if ($(".masthead").offset().top > 100) {
$(".masthead").addClass("navbar-scrolled");
} else {
$(".masthead").removeClass("navbar-scrolled");
}
}
CSS:
.navbar-scrolled {
/* some css for navbar when scrolled */
}
JSFiddle example:
http://jsfiddle.net/8ruwnaam/
And then of course you could add some optimization to not apply the classes all the time if they are already there. But it works quite fine without such things as well.
Additional things:
The first version of this answer and your question use IDs for styling, which is not really a good idea according to a lot of people. Styling IDs goes against the DRY principles, and causes all these funny little problems when you forget to think about CSS specificity. IDs are quite alright for a lot of things when it comes to the logic in the JS or something, but try to use classes for styling.
You should create an .opaque css class and attach it based on actively scrolling or if scrollTop is < 50:
.opaque {
opacity: 0.5;
}
Then attach that class on('scroll') or at scrollTop (this is using the debounce plugin):
function myFunction() {
var $masthead = $('#masthead')
, $window = $(window);
// currently scrolling
$window.scroll($.debounce( 250, true, function(){
$masthead.addClass('opaque');
}));
// done scrolling
$window.scroll($.debounce( 250, function(){
// if at the top, add or keep opaque class
if($(this).scrollTop() < 50) {
if(!$masthead.hasClass('opaque')) {
$masthead.addClass('opaque');
}
} else {
$masthead.removeClass('opaque');
}
}));
}
You need to set it to be transparent by default (as it will be on the top) like that
#masthead {
position: fixed;
top: 0;
left: 0;
z-index: 9999;
width: 100%;
height: 50px;
background-color: #00a087;
opacity: 0.5; /*edited the opacity to be 50% by default*/
}
then use this script to achieve your needs:
$(document).ready(function () {
$(window).scroll(function(){
var ScrollTop = parseInt($(window).scrollTop());
if (ScrollTop < 100) {
document.getElementById("masthead").style.opacity = "0.5";
} else {
document.getElementById("masthead").style.opacity = "1";
}
});
});
Related
When using a combination of jQuery and CSS to trigger my navbar to shrink on scroll, it get's buggy when you scroll back up to a certain position, I have linked a video as an example.
I have tried two different methods. The first is using $(window).scrollTop) with an if statement and a series of .addClass and .removeClass. The second thing I have tried is using $(window).scrollTop) with a series of .css dynamic style modifications. Both of these attempts render the same end result that is shown in this video https://youtu.be/YXKsrL1cghs .
My first jQuery attempt:
$(document).ready(function () {
$(window).on("scroll", function () {
if ($(window).scrollTop() >= 40) {
$(".navbar").removeClass("py-5");
$(".navbar").addClass("compressed");
} else {
$(".navbar").addClass("py-5");
$(".navbar").removeClass("compressed");
}
});
});
My second jQuery attempt:
$(document).ready(function () {
$(window).on("scroll", function () {
if ($(window).scrollTop() >= 40) {
$(".navbar").css({ "padding-top": "10px" });
$(".navbar").css({ "padding-bottom": "10px" });
} else {
$(".navbar").css({ "padding-top": "3rem" });
$(".navbar").css({ "padding-bottom": "3rem" });
}
});
});
My CSS:
.navbar.compressed {
padding-top: 10px;
padding-bottom: 10px;
}
My expected results would be a smooth scrolling fixed navbar that shrinks to a smaller size after scrolling beyond a certain point.
What actually occurs is that when you scroll down past a certain point, for 20px worth of height, it gets super buggy and starts bouncing up and down. Once you clear those 20 or so px it's perfectly fine, but when you scroll back up it acts the same within those 20px.
When watching the video, I noticed that your .navbar has transition: all .3s. It could be the reason that when you remove the class py-5 and add class compressed, it triggers the transition twice.
It would be helpful if you can provide the HTML markup and CSS as well.
The script is manipulating the DOM quite a lot. I am not sure if this is going to fix your problem but it might be a good idea to only change the classes if the have not yet been applied.
$(document).ready(function() {
$(window).on("scroll", function() {
let navbar = $(".navbar");
if ($(window).scrollTop() >= 40) {
if (navbar.hasClass("py-5")) {
navbar.removeClass("py-5");
navbar.addClass("compressed");
}
} else {
if (navbar.hasClass("compressed")) {
navbar.addClass("py-5");
navbar.removeClass("compressed");
}
}
});
});
body {
height: 10000px;
position: relative;
}
.navbar {
width: 100%;
position: fixed;
height: 50px;
top: 0;
transition: all .3s
}
.py-5 {
background-color: blue;
padding-top: 10px;
padding-bottom: 10px;
}
.compressed {
background-color: red;
padding-top: 0px;
padding-bottom: 0px;
}
<html>
<head></head>
<body>
<nav class="navbar py-5">Navigation</nav>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
</body>
</html>
I know it is a repeat question, but I am trying to get my navigation bar to change styling using JavaScript/jQuery/CSS by making jQuery add and remove classes depending on the position of the scrollbar, yet with no prevail. I am a huge noob with jQuery. Could someone tell me if these is something wrong with my code. I have searched for hours and I can't find and error. Here is a working example: http://codepen.io/anon/pen/QbWOJv
And here is my code:
// on scroll,
$(window).on('scroll',function(){
// we round here to reduce a little workload
stop = Math.round($(window).scrollTop());
if (stop > 50) {
$('.nav').addClass('passed-main');
} else {
$('.nav').removeClass('passed-main');
}
.nav
{
background-color: #000000;
opacity: 0.3;
width: 100%;
height: 40px;
position: fixed;
top: 0;
z-index: 2000;
transition: all 0.3s;
}
.nav.past-main
{
background-color: #ffffff;
opacity: 1;
}
<div class="nav">
</div>
Perhaps the example is something that you want to achieve, and when you try it with your code above, it's not working.
Here's the problem with your code in the snippet:
You forgot to close the function
// on scroll,
$(window).on('scroll',function(){
// we round here to reduce a little workload
stop = Math.round($(window).scrollTop());
if (stop > 50) {
$('.nav').addClass('passed-main');
} else {
$('.nav').removeClass('passed-main');
}
}); // You forgot to close the function here
You add/remove class passed-main while in your CSS you're using class selector .nav.past-main
Your window doesn't have any scrollbar, so you need to add this to the CSS to test if it works
body {
height: 1500px;
}
You forgot to include the jQuery in the Snippet.
Here's the working updated snippet
// on scroll,
$(window).on('scroll', function () {
// we round here to reduce a little workload
stop = Math.round($(window).scrollTop());
if (stop > 50) {
$('.nav').addClass('past-main');
} else {
$('.nav').removeClass('past-main');
}
});
.nav {
background-color: #000000;
opacity: 0.3;
width: 100%;
height: 40px;
position: fixed;
top: 0;
z-index: 2000;
transition: all 0.3s;
}
.nav.past-main {
background-color: #ffffff;
opacity: 1;
}
body {
height: 1500px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.10.1/jquery.min.js"></script>
<div class="nav"></div>
I am attempting to create a navigation bar that remains fixed only after it has reached the top of the page. I have the code working so that the nav is fixed, but I can't seem to get it to scroll to the top first.
Here's the HTML:
<div id= "home"> contentcontentcontent </div>
<div id="nav">
home
go green
your area
how to</div>
And the CSS:
nav {
text-align: center;
top: 600;
z-index: 100;
position: fixed;
width: 100%;
border: 0;
margin-bottom: 0;}
fixed {
top:600;
z-index: 100;
position: fixed;
width: 100%;}
home {
overflow: hidden;}
And the jQuery:
$(document).ready(function() {
$(window).scroll(function () {
//console log determines when nav is fixed
console.log($(window).scrollTop())
if ($(window).scrollTop() > 600) {
$('#nav').addClass('fixed');
}
if ($(window).scrollTop() < 601) {
$('#nav').removeClass('fixed');
}
});
These were based off of responses to similar questions on this site, but nothing has seemed to work so far. Does anyone know what's wrong with my code?
When writing a CSS selector, ids and classes need to be prefixed by a # or a . respectively. In your CSS you have
nav { // rules }
fixed { // rules }
home { // rules }
When you should have
#nav { // rules }
.fixed { // rules }
#home { // rules }
Here is a fiddle of your code working.
I am using following code to make a menu sticky when the window is scrolled down. It works fine if the window height is enough to scroll down the full header area, but it it creates problem is the height is just close enough to scroll, in that case it starts flashing and does not let scroll.
Here is the demo of the problem, refresh couple of times and try to scroll down. I have set the body height to 622px to reproduce the problem:
http://jsbin.com/ipEROYO/1
Here's the code I'm trying:
$(document).ready(function() {
var stickyNavTop = $('.nav').offset().top;
var stickyNav = function(){
var scrollTop = $(window).scrollTop();
if (scrollTop > stickyNavTop) {
$('.nav').addClass('sticky');
} else {
$('.nav').removeClass('sticky');
}
};
stickyNav();
$(window).scroll(function() {
stickyNav();
});
});
CSS:
.sticky {
position: fixed;
width: 100%;
left: 0;
top: 0;
z-index: 100;
border-top: 0;
}
It's because when you are setting the navigation div to position:fixed you are shortening the length of the document (by the height of that div), which then causes the scroll bar to go away, which causes the scrollTop() value to be 0 which causes the .nav div to be position:static and it is an endless cycle if you keep scrolling down.
Here's my quick solution:
$(document).ready(function() {
var height = $('.nav').outerHeight();
$(window).scroll(function() {
if($(this).scrollTop() > height)
{
$('.nav').css('position','fixed');
$('body').css('padding-bottom',height+'px');
}
else if($(this).scrollTop() <= height)
{
$('.nav').css('position','static');
$('body').css('padding-bottom','0');
}
});
$(window).scroll();
});
Just modified the JSbin. Check it out. You were really close, just doing more than you needed to like setting the sticky class on load of the page rather than when the function first runs. Let me know if this helps.
try that
$(window).scroll(function () {
var scroll_top = $(this).scrollTop();
if (scroll_top > 66) {//height of header
$('.nav').addClass('sticky');
} else {
$('.nav').removeClass('sticky');
}
});
Strongly recommend a CSS only solution for this layout. No one seems to know what to call this method, so I've been referring to it as the absolute stretch technique, but in my experience it works beautifully across mobile devices and PC's including all major browsers except IE6 and below. There is some discussion of it here.
body, .header, .nav, .mainContent{
position: absolute;
top: 0;
left: 0;
right: 0;
}
body, .mainContent {
bottom: 0;
}
.header{
height: 120px;
}
.nav{
height: 70px;
top: 120px;
}
.mainContent{
top: 190px;
overflow: auto;
}
You'll find you can get very robust, concise, well organized layouts in this manner, and fixed headers, footers and sidebars follow very easily.
I've a sticked element which gets the top-alignment from current scroll-offset. Problem is, that the layout is not "retriggerd" if the space from it is free. So there stays a ghost-gap where the sticked element was...
http://fiddle.jshell.net/pPc4V/
The markup is pretty simple:
...
as well as the js:
var $win = $(this);
var sticked = document.querySelector('a.sticked');
$win.on('scroll', function () {
var scrollTop = $win.scrollTop();
sticked.style.top = scrollTop + 'px';
// $win.resize();
});
...and the css looks good so far:
a {
display: inline-block;
width: 90px;
height: 90px;
background: deepskyblue;
}
.sticked {
position: relative;
top: 0;
left: 0;
background: tomato;
}
I tried to trigger the resize-event on scroll (as you see above uncommented), but no success! Any ideas, how to retrigger the layout so that the free-gap is filled with the next floated element?
Update
To clarify what I mean I made a simple image-timelime:
Step 1
Step 2
Step 3
The issue is that you are setting position fixed on an element which is displayed inline. That will cause that space to occur. I have redid your jsFiddle with proper alignment.
To fix it, I added the class "stuck" only when the document's scrollTop position is greater than the scrollTop position of your target element.
jsFiddle: http://fiddle.jshell.net/pPc4V/44/
HMTL:
<div id="grid">
etc...
</div>
CSS:
#grid {
height:1000px;
overflow:hidden;
float:left
}
#grid > a {
display: inline-block;
width: 90px;
height: 90px;
background: deepskyblue;
}
.stuck {
position: fixed;
background: navy !important;
}
JS:
$(window).on('scroll', function () {
var $doc = $(document),
parentElement = $('#grid'),
childToGetStuck = parentElement.find('a:nth-child(5)');
if ($doc.scrollTop() > childToGetStuck.scrollTop()) {
childToGetStuck.addClass('stuck');
//console.log($('.stuck').scrollTop())
} else {
childToGetStuck.removeClass('stuck');
}
});