So I have a supposedly fixed-positioned element that I want to fix on the viewport at the top-right corner.
This is the HTML:
<div class = "header">
<p>This is a heading with an absolute position</p>
</div>
and the CSS:
.header {
position: absolute;
right:10px;
top: 10px;
}
It works as desired until you scroll to right with a laptop or zoom in with a mobile device. Either these two events will shift the element to left depending on the extent the events are.
I came up with 2 solutions:
1: make a div container at the top with the width as 100% and make the element relative to the container. This failed as when I scroll the window the container does not extend accordingly
2: add an event listener listening to two events scroll and touchend.
$(window).scroll(function(){
$(".header").css({"right": "10px", "top": "10px"});
});
$(document.body).bind("touchend", function(){
$(".header").css({"right": "10px", "top": "10px"});
});
I wanted to update the element at every selected event and make it always the same position relative to the viewport but this method failed too. Seems like the css will only position the element according to the original viewport
Is there a simple yet efficient solution for this issue?
If you are trying to anchor something to the viewport, use a fixed position:
position: fixed;
Related
Modern browsers seem to have a feature where the viewport sticks to bottom when page height increases. What actually happens is that browser scrolls the viewport at the same rate as height being increased when initial position is at (or very close to) the bottom of the page. This results in appearance as if page is expanding upwards instead of downwards.
How can this feature be disabled for a certain page using CSS or JS, so that the page would always visually expand downwards?
This of course, also happens when added element's height is expanded animated. For this reason, if possible, I would want to avoid resetting scroll position afterwards to prevent visible jump. The demo of this "feature" (that seems to happen only within rare conditions) interacting with the viewport and drop animation can be observed in the gif below.
I know there must be a way, otherwise every site with infinite scroll would suffer from an infinite loop. Counter argument: Chrome appears not to do this for containers that surpass certain height limit. So maybe infinite-scroll sites don't even bother addressing this in their sites.
Check this fiddle. You can observe that in Chrome, the first container snaps to the bottom, while the other divs has a scroll relative to the top. In Firefox or IE 11, you cannot observe this behavior.
This happens when the top bound of the last element on a scroll container is above the top bound of the container. The browser decides that the last element is what the user is interested in and decides to stay in that position.
The last div doesn't snap to the bottom because the scroll happens relative to the top bound of the last element and the last element is growing.
If you want a different behavior, I would not suggest handling it with Javascript, but I would suggest changing your layout considering these rules. For example the last div should be the growing one, instead of the previous siblings of it.
Obligatory code:
var div = document.querySelectorAll('.growing');
var height = 500;
setInterval(function(){
height += 100;
div[0].style.height = height + 'px';
div[1].style.height = height + 'px';
div[2].style.height = height + 'px';
},1000);
.start, .end{
height: 110px;
}
.start{
background: red;
}
.end{
background: green;
}
.growing{
background: yellow;
}
.cnt1,.cnt2,.cnt3{
overflow: auto;
border: 5px solid black;
margin: 5px 0;
scroll-snap-type: mandatory;
}
.cnt1{
height: 100px;
}
.cnt2{
height: 120px;
}
.cnt3{
height: 100px;
}
<div class="cnt1">
<div class="start"></div>
<div class="growing"></div>
<div class="end"></div>
</div>
<div class="cnt2">
<div class="start"></div>
<div class="growing"></div>
<div class="end"></div>
</div>
<div class="cnt3">
<div class="start"></div>
<div class="end"></div>
<div class="growing">
Content
</div>
</div>
Edit:
If the bounds of the growing div is in the visible area, the scroll is relative to the top of the growing div. So you can hack CSS to show the growing div, but actually not show it.
In this fiddle I have used two different CSS hacks. First one is adding a negative margin bottom and a positive padding bottom at same amount. The second hack is adding an :after element to the growing div but hide its visibility.
for click events, use blur, avoid scrollTo
It seems like this issue is focus-related. I came across a similar bug and when the element that triggered a height change was switched to an unfocusable element, like a div, the screen jumping disappeared. This clearly isn't a great solution because we should be able to use buttons! It also implicates focus in this strange behavior. Further experimentation led to blurring the trigger element before the height change, which solves the problem without moving the viewport. I've only tried this with click events so I'm not sure if it works for drag n drop.
codepen that showcases viewport jumping with accordions and a blur fix
function handleClick(e) {
e.currentTarget.blur();
// code to change height
}
Do you mean that when you scroll to the bottom, and a piece of content gets added, you stay at the bottom? Because the solution for that is real simple:
Option 1
Store the current scrolloffset to the top (eg how many px you've scrolled down)
Add new content
Set scrolloffset to the top to the stored value
Those last two steps can be done so fast that the user wont notice.
Option 2
Not 100% sure this works, but i'm guessing it does:
When the visitor scroll to the bottom, always scroll them back 3px. This way, they're not at the bottom at the point where new content gets added, so the browser stays where it is.
As per my understanding regarding your requirement, I have given a working jsfiddle sample.
Hope it would help to you.
If you expect something more, feel free to add comment.
Cool!
$(function(){
var height = 200;
var pos = 0;
setInterval(function(){
if($(document).height() >= $(window).height()){
var height = $('.container1').height();
$('.container1').height(height + 20);
pos = pos + 20;
$(window).scrollTop(pos);
}
}, 1000);
});
.container1 {
border: 1px solid #ccc;
min-height: 200px;
background: #ccc;
height: auto;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="container1">
<p>11</p>
<p>12</p>
<p>13</p>
</div>
All of your draggable elements are in a container with no auto overflow, when you drag and drop your elements the whole page scrolls due to dragging.
Instead of that do as:
<div class="container">
<!-- Place all your draggable elements here -->
</div>
set a max-height and overflow of the container class as:
.container {
max-height: 400px;
overflow: auto;
}
Now when you drag and drop your elements, instead of the whole page, the only container will scroll.
After implementing this solution, it will look like this.
Before dragging.
While dragging.
Hope this helps you.
I tried to put a position: fixed on the div ".ais-search-header", but it does not move while on scroll. I also try to drag it out from the parent div, but still did not work.
URL: https://kickegg0.myshopify.com/search.searchdata?q=q
Pass: tweast
There is a bug in Chrome and Firefox where position: fixed does not position relative to the screen when there is an ancestor element with the transform or backface-visibility attributes (or their webkit equivalents) set.
Move the element you want absolutely positioned above the elements with those attributes.
A position: fixed element has no dependency to its parent container. Its position actually depends on the browser window. That means it won't move or scroll on page scroll. It will be on top of the page. But those under that element will scroll according to the page. If you want to move the container according to scroll, give it position: absolute like:-
#parent {
position: relative;
}
#container {
position: absolute;
}
So that it will be inside the container and will move on page scroll.
Position 'fixed' positioning is based on your browser window so not move with scrolling. if you want to move with scrolling use position 'absolute'
I have a div that has fixed position and bottom 0 to display at the bottom of the window.
My problem is when window resize, this div move to up and into other elements. For example when I open console box in chrome this div jump to other elements in facebook fix position such as friend list, when I open console box, element jump to up but hidden up element.
Please help me how I can fix div in window resize.
CSS Position Fixed:
Do not leave space for the element. Instead, position it at a
specified position relative to the screen's viewport and doesn't move
when scrolled. When printing, position it at that fixed position on
every page. Fixed positioning is similar to absolute positioning, with
the exception that the element's containing block is the viewport.
This is often used to create a floating element that stays in the same
position even after scrolling the page. - by Mozilla MDN
In other words, When you use position: fixed; that takes elements out of the document's regular flow.
How I can fix div in Window Re-size?
Solution: There's no way to do it as you want using CSS. You must remove position: fixed; because when you set bottom: 0px with position: fixed; to your element then it doesn't matter that what is the size (vertical) of your browser or window because position: fixed; element will always appear on the bottom of the viewport screen at 0px.
You can use
position: fixed
or
`position:absolute`
I am using max-width: 100%; height: auto; on all my <img> elements and on my image slider wrapper.
When resizing the browser window, the images scale correctly, but many surrounding elements don't follow along and misposition. They will self-correct once the page is refreshed or next image is loaded in the image slider. Any ideas?
Demo - scale the window, css at line 25
Pikachoose library sets the sizes of a few elements on each animation.
<div class="pika-stage" style="height: 355px;">
<div class="pika-aniwrap" style="position: absolute; top: 0px; left: 0px; width: 835px;">
This is why everything fixes itself when the next animation happens. You could look though the source and replicate the animations re-sizing code and put it in a $(window).resize event handler. Looking at the docs for Pikachoose it seems that they have a goto method.
You could do something like this:
$(window).resize(function(){$('#pikame').data('pikachoose').GoTo(3)})
Where the index of 3 is the current active slide. You probably want to use a form of timeout and only call it once to improve performance.
var resizeSlider = null
$(window).resize(function(){
if(resizeSlider) clearTimeout(resizeSlider)
resizeSlider = setTimeout(function() {
$('#pikame').data('pikachoose').GoTo(3)
}, 300)
})
This should make it so the goto is fired 300ms after the last window.resize event.
Hope this gives you some ideas.
I want to reposition an entire div and its contents up about 10-15 pixels.
How can I do this?
Note: this is slider element, so when I click a button the slider slides down. Once it is finished I want to reposition it up about 15 pixels.
$('#div_id').css({marginTop: '-=15px'});
This will alter the css for the element with the id "div_id"
To get the effect you want I recommend adding the code above to a callback function in your animation (that way the div will be moved up after the animation is complete):
$('#div_id').animate({...}, function () {
$('#div_id').css({marginTop: '-=15px'});
});
And of course you could animate the change in margin like so:
$('#div_id').animate({marginTop: '-=15px'});
Here are the docs for .css() in jQuery: http://api.jquery.com/css/
And here are the docs for .animate() in jQuery: http://api.jquery.com/animate/
$('div').css({
position: 'relative',
top: '-15px'
});
In css add this to the element:
margin-top: -15px; /*for exact positioning */
margin-top: -5%; /* for relative positioning */
you can use either one to position accordingly.
you can also do this
margin-top:-30px;
min-height:40px;
this "help" to stop the div yanking everything up a bit.