I am trying to make a header for a website where the header changes to different colors at different positions on the page.
Trying to get blue color background for header if the page is scrolled down with less than 40 pixels. And then red color background for header if the page is scrolled down between 40 pixels and 100 pixels. And then when the page is moved completely up, the header background is a yellow color.
Edit 1:
In short, Trying to make a sticky header change colors at different positions of the scroll on a page.
Edit 2:
Tried a new way of putting conditions. Updated the below code with latest working sticky header.
My problem is, when the header goes to the top position, it doesn't change back to orange color
So far I have got this code.
JS Fiddle
jQuery(document).ready(function($){
var mywindow = $(window);
var transoffset = $('#stickyheaders').offset().top;
var mypos = mywindow.scrollTop();
mywindow.scroll(function() {
if (mypos > 40) {
if(mywindow.scrollTop() > mypos)
{
$('#stickyheaders').addClass('headerup');
}
else
{
if(mywindow.scrollTop() < 155) {
$('#stickyheaders').addClass('headertranspup');
} else {
//$('#stickyheaders').removeClass('headerup');
$('#stickyheaders').addClass('headerstyleup');
}
}
}
mypos = mywindow.scrollTop();
});
});
body { margin: 0; }
section {
height: 2000px;
padding-top: 100px; }
#stickyheaders{
background: orange;
-webkit-transition: transform 0.34s ease;
transition : transform 0.34s ease;
}
.headerup{
position: fixed;
top:0; left:0;
width: 100%;
background: orange !important;
//transform: translateY(-110px);
//adjust this value to the height of your header
}
.headerstyleup{
background-color: blue !important;
}
.headertranspup{
background-color: red !important;
}
.headertranpup{
background-color: yellow !important;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.10.1/jquery.min.js"></script>
<section>
<div id="stickyheaders">This div will stick to the top</div>
</section>
The easiest solution for a problem like this is by assigning background-colour to the header directly in the element property using jquery rather than adding a new class with the same css property like background-colour in this case.
jQuery(document).ready(function($){
var mywindow = $(window);
var mypos = mywindow.scrollTop();
mywindow.scroll(function() {
if (mypos > 40) {
if(mywindow.scrollTop() > mypos)
{
$('#stickyheaders').addClass('headerup');
//$('#stickyheaders').addClass('headertranpup');
$('#stickyheaders').css("background-color","orange");
}
else
{
if(mywindow.scrollTop() < 75) {
$('#stickyheaders').removeClass('headerup');
$('#stickyheaders').css("background-color","transparent");
}
else
{
$('#stickyheaders').css("background-color","blue");
}
}
}
mypos = mywindow.scrollTop();
});
});
body { margin: 0; }
section {
height: 2000px;
padding-top: 100px; }
#stickyheaders{
-webkit-transition: transform 0.34s ease;
transition : transform 0.34s ease;
}
.headerup{
position: fixed;
top:0; left:0;
width: 100%;
adjust this value to the heigt of your header*/
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<section>
<div id="stickyheaders">This div will stick to the top</div>
</section>
Related
I want my navbar to be transparent, but when the user scrolls a bit I want it to change to a solid color and I am using bootstrap for the navbar, I have done the code that is needed with javascript.
I had this javascript in my HTML file, but it doesn't seems to work and I don't really know why
<script>
var myNav = document.getElementById("mynav");
window.onscroll = function() {
use strict";
if (document.body.scrollTop >= 100) {
myNav.classList.add("scroll");
} else {
myNav.classList.remove("scroll");
}
};
</script>
and I have also added the CSS code.
.scroll {
background-color: transparent !important;
transition: all 0.5s ease-in;
}
I don't know why it doesn't work, it is not displaying any errors, I have also manually put the class and it worked so the problem is from the js code and not the CSS.
Use scrollY property of Window object.
See the Snippet below:
var myNav = document.getElementById("mynav");
window.onscroll = function() {
if (window.scrollY >= 100) {
myNav.classList.add("scroll");
} else {
myNav.classList.remove("scroll");
}
};
.scroll {
background-color: transparent !important;
transition: all 0.5s ease-in;
}
.main-container{
height: 1000px;
}
#mynav{
position: fixed;
background-color: gray;
height: 50px;
margin:0 auto;
top: 0;
bottom:0;
line-height: 50px;
padding:5px;
width: 100%;
}
<div class="main-container">
<div class="mynav" id="mynav">
Hello World! this is mynav
</div>
</div>
Try using window.scrollY instead of document.body.scrollTop.
if (window.scrollY >= 100)
You can also use document.documentElement.scrollTop. It's the html element that actually scrolls, not the body. Typically document.body.scrollTop will always be 0.
I know how to make the navigation bar fading into the viewport from the top.
$(document).scroll(function () {
var x = $(window).scrollTop();
console.log(x)
if (x > 699) {
$("header").addClass("fix");
} else {
$("header").removeClass("fix");
}
});
.fix {
position: fixed;
background:#fff;
-webkit-animation: test .5s linear;
}
.fix + main {
padding-top: 100px;
}
#-webkit-keyframes test {
from { top:-100px }
to { top:0 }
}
When it removes the class, it just disappears.
How can i make fade out back to the top?
I log it into console only for testing. (Yes, i wrote the code, it's not copy paste.)
There is no need to use keyframes here, a simple transition will do the trick
You need to put the position fixed and the original top value on the header itself and only update the animated value when scrolling.
The issue you had before was you had position fixed on the fix class, as soon as you remove the fix class, your element is no longer fixed so it will disappear without any animations. In other words, it can only animate if you had the fix class on it.
https://jsfiddle.net/19qdtL3L/
I edited the scroll value so it will show up sooner
$(document).scroll(function() {
var x = $(window).scrollTop();
console.log(x)
if (x > 300) {
$("header").addClass("fix");
} else {
$("header").removeClass("fix");
}
});
header {
top: -100px;
position: fixed;
transition: top 0.5s;
}
.fix {
background: green;
top: 0;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<header>header element</header>
<br><br><br><br><br>
<br><br><br><br><br>
<br><br><br><br><br>
<br><br><br><br><br> <br><br><br><br><br> <br><br><br><br><br>
<br>sdfdsf
Your actual keyframe is only going one way : down (top: -100px to top: 0). What you want to do can't work like this.
You could do this without a keyframe, only with a transition :
$('button').on('click',function(){
$('div').toggleClass('shown');
});
div{
position: static;
top: -50px;
left: 0;
width: 100%;
height: 50px;
background-color: red;
transition: all .5s;
}
div.shown{
top: 0;
}
button{
margin-top:100px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div></div>
<button>Click me</button>
I want to add a class to header after (gray)section scroll is over. And remove the same class when (gray)section reappers on scroll-up.
https://jsfiddle.net/tgLybw2e/1/
$(window).scroll(function(event){
didScroll = true;
});
You can use a window.onscroll function along with window.scrollY to detect when the screen has scrolled to the bottom of the gray element, then add a class.
This could be made more dynamic by using JS to get the height of the gray element so it doesn't need to be hardcoded to the same value as set in CSS.
window.onscroll = function() {
var header = document.getElementById('header');
if (window.scrollY > 630) {
header.classList.add('updated-class');
} else {
header.classList.remove('updated-class');
}
}
header{
height: 70px;
border-bottom: 1px solid #000;
position: fixed;
color: #fff;
left:0;
right:0;
text-align:center;
}
header.changeColor{
color: 000;
}
section{
height: 700px;
background: #cdcdcd;
}
section + section{
background: #fff;
}
.red{
background:red;
}
.updated-class {
background-color: red;
transition: background 1s linear;
}
<header id="header">
abcfdff
</header>
<section>
</section>
<section>
</section>
<section class="red">
</section>
Try this,
$(window).scroll(function(event){
if (window.scrollY > 700) {
$('header').addClass('changeColor');
}else
$('header').removeClass('changeColor');
});
jsFiddle for the same
https://jsfiddle.net/tgLybw2e/2/
step one1
On window load add class to header & count height of gray section
step 2
On event window scroll count scroll Y of window
step 3
create function to compare gray height = window scroll Y,
when its true, remove class from header.
I'm using Stick-Kit to keep some images in place while scrolling, and it seems to be affecting another script that initiates a CSS animation by adding a class to a div when it enters the viewport. I assume the Sticky-Kit script is 'reseting' the other, as the animation only occurs once when Sticky-Kit is removed. The issue is visible when the animated div gets to the top of the screen. How do I ensure the animation occurs only one time (when it first appears in the viewport)?
http://codepen.io/SeanLindsay1/pen/ZBVyLZ
HTML
<div id="bg">
<h2 class="header-title"><span>HEADER</span></h2>
<div id="pic1">
1
</div>
<div id="pic2">
2
</div>
<div id="pic3">
3
</div>
</div>
CSS
/* STICKY-KIT */
#bg {
background-color: white;
width:100%;
height:1500px;
padding:0;
margin:0;
font-size:30px
}
#pic1 {
position:relative;
width:60% ;
height:500px;
background-color:blue;
}
#pic2 {
position:relative;
width:60% ;
height:500px;
background-color:green;
}
#pic3 {
position:relative;
width:60% ;
height:500px;
background-color:red;
}
/* HEADER TITLES */
.header-title span {
display: inline-block;
position: relative;
}
.change:after {
content: " ";
position: absolute;
height: 5px;
border-bottom: 1px solid #bebebe;
-webkit-animation: extend .1s 1 forwards;
animation: extend 1s 1 forwards;
margin-left: 4px;
top: 1.2em !important;
}
#-webkit-keyframes extend {
0% {
width: 0;
}
100% {
width: 200px;
}
}
#keyframes extend {
0% {
width: 0;
}
100% {
width: 200px;
}
}
jQuery
// Check to see if element is in viewport
function isElementInViewport(elem) {
var $elem = jQuery(elem);
// Get the scroll position of the page.
var scrollElem = ((navigator.userAgent.toLowerCase().indexOf('webkit') != -1) ? 'body' : 'html');
var viewportTop = jQuery(scrollElem).scrollTop();
var viewportBottom = viewportTop + jQuery(window).height();
// Get the position of the element on the page.
var elemTop = Math.round( $elem.offset().top ) + 200 ;
var elemBottom = elemTop + $elem.height();
return ((elemTop < viewportBottom) && (elemBottom > viewportTop));
}
// Check if it's time to start the animation
function extendLine() {
var $elem = jQuery('.header-title span').each(function() {
var $elem = jQuery(this);
// If the animation has already been started
if ($elem.hasClass('change')) return;
if (isElementInViewport($elem)) {
// Start the animation
$elem.addClass('change');
}
});
}
// Capture scroll events
jQuery(window).scroll(function(){
extendLine();
});
$("#bg").stick_in_parent();
$("#text").stick_in_parent({offset_top: 390});
$("#pic1").stick_in_parent();
$("#pic2").stick_in_parent();
$("#pic3").stick_in_parent();
If possible, you can use a CSS Transition instead of an Animation. It'll have better browser support, and will work. I can't really find out what's happening in your code, but if you change a couple of lines, it'll work as expected.
Here is a forked codepen: http://codepen.io/ddanielbee/pen/BQbQqj
Here are the specific lines:
.header-title span::after {
content: " ";
transition: all 1.5s ease-out;
width: 0;
}
.header-title span.change::after {
position: absolute;
height: 5px;
border-bottom: 1px solid #bebebe;
width: 200px;
margin-left: 4px;
top: 1.2em !important;
}
Removing this line of code:
$("#bg").stick_in_parent();
ensures that the header text block is not influenced by Stick-Kit and eliminates the problem of repeated execution of the animation, as shown in this codepen.
I haven't observed any ill effects caused by that change, but I cannot guarantee that there aren't any, since I don't know why this line was in the original code.
I have a hamburger (three horizontal bars) icon I want to change from float: left to float:right but with a smooth animation.
I can't use jQuery but I can use JavaScript so I have this small function that changes float state when the image is clicked:
var menuButton = document.getElementById('menu-button');
menuButton.onclick = function () {
menuButton.style.float = "right";
}
So this works but not smooth animation how can I make it a smooth animation?
A running demo:
var menuButton = document.getElementById('menu-button');
menuButton.onclick = function () {
menuButton.style.float = "right";
}
nav {
background: pink;
height: 60px;
}
nav #menu-button {
margin: 20px 24px;
display: inline;
float: left;
}
<nav id="nav-bar">
<img id="menu-button"alt="menu icon" src="images/toggle-open.svg">
</nav>
If you know the width of your container, do not use float properties but margin-left :
a {
margin-left: 0;
transition: margin-left 1s ease-in-out;
}
a.right{
margin-left: 400px; /* change for good value */
}
Then add right class to your a element with javascript
https://jsfiddle.net/rd4h4s5h/
Unfortunately, changing left-to-right float can't be simply animated with any current tech, because an animation requires a relative anchor-point from which to perform calculations.
What you could do is animate the relative left-floated position, to an approximated right-floated position (by increasing left-margin, for example), and upon completion, change to a right-float. But really, the last step isn't necessary, except to handle future layout changes to the page (e.g. window resize, for a fluid-width site).
I was able to get this working using CSS3 transitions and marginLeft.
There's a little hackery in the parentElement.parentElement (to climb two levels of the DOM tree), and in the -44px to account for the icon width plus margin width, but if you wanted to, you could write more complex coded solutions to these (handling the element's actual width / margin on the fly).
var menuButton = document.getElementById('menu-button');
menuButton.onclick = function () {
var left = menuButton.parentElement.parentElement.clientWidth - 44;
menuButton.style.marginLeft = left+"px";
window.setTimeout(function() {
menuButton.style.float = "right";
}, 1000);
}
nav {
background: pink;
height: 60px;
}
nav #menu-button {
margin: 20px 24px;
display: inline;
float: left;
/* Width and height hack to represent missing image's height and width */
width: 20px;
height: 20px;
/* CSS Transition added */
-webkit-transition: margin-left 1s;
transition: margin-left 1s;
}
<nav id="nav-bar">
<img id="menu-button"alt="menu icon" src="images/toggle-open.svg">
</nav>
I would do it this way:
<style>
nav {
position: relative;
}
nav a {
position: absolute;
left: 0;
transition: left 1s linear;
}
</style>
<nav id="nav-bar">
<a id="box" href="#/index"><img id="menu-button" alt="menu icon" src="images/toggle-open.svg"></a>
</nav>
<script>
const navBar = document.getElementById("nav-bar");
const box = document.getElementById("box");
const menuButton = document.getElementById("menu-button")
menuButton.addEventListener("click", (e) => {
box.style.left = (navBar.offsetWidth - box.offsetWidth) + "px";
});
</script>