I have a JavaScript menu bar that is positioned on my webpage, then when the browser bar reaches the top of the menu it locks into a fixed position and moves with the window. However, i need to contain the menu within a div, how can this be done?
This is my menu bar:
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.5.1/jquery.min.js"></script>
<script type='text/javascript'>
$(window).load(function(){
$(window).scroll(function(){
if ($(window).scrollTop() >= 200)
{
$("#floatbar").css({position:'fixed',left:'0',top:'0'});
}
else
{
$("#floatbar").css({position:'absolute',left:'0',top:'200px'});
}
});
});
</script>
and this is my html:
<div id="menu_runner">
<div id="floatbar">
Issue 49<br />
Issue 48<br />
Issue 47<br />
Issue 46<br />
</div>
</div>
and my css:
#menu_runner {
width: 100px;
height: 2000px;
float: right;
position: relative;
}
#floatbar {
width: 70px;
position: absolute;
top: 200px;
}
where the menu runner is the containing div of the menu, and the floatbar obviously contains the menu which runs the JavaScript.
However when I try this code, the menu sticks to the left and 200px from the top, and not within the menu_runner div. How can i make the floatbar be positioned in the menu_runner div and then scroll down with the JavaScript within the div as it should.
Here's a live demo of my code: http://jsfiddle.net/f4dhy/
Here's one method:
Live demo
Javascript:
$(window).scroll(function() {
if ($(window).scrollTop() >= 200) {
screenWidth = $(window).width();
containerWidth = $("#menu_runner").outerWidth(true);
pos = screenWidth - containerWidth;
$("#floatbar").css({
position: 'fixed',
left: pos,
top: '0'
});
}
else {
$("#floatbar").css({
position: 'absolute',
left: '0',
top: '200px'
});
}
});
The idea is get the screen's width, the menu container's width, and from that we get figure out how to position the left edge of the menu so that it lines up with the container.
In your css, add:
body{
padding: 0;
margin: 0;
}
which fixes the slightly off positioned problem you'd see without it due to the default margin set by browsers.
You might see the menu kinda bounce into position when you scroll it to the top, which is unfortunate but hopefully not too much of a problem.
This doesn't work in IE6 because of the position:fixed being used. You'll have to search for a solution to that. I'm not too familiar with what the accepted workaround is (but a quick google search shows a few hacks that might work)
I'm curious though, any reason you want to do it this way? Why have the menu scroll with the screen and then stop at the top? Why not just fix it to one place on the screen from the start, something like this?
Related
I have two navigation in my website. Both the navigation bars are fixed. Basically when I scroll up, I would like to use the animate() and show both the navigation bar in the page. How do I get the scroll up event and use that to animate the divs, like the Google search widget. I would really appreciate your help. Thank you.
html:
<div id="navbar_header">
some link
</div>
<div id="main_content">
<p>Some content...</p>
</div>
<div id="navbar_footer">
some link
</div>
css:
#navbar_header {
background: #22313F;
position: fixed;
top: 0px;
left: 0px;
width: 100%;
height: 40px;
}
#navbar_footer {
background: #22313F;
position: fixed;
bottom: 0px;
left: 0px;
width: 100%;
height: 40px;
}
Normally using the window for the scroll event should be sufficient, as it's big enough and the one element, that's being scrolled. If jQuery is loaded correctly, you could try something like this:
$(document).ready(function(){
var lastTopPosition = 0;
$(window).scroll(function(){
var topPosition = $(window).scrollTop();
if (topPosition > lastTopPosition ){
$("#navbar_header").stop(true).animate({'top':'-40px'}, 200);
$("#navbar_footer").stop(true).animate({'bottom':'-40px'}, 200);
} else {
$("#navbar_header").stop(true).animate({'top':'0px'}, 200);
$("#navbar_footer").stop(true).animate({'bottom':'0px'}, 200);
}
lastTopPosition = topPosition;
}
});
This piece of code gets the current position from the top everytime you scroll. If the distance gets bigger (scroll down) the two bars fadeout. If it's getting smaller (scroll up) it fades in. You can replace the FadeOut/In methods here with you animate() call too. A check, if the elements are displayed would be good here too, but I guess you can figure that one out ;-)
If I understood this right, something along the lines of:
$("#main_content").scroll(function(){
$('#navbar_header').show(300);
$('#navbar_footer').show(300);
});
Where show(300) will basically do a 300ms showing animation of your divs.
If you look at the website:
http://eyeheartworld.org/pages/the-cause
and scroll down, there's an implementation of a concept I found on codepen (when you scroll down, the navigation bar scrolls and is fixed)
var header = $("#guide-template");
$(window).scroll(function() {
var scroll = $(window).scrollTop();
if (scroll >= window.innerHeight) {
header.addClass("fixed");
} else {
header.removeClass("fixed");
}
});
(http://codepen.io/simpleminded/pen/noaJj) and I just wanted a quick run through at the least of how the PICTURES on the top page are working. They scroll to the top and then stay fixed while other pictures scroll over them.
it's a simple case of adding position: fixed; to a block at the top of your HTML content. Here's a very basic example:
body{
margin: 0;
padding: 0;
}
#top-bar{
height: 40px;
width: 100%;
background-color: #000000;
color: #FFFFFF;
position: fixed;
}
#content{
height: 3000px;
padding-top: 40px;
}
<!DOCTYPE HTML>
<html>
<head></head>
<body>
<div id="top-bar"></div>
<div id="content">
AAA<br />
BBB<br />
CCC<br />
DDD<br />
EEE<br />
FFF<br />
XXX<br />
YYY<br />
</div>
</body>
</html>
It basically looks for the height of your screen with: window.innerHeight and adds a class when the amount scrolled is bigger than the height of your screen.
This is the same height as the #introscreen, which is set to 100vh with css. 100vh is basically the same as 100% (More on VH here).
So the 'navbar' is always just below the users' screen, and once you scroll this exact amount, it adds the class 'fixed' which fixes the navbar to the screen. If you scroll back the class gets removed again.
Would it be possible to have a DIV position: fixed, but if the content of that DIV extend beyond the viewing area of the screen then you could still scroll with the window? I've put everything I have thus far in this...
FIDDLE
This code sits inside a media query that gets triggered when the screen hits a max width and/or a max height, but I don't think that code is relevant to my question. This is the bit of code that I believe I need to modify to work correctly:
.expand {
display: block !important;
position: fixed;
-webkit-backface-visibility: hidden;
top: 50px;
left: 0;
background: rgba(31, 73, 125, 0.8);
width: 100%;
z-index: 999;
}
The reason I want this fixed is so the little hamburger menu stays statically in the upper left hand corner of the screen at all times, as at times the site I'm building could be rather lengthy, so I would like viewers to have a little more ease of access.
Thank you!
Yes, you just need to give the div a fixed height and the overflow: auto setting
(Demo)
.expand {
bottom: 0;
overflow: auto;
}
If you don't want to give it a minimum height, a simple (but not supported by old browsers) option would be to use css calc() like so
.expand {
max-height: calc(100% - 50px); // 100% viewport height minus the height of the nav.
}
I would suggest setting a fallback height before in case the browser does not support calc
JavaScript
To achieve what you really want you need javascript. Here it is.
Check to see if the menu is open, if not...
Define a check to see if the contents are larger than the viewport, if so then set bottom: 0px; and overflow: auto and remove scrolling from the body.
If so...
Remove all styles from the menu and the body that were added when opening the menu.
(Demo)
(function($) {
var menu = $('.responsive-menu'), open;
$('.menu-btn').click(function () {
if(!open) {
if(menu.height() > $(window).height()) {
open = true;
menu.css({'bottom': '0px', 'overflow': 'auto'});
document.body.style.overflow = 'hidden';
}
} else {
open = false;
menu.css({'bottom': '', 'overflow': ''});
document.body.style.overflow = '';
}
menu.toggleClass('expand');
});
})(jQuery);
I have a header, in which i put my h1 and h2 headings at top. The problem is that header scrolls along the scroll bar which is of course normal but i want to fixed it at some point when all the headings on header scroll away. At this point I want header to stop and stays fixed.
I already tried fixed position but of course it fixed heading as well which exactly I don't want.
I also tried this JavaScript but no luck.
JavaScript
$(window).scroll(function() {
var _height = 120 - (120 * $(this).scrollTop() / $('body').height());
if (_height >= 80) {
$('.header_container').height(_height);
}
});
and here qre my HTML and CSS codes respectively.
HTML
<div class="header_container" id="header_container">
<div id="header_titles">
<h1 class="homepage-heading">Browse</h1>
<h2 class="homepage-heading-subtle">GENRES & MOODS</h2>
</div>
</div>
CSS
#header_container {
background-color: black;
width: 100%;
height: 120px;
top: 0;
left: 0;
right: 0;
}
#header_titles {
position: absolute;
width: 100%;
font-size: 35px;
text-align: center;
padding-top: 10px;
}
So, let me see if I get this...you want your header to be scrolled normally with the page until a certain point where it becomes fixed?
EDIT
Ok, well, you could determine the element on the page that you want the position to be triggered at. Like, the top of a certain paragraph, and use that position in your condition.
var condition = $(element).offset().top;
if($(window).scrollTop > condition) { //add a fixedClassName } else { remove the fixedClassName }
and have header.fixedClassName have those proprieties ( with position fix, top 0 and width: 100% to your header etc). Be sure to add and remove a class on the body that gives it padding-top with the height of your displaced header.
Used some similar effect here http://goodmen.se/ after a point the logo shows up in the header, then there's a background change. You do something similar with your position.
EDIT 2
Here's an example fiddle http://jsfiddle.net/Corsico/vpskd8hd/
So you want a sticky header?
In your javascript create a code:
var $header_container = $('#header_container');
var header_height = $header_container.outerHeight(true);
if($(window).scrollTop() < header_height){
$header_container.removeClass('sticky');
} else{
$header_container.addClass('sticky');
}
$(window).on('scroll', function(){
if($(window).scrollTop()< header_height){
$header_container.removeClass('sticky');
} else{
$header_container.addClass('sticky');
}
});
This will add a sticky class to your header, and then you can set the header to be fixed:
.sticky{
position:fixed;
top:0;
left:0;
width:100%;
display:block;
}
This should do it. When you scroll pass the height of the header, you'll get the 'sticky' class, if not, you'll remove the sticky class...
Im trying to add a footer at the bottom of this content that doesn't overlay the content but moves it up.
The only way I can see it working would be something like, when browser is at the bottom remove 'fixed' class on the left red '#work'.
js fiddle DEMO
Updated js fiddle DEMO
HTML
<div id="header-block">
Header-block, this sits here in the background
</div>
<div id="content">
<div id="work">
This content should be fixed when at the top
</div>
<div id="description">
This content should scroll -
</div>
</div><!-- end content -->
<div id="footer">
This should appear at the bottom
</div>
CSS
body {
margin: 0px;
padding: 0px;
}
#header-block {
background: green;
width: 100%;
position: fixed;
z-index: 1;
height: 300px;
top: 0;
}
#content {
margin-top: 300px;
width: 100%;
position: relative;
z-index: 2;
}
#work {
background: red;
width: 50%;
height: 100vh;
float: left;
position: absolute;
}
#description {
background: blue;
width: 50%;
height: 1200px;
float: right;
font-size: 30px;
}
#footer {
background: black;
width: 100%;
height: 100px;
position: absolute;
z-index: 3;
bottom: 0;
}
If I understand your question correct, this should do the trick (although it depends very much on JavaScript unfortunately).
// Fix work column on scroll
contentStart = $("#content").offset().top ;
contentSize = $("#content").height() ;
window.onscroll = function(){
if( window.XMLHttpRequest ) {
var position=window.pageYOffset;
// calculate the position of the footer and the actual seen window
var docViewTop = $(window).scrollTop();
var docViewBottom = docViewTop + $(window).height();
var elemTop = $("#footer").offset().top;
if ( position > 300 && !(docViewBottom >= elemTop)) {
$('#work').css({'position':'fixed', 'top':'0', 'height':'100vh'});
} else {
// if the footer is visible on the screen
if(docViewBottom >= elemTop) {
$('#work').css({ 'top': 0 - (docViewBottom - elemTop) }); // scroll the #main div relative to the footer
} else {
$('#work').css({'position':'relative', 'top': 'auto'}) ;
}
}
}
}
For further informations about the calculations, perhaps this question on stackoverflow is useful.
Edit: Andrew Haining posted his answer in between of my answer, perhaps give his link a try and maybe it's a better (more proper) solution. Unfortunately I haven't actualised this page when I was testing your code in JSFiddle and I didn't see his answer.
If you want to use my script, make sure you can test it with different resolutions. It works just fine for my resolution in JSFiddle, I didn't test any other.
I'm not 100% sure what you want, but if you remove the position: absolute and the bottom: 0 from the footer, and put a div with class='clearboth' above the footer, it seems to do what you need.
CSS
.clearboth {
clear: both;
}
This is a drawing of what I see on your fiddle;
Do you want the red and the blue to always be touching the black?
I don't see the red overlying the black
You should use jQuery to add a class containing the position:fixed value when the scroll position of the page is less than the inline position of the #work div. Once it scrolls past the position, remove the class and have the element fall back in line.
You can achieve this using the following jQuery methods.. .scrollTop() .offset().top() and $(window).height().
This tutorial will give you an understanding of what you need to do to achieve the necessary results, you will just have to change the calculation slightly using $(window).height(), $('#footer').height() and a few other changes to get what you desire.
Based on the question you asked i think this is what you mean. The red div should be fixed when it gets to the top but be absolute when it is below the top for scrolling and the black footer should be below the red while scrolling, check this code i have done for you. just add this jquery script and run it.
<script type="text/javascript" src="js/jquery.js"></script>
<script>
$(document).ready(function() {
$(window).scroll(function () {
console.log($(window).scrollTop());
if ($(window).scrollTop() >= 322) {
$('#footer').css("z-index","1");
$('#work').css(
{
"background": "red",
"width": '50%',
'height': '100vh',
'float': 'left',
'position': 'fixed',
'top': '0'
});
}
if ($(window).scrollTop() <= 322)
{
$('#work').css(
{
"background": "red",
"width": "50%",
"height": "100vh",
"float": "left",
"position": "absolute"
});
};
});
});
</script>
If not exactly a parallax, this is somewhat close to how parallax works, containers moving at different speeds, and some containers sitting fixed or scrolling when they attain a particular top/bottom offset in the viewport.
There's plugin that can do it. Skrollr
You can use Skrollr along with skrollrcss, and it'll make sure how the containers take position on screen based on scrolltop of the window and the container specifically.