Element changes place when position fixed applied - javascript

When I apply position: fixed with Javascript my element moves a few pixels down and gets fixed in another position, some pixels down, instead of just staying where is was.
Why is this?
// html
<div id="container">
<div id="myDiv"></div>
</div>
// CSS
#container {
height: 2000px;
}
#myDiv {
margin-top: 50px;
width: 100px;
height: 50px;
background-color: #88a;
}
// Javascript
myDiv.style.position = 'fixed';
I find this behaviour at least in Chrome and FF.
http://jsfiddle.net/bSM8h/

When you apply position:fixed, also do:
pin.addEventListener('click', function () {
myDiv.style.position = 'fixed';
myDiv.style.top = '50px';
myDiv.style.marginTop = '0';
});
http://jsfiddle.net/bSM8h/2/
*edit*
By default browsers do body{padding:5px;} that is why a good idea is to html5boilerplate your css's
*end edit*
For some reason (see explanation here), margin-top also pushed the container with it. Once applied position:fixed, the container sprung back to the top of the page (lost the margin) and was positioned 5px from the top of page.
before position:fixed
after position:fixed

Just add this to your CSS:
body {
margin:0;
padding:0;
}
This will prevent the extra padding added by the browser defaults.

Related

How to remove a div but prevent the scroll position to be changed?

What do i want to achive?
I want to remove a div which isnt visible(for the user not the css atribute) anymore on the screen because i let the html and body scroll to a div with jquery(scrollTop). Now i want to remove the div which was visible beforr i scrolled down with jquery.
Edit: After removing the .header div, the #begining should be the top of the page and the .header div should be removed forever.
What is the problem?
After i scrolled down and removed the div with the following line of code: $('.header').css('display','none'); the scroll position changes.
Code to scroll down and remove the div.
function scrollToBegining(){
$('html, body').animate({
scrollTop: $("#begining").offset().top
}, 750);
setTimeout(function(){
$('.header').css('display','none');
},750);
}
Problem visualized:
GIF of the problem (Watch to understand better)
This is odd, but I think a better choice is to slideUp the div instead of scrolling:
function scrollToBegining(){
$('.header').slideUp(750);
}
Obviously, rename the function since it's no longer scrolling.
You can use visibility: hidden to hide the div but reserve its space. Also, sometimes the scroll position has to be changed when you use display: none.
visibility: hidden
is what you are looking for, but another solution I use with this kind of issue is instead of scrolling down to your second div, have the initial div shrink its height in a uniform animation until it is 0. This prevents the weird shuddering scroll issue you are experiencing
document.querySelector('#header h1').addEventListener('click', closeHeader)
function closeHeader(){
document.querySelector('#header').classList.add("hidden");
}
#header {
height: 300px;
width: 100%;
background: red;
text-align: center;
}
#content {
height: 1000px;
width: 100%;
background: yellow;
text-align: center;
}
.hidden {
display: none !important;
margin: 0 !important;
padding: 0 !important;
}
<div id="header">
<h1>
HEADER
</h1>
</div>
<div id="content">
CONTENT
</div>

Is scrollTop, and scrollLeft for overflow hidden elements reliable?

I accidentally discovered that scrollTop, and scrollLeft on an element work even when an element is overflow: hidden. Can this behaviour be relied on?
Supposedly scrollTop, and scrollLeft are supposed to be zero for elements without scrollbars, and setting them on such elements is supposed to have no effect.
Yes, even if an element has CSS overflow set to hidden,
Javascript Element.scrollTop(), Element.scrollLeft() allows you to manipulate the element's scroll position if the element contains overflowing children.
https://developer.mozilla.org/en-US/docs/Web/API/Element/scrollLeft
https://developer.mozilla.org/en-US/docs/Web/API/Element/scrollTop
Here's a quick use case:
Animate gallery using scrollLeft
var GAL = $("#gal"),
n = GAL.find(">*").length;
c = 0;
$("button").on("click", function(){
GAL.animate({ scrollLeft: (++c%n) * GAL.width() });
});
#gal {
height: 40vh;
overflow: hidden; /* !! */
white-space:nowrap;
font-size: 0;
} #gal>* {
font-size: 1rem;
display: inline-block;
vertical-align: top;
width: 100%;
height: inherit;
background: 50% / cover;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="gal">
<div style="background-image:url(//placehold.it/800x600/cf5);"></div>
<div style="background-image:url(//placehold.it/800x600/f0f);"></div>
<div style="background-image:url(//placehold.it/800x600/444);"></div>
</div>
<button>scrollLeft</button>
Not sure yet why Chrome does not do the following but:
Firefox will remember your gallery scroll-position on historyBack (navigating back to the page where you scrolled your gallery)

Disable body scroll but don't hide scrollbar

When I click a thumbnail, it opens a div overlay box on top:
.view-overlay {
display:none;
position:fixed;
top:0;
left:0;
right:0;
bottom:0;
overflow-y:scroll;
background-color:rgba(0,0,0,0.7);
z-index:999;
}
For browsers with non-floating scrollbars, disabling scroll with overflow: hidden removes the scrollbar causing the content to shift to the right a bit to make up for the additional space.
I want to keep the scrollbar there so that doesn't happen. There are solutions online but I can't find one that definitively works well in all browsers.
https://stackoverflow.com/a/13891717/4774917 - This answer seems to work well on Chrome, but causes weird glitchy behaviour on Safari OSX 10.10.
https://stackoverflow.com/a/8701977/4774917 - This answer causes the body to scroll back to the top (Chrome).
What's a solution that:
a) disables body scroll when the overlay is opened
b) keeps the body stay put at its original scroll position
c) keeps the scrollbar there so content doesn't shift
d) works on (most/all) browsers without glitchy behaviour?
Example: https://dribbble.com does this and it seems to work on the browsers I've tested it on (including Safari) without glitchy behaviour.
One approach that's both very simple and effective is to not have the main content in the body itself, but a wrapper that's a sibling with the overlay. With this approach you can toggle the overlay whenever necessary without affecting the scroll of the content element.
var e = document.getElementById('overlay');
document.body.onclick = function() {
e.style.display = (!e.style.display || e.style.display === 'block') ? 'none' : 'block';
};
html,
body,
#content {
height: 100%;
margin: 0;
}
#content {
overflow: auto;
}
#high {
height: 800px;
}
#overlay {
position: absolute;
height: 100%;
width: 100%;
background: rgba(0, 0, 0, 0.5);
}
<div id="overlay"></div>
<div id="content">
Long content resides in this container
<div id="high"></div>
And the long content ends here
</div>

how to stop header from scrolling at some point and make it fixed

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...

how to fix the position of div to bottom right of div containing background image

I have html sturcture
<div id="bg" class="layer">
<img id="trackmap" src="images/back_2416.jpg" width="1208" height="768" class=" ui-draggable map-icon" usemap="#main-map" data-zoom-image="images/background_zoom.jpg" data-big="images/background_zoom.jpg" style="position: relative; left: -439px; top: -272.6px; margin: 0px; display: inline-block; height: 1327.2px; width: 2088px;">
<div id="nav-text">LOREM IPSUM.</div>
</div>
Jquery
var windowHeight = $("#trackmap").height();
var windowWidth = $("#trackmap").width();
var text_height=((windowHeight)-(100));
$("#nav-text").css("top",windowHeight);
Css
.layer {
position: absolute;
width: 1208px;
height: 768px;
}
#nav-text{
z-index: 200;
color: white;
position: absolute;
font-size: 10px;
margin-left: 715px;
width: 310px;
height: 10px;
position: fixed;
bottom: 5px;}
I just want to fix the nav-text to the bottom right whatsoever.. Now i problem i am facing is theres zoom function on the trackmap.. which increases the height and width of the image ..so the text comes in between of the image ..intereferring with the image.. I have tried taking the image width height using jquery ..but somehow its not working
I am not sure I am following your issue here, but it sounds like you are trying to get a div to be in the bottom-right of another div no matter what size it is. That can be done by setting the parent div position to relative which you have, and the child div position to absolute. You have that set but then override it by setting the position to fixed lower in the CSS. You will also want to set the bottom to 0 and the right to 0.
This will position the child div to the bottom right of the parent div. Then you can get rid of your jQuery. Hopefully this helps.
Ok.. I am in a hurry to catch the bus.. but here's a fiddle that illustrates the idea..
basically you will need to use the scrolltop and left parameters to do so:
$(".container").on("scroll", function() {
$(".nav-text").css("top", $(this).prop("scrollTop") + 130);
$(".nav-text").css("left", $(this).prop("scrollLeft") + 120);
});
but move the scrolls first.. sorry I need to go now..
You can achieve this by not fixing the .layer width and height, using display:inline-block; to prevent the div from filling the whole container width. At that point, the .layer size will match the image size whatever it is.
Finally you just need to set the text to absolute position and bottom and right properties too.
.parent{
display:inline-block;
position:relative;
}
.children{
position:absolute;
bottom:0;
right:0;
}
Here is the fiddle explaining
And here is the proof it works even if the image size is changed(click on the image).
Fiddle 2

Categories

Resources