Change CSS After Scrolling - javascript

I have a navbar that uses some CSS to change the opacity:
.navbar {
background-color: #4B5253;
opacity: 0.8;
filter: alpha(opacity = 80);
}
I need the opacity to change to 1.0 after the user scrolls down a certain number of pixels, for example, 500px.
I'm using jQuery, but I didn't find a solution.
Also, I'm not good with JavaScript, and sometimes I don't know where should I put my code. So if is there any way to do it all with CSS, it will be great!
Here is an example of what I want—pay close attention to the header as you scroll down.

If you want a native solution then use this:
function changeCss () {
var bodyElement = document.querySelector("body");
var navElement = document.querySelector("nav");
this.scrollY > 500 ? navElement.style.opacity = .8 : navElement.style.opacity = 1;
}
window.addEventListener("scroll", changeCss , false);
here is a live demo
function changeCss () {
var bodyElement = document.querySelector("body");
var navElement = document.querySelector("nav");
this.scrollY > 500 ? navElement.style.opacity = .8 : navElement.style.opacity = 1;
}
window.addEventListener("scroll", changeCss , false);
body{
background-color: white;
height: 1000vh
}
nav{
position:fixed;
top:0;
left:0;
width:100%;
text-align: center;
background: blueviolet
}
nav li{display: inline-block}
nav a{
padding: 10px 12px;
color: white;
text-transform:uppercase;
text-decoration: none
}
<nav class="menu">
<ul>
<li>Home</li>
<li>About</li>
<li>Contact</li>
</ul>
</nav>

I wrote CSS for class a, then class b.
In .a, opacity was 0.8 and in .b the opacity was 1.0. With jQuery, I just changed the element's class:
.a {
opacity: 0.8;
}
.b {
opacity: 1.0;
}
$(window).scroll(function () {
var $heightScrolled = $(window).scrollTop();
var $defaultHeight = 500;
if ($heightScrolled < $defaultHeight) {
$('#mynav').removeClass("b")
$('#mynav').addClass("a")
}
else {
$('#mynav').addClass("b")
}
});

The easiest way to accomplish what you're trying to do is a combination of some simple jQuery and CSS transitions.
We will use JavaScript to check for the windows scroll position on every scroll event and compare it to the distance of the bottom of the #main element; if the scroll position is greater, then we'll apply a class to the body to indicate we have scrolled past #main, and then we will use CSS to define the nav styling for that state.
Change the CSS code so it changes opacity when it's past #main.
// get the value of the bottom of the #main element by adding the offset of that element plus its height, set it as a variable
var mainbottom = $('#main').offset().top + $('#main').height();
// on scroll,
$(window).on('scroll', function() {
// we round here to reduce a little workload
stop = Math.round($(window).scrollTop());
if (stop > mainbottom) {
$('.nav').addClass('past-main');
} else {
$('.nav').removeClass('past-main');
}
});
.nav {
background-color: transparent;
color: #fff;
transition: all 0.25s ease;
position: fixed;
top: 0;
width: 100%;
background-color: #ccc;
padding: 1em 0;
/* make sure to add vendor prefixes here */
}
.nav.past-main {
background-color: #fff;
color: #444;
}
#main {
height: 500px;
background-color: red;
}
#below-main {
height: 1000px;
background-color: #eee;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<nav class="nav">
[logo]
</nav>
<div id="main">#main</div>
<div id="below-main">#below-main</div>

Related

Navigation sliding line on hover (and active state)

I'd spinning this off this original post: https://stackoverflow.com/a/65040903/1406440
I used something similar years ago (https://codepen.io/moy/pen/pZdjMX) but it uses a lot of jQuery in comparison. So I was wondering if I can amend the example in the original post to achieve the same effect. Which would mean...
Updating so that if there was an 'active' item, the line is already visible and moves from that location.
Is it possible to apply to a class rather than id?
With the above in mind, could this be applied in two separate places or would I need to duplicate the code?
Finally I wonder if we could use a :before or :after class so I don't have a div floating in the ul?
const navBar = document.getElementById("nav");
const navCursor = navBar.querySelector('.cursor');
const navItems = navBar.querySelectorAll('li');
function handleMouseEnterNavItem(event) {
// executed when mouse enter a navigation item
// update cursor to match position and size of target
const { offsetLeft, clientWidth } = event.target;
navCursor.style.left = offsetLeft + 'px';
navCursor.style.width = clientWidth + 'px';
}
navItems.forEach((navItem) => {
navItem.addEventListener('mouseenter', handleMouseEnterNavItem);
});
ul {
position: relative;
}
ul li {
font-family: sans-serif;
text-decoration: none;
color: gray;
margin: 22px 10px 10px;
display: inline-block;
padding: 0; /* note: padding will be underlined */
}
ul .cursor {
background: blue;
height: 1px;
position: absolute;
bottom: 0;
z-index: 10;
transition: .16s all 0.025s;
}
ul a {
text-decoration: none;
}
<ul id="nav" class="tabs-nav">
<li class="active">News</li>
<li>Activities</li>
<li>Search</li>
<li>Time</li>
<div class="cursor"></div>
</ul>

Animate toolbar background colour when scrolled down

I have a fixed tool bar with a dark background colour on top of my page with the following code.
/*html*/
<div class="floating-header-div">
<md-toolbar>
<a>Login</a>
</md-toolbar>
</div>
/*css*/
.floating-header-div {
position: fixed;
z-index: 999;
width: 100%;
}
md-toolbar {
background-color : rgb(55,58,60);
}
What I want to achieve is that the tool bar starts off with transparent background colour when the page is not scrolled. (So I only see the login link)
As the user scroll down abit more (past a certain section), the background color of the toolbar appears. Preferably animated.
How can I achieve this. I am using Angular 2 so preferably nothing too fancy like using document or jquery
Use (scroll)="onScroll($event) to catch the scroll event and with #ViewChild access the toolbar. With a simple validation toogle when your toolbar has to be transparent:
<div #content class="content">
<md-toolbar class="toolbar" color="{{ setColor ? 'primary' : 'accent' }}">
<span>Login</span>
</md-toolbar>
<div class="topimage"></div>
<p>Content</p>
</div>
#ViewChild('content') content;
setColor = false;
onScroll(event) {
this.setColor = this.content.nativeElement.getBoundingClientRect().top < -64;
}
I am not very good with Angular 2 animations but you can do it with CSS3:
.mat-toolbar{
-webkit-transition: background-color 400ms linear;
-ms-transition: background-color 400ms linear;
transition: background-color 400ms linear;
}
Here is a working example: https://plnkr.co/edit/emKv4YXGEGiRj8lyaWgr?p=preview
this should help you, you may need to modify this to suit your needs.
/*for setting navigation bar colour*/
$(document).ready(function(){
var scroll_start = 0;
var nav_element = $(".navbar");
var startchange = $('#my_element'); // element to start change when it reaches the top
var nav_element_height = nav_element.outerHeight();
var startchange_offset = startchange.offset().top;
var offset = Math.round(startchange_offset - nav_element_height);
$(document).scroll(function() {
scroll_start = $(this).scrollTop();
if(scroll_start > offset) {
nav_element.addClass('navbar-bg-color');
} else {
nav_element.removeClass('navbar-bg-color');
}
});
});
Try something like this :)
app = angular.module('myApp', []);
app.directive("scroll", function ($window) {
return function(scope, element, attrs) {
angular.element($window).bind("scroll", function() {
if (this.pageYOffset >= 50) {
scope.boolChangeClass = true;
} else {
scope.boolChangeClass = false;
}
scope.$apply();
});
};
});
body { margin: 0; background: lightgrey; min-height: 900px;}
.header {
background: transparent;
height: 70px;
padding: 24px;
box-sizing: border-box;
position: fixed;
right: 0;
left: 0;
top: 0;
z-index: 150;
font: 18px sans-serif;
color: white;
transition: all .25s ease-out;
}
.min .header { height: 50px; padding: 14px 24px; background: rgb(55,58,60);}
img{
width: 100%;
position: fixed;
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.0.4/angular.min.js"></script>
<html>
<head>
<meta charset="UTF-8" />
<title>Document</title>
</head>
<body ng-app="myApp" scroll id="page" ng-class="{min:boolChangeClass}">
<div class="header">Header Title</div>
<div class="content">
<img src="https://images.pexels.com/photos/115045/pexels-photo-115045.jpeg?w=940&h=650&auto=compress&cs=tinysrgb">
</div>
</body>
</html>

Animating height property :: HTML + CSS + JavaScript

I have noticed this 'issue' lately when trying some stuff.
Say I want to create a drop-down menu or an accordion.
This is my HTML:
<div class="wrapper" onclick="toggle()">
I want to be animated!
<div class="content">
Was I revealed in a timely fashion?
</div>
</div>
Stylesheets:
.wrapper {
background: red;
color: white;
height: auto;
padding: 12px;
transition: 2s height;
}
.content {
display: none;
}
.content.visible {
display: block;
}
JavaScript:
function toggle () {
var content = document.getElementsByClassName('content')[0];
var test = content.classList.contains('visible');
test ? content.classList.remove('visible') :
content.classList.add('visible');
}
I am trying to achieve a nice, smooth animation when we toggle the state of the content. Obviously this does not work. Anyone can explain to me why it does not work and how to fix it? Many thanks.
Link to the JSFiddle.
First things first, some CSS properties CANNOT be transitioned, display is one of them, additionally only discrete values can be transitioned, so height: auto cannot as well.
In your case the problem is with height: auto, while there are a few hacks for doing this, if you are just showing and hiding stuff, why not add, and use jQuery's toggle instead?
$(".content").toggle("slow");
jsFiddle
--EDIT (without jQuery)--
Because it's the auto that is giving us problems, we can use javascript to replace auto with a value in pixels and then use the css transition normally, if your content doesn't have a scroll, we can easily take that value from the scrollHeight property:
function toggle () {
var content = document.getElementsByClassName('content')[0];
var test = content.classList.contains('visible');
console.log(test);
if (test) {
content.classList.remove('visible')
content.style.height = "0px";
} else {
content.classList.add('visible');
content.style.height = content.scrollHeight + "px";
}
}
Css
.wrapper {
background: red;
color: white;
height: auto;
padding: 12px;
transition: 2s height;
}
.content {
height: 0px;
display: block;
transition: 2s height;
overflow: hidden;
} /* totally removed .content.visible */
jsFiddle

I can't get my navigation to change on scroll

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>

jQuery or JS, make element leave the screen on bottom and enter on top

I'we been searching for solution but couldn't find any similar. As title said, I have navigation absolute positioned on very bottom of screen, but when user reach bottom, I want navigation to "slide down", and show on top.
My logic was to see which screen height user got so I can animate only one css property.
Here's the code I wrote that doesn't work
if ( (topDistance-10) < scrollTop ) {
//Navigation control
var navHeight = $(window).height();
$(".navigation").animate({bottom: -64},600).delay(1000).css('bottom' , navHeight).delay( 3500 ).animate({bottom: navHeight - 64},600);
}
HTML:
<ul class="navigation stickBottom">
<li data-slide="1">home</li>
<li data-slide="2">truth</li>
<li data-slide="3">about</li>
<li data-slide="4">contact</li>
</ul>
css:
.navigation {
position: fixed;
z-index: 3;
bottom: 0;
width: 100%;
left: 0;
padding: 15px 0 15px 20px;
background-color: rgba(0, 0, 0, 0.75);
}
.navigation li{
color:#fff;
display: inline-block;
padding: 0 10px;
line-height:30px;
margin-bottom:2px;
font-weight:bold;
-webkit-transition: all .2s ease-in-out;
text-align:left;
font-size:26px;
}
Try to use like this
var body = $("html, body");
body.animate({scrollTop:0}, '500', 'swing', function() {
alert("Finished animating");
});
See this example http://jsfiddle.net/hellosze/MMgXu/
Ok, thanks for help, this is what I need
// 1. Hide On Bottom
$(".navigation").animate({bottom: -64},200);
// 2. Switch to top
setTimeout(function() {
$(".navigation").attr('style' , 'bottom:' + navHeight + 'px');
},300);
// 3. Show on top
setTimeout(function() {
$(".navigation").animate({bottom: navHeight - 64},200);
},400);

Categories