Moving element with javascript - choppy effect in Safari and Firefox - javascript

Basically I'm trying to move an element based on the scroll position. The issue I have is that when scrolling on Firefox and Safari (MacOS) the element acts weird and choppy as the positioning doesn't update on time or something. Sometimes you need to scroll up and down few times to see it. Firefox has additional smoothing which makes things even uglier.
Element needs to be relatively positioned (needs to respect overflow: hidden).
The sample code is below:
HTML:
<div class="container">
<div id="block"></div>
</div>
CSS:
.container{
height: 800vh;
width: 100%;
}
#block{
width: 300px;
height:50px;
background: #000;
position: relative;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
JS:
var block = document.getElementById('block');
window.addEventListener('scroll', function(){
block.style.top = window.pageYOffset*1.2 + "px";
});
And a CodePen link: https://codepen.io/maciejgunia/pen/gxQReo
Thanks for any suggestions.
EDIT: here is the observed behaviour - I know some people see it differently - https://jumpshare.com/v/RhU7gNYAlMFwDo7HIl5Z

add transition: top 1s; to #block CSS this will smooth out your animation

Related

CSS resizing issue with image

I'm trying to use this background gradient and keep it centered on all screen sizes (Next.js, React, Sass)
The JSX:
<div className="bg-gradient-container">
<Image src={Gradient} alt=""/>
</div>
The css styles:
.bg-gradient-container {
position: absolute;
top: calc((470px - 32vh)*-1);
left: calc((1920px - 100vw)/-2);
width: 1920px;
z-index: -10;
animation: appear2 3s ease-in;
}
I've been trying things for a while and can't figure it out. In the gif, when I set it to Desktop mode then it resizes fine. When it's set to mobile, it resizes keeping the entire right side of the image in frame.
The weird thing is that when I hover over the image in devtools, it says that the width is 1920x1080, and the text content is the full viewport width (even though it doesn't take up the whole viewport ??).
try to use
left: 50%;
transform: translateX(-50%);
instead of left: calc((1920px - 100vw)/-2);
Try:
.bg-gradient-container {
position: absolute;
top: 0;
left: 0;
height: auto;
width: 100%;
z-index: -10;
animation: appear2 3s ease-in;
}
If that does not work, you might need to apply height: auto and width: 100% to the image. The idea is that the Image element should fill it's container (parent element).
Also, Chrome dev tools can be a little buggy when using responsive mode, sometimes it does not resize everything correctly. When you select something like 'iPhone 12 Pro' from the Dimensions dropdown menu in dev tools, does the image resize correctly?

Fullscreen <canvas> element on iOS: glitch on scroll

I have a <canvas> element with this CSS:
canvas[resize] {
width: 100%;
height: 100%;
position: fixed;
left: 0; top: 0;
pointer-events: none;
background: black;
}
I display funny stuff behind the actual content on a website. On iOs, the address bar hides on scroll. When it hides, the canvas doesn't fill the entire height anymore for a second or so, which is ugly.
Here is a video. Note that I colored the canvas all black to make the point more clear. Normally the canvas is not just black. Note how the content underneath can be seen at the bottom when the address bar hides.
Of course I tried to make the canvas higher than 100% but this has no effect. Even when I set the height to 1000px (and confirm on the console that $('canvas').height() returns 1000) the same thing happens. It is as if the canvas element isnt rendered outside of the viewport.
I read up on how to force hide/show the address bar so the transition does not happen but it seems that all methods are outdated. Of course I prefer not to influence the address bar's behaviour.
Here is a demo showing the problem. The canvas is not black in this demo, it is the wobbly colored thing in the background.
Any suggestions?
I solved it by
making the canvas higher than the viewport
adding the wonderfully hacky -webkit-transform: translate3d(0, 0, 0);
It now looks like this:
canvas[resize] {
-webkit-transform: translate3d(0, 0, 0);
width: 100%;
height: 115%; // Higher than the viewport
position: fixed;
left: 0; top: 0;
pointer-events: none;
background: black;
}

Position fixed within container element instead of the browser / viewport

I need to position a header to be fixed within the containing parent so that it follows when scrolling. The problem is that
position:fixed
fixes the position to the browser, not the parent. What this is resulting in is that when I have a container that has a horizontal scroll for overflow in the width (the content is wider than the container), my fixed header does not have the overflow-scroll as the content of the table does.
See this fiddle demo
So the goal here is to fix the position of the header, but fixed relative to it's parent container. In this fiddle, you can see that I've commented out a block of css:
.container{
/*-webkit-transform: translateZ(0);
-moz-transform: translateZ(0);
-ms-transform: translateZ(0);
transform: translateZ(0);*/
-webkit-transform: none;
-moz-transform: none;
-ms-transform: none;
transform: none;
}
If you replace the current css block (with transform set to none) with the one with translateZ, the header will get positioned within it's parent container, but is no longer fixed.
Anyone know how to solve this? Preferred solution would be CSS/HTML only and avoid JS but if nothing else, then JS is of course what I need to go with!
CSS can't do this by itself.
Position: fixed works in relation to the viewport, not it's containing element.
I've seen an attempt to solve this problem using the CSS3 transform property, but (as you noted in your comment to my first answer) it doesn't seem to work.
I understand you can't use any client-side library but that's the only solution available to my knowledge. For you and others who may one day need this, here's a solution that works. It employs a bit of jQuery:
Positioning an element inside another element with the positioned element fixed along the x and y axes (i.e. position fixed horizontally and vertically).
http://jsfiddle.net/8086p69z/8/
HTML
<div class="moving-article">
<div class="container">
<header class="fixed-header">FIXED HEADER</header>
<ul>
<li>SCROLL</li>
<li>SCROLL</li>
<li>SCROLL</li>
</ul>
</div>
</div>
CSS (relevant section)
.moving-article {
height: 150px;
width: 75%;
overflow-x: scroll;
}
.fixed-header {
background: rgba(0,0,0,0.5);
width: 50%;
text-align: center;
line-height: 40px;
position: absolute;
top: 0;
left: 0;
}
.container{
width: 1000px;
}
jQuery
var leftOffset = parseInt($(".fixed-header").css('left'));
$(window).scroll(function(){
$('.fixed-header').css({
'left': $(this).scrollLeft() + leftOffset
});
});
set the header's position to 'absolute', and it's parent container (which you want it to be relative to) to 'relative', and set it to stick to the top of the parent with 'top: 0'
CSS:
.container {
position: relative;
}
.child {
position: absolute;
top: 0;
}
To keep an element fixed within a parent cannot be done with position: fixed because position: fixed takes the element out of the flow and therefore it has no parent. It positions itself relative to the viewport.
To accomplish your goal, while keeping things simple and efficient, you may want to consider Tether, "a client-side library to make absolutely positioned elements attach to elements in the page efficiently".
Hope this helps. Good luck.

How to not allow the 'bounce' effect on the end of scrolling on a website?

Im trying to get this scrolling effect i have seen on the website http://www.unheap.com , if you scroll to the bottom or to the right you'll notice that you can't scroll past whatsoever. Most website including this one allow you to scroll past slightly with a lot of resistance but I'm trying to replicate the example above where you can't scroll past at all. Anyone know of any plugins or methods on how to go about creating this effect?
The actual website itself is 100% the width and height of the page and any scrolling that occurs is accomplished via an absolutely positioned container with overflow: scroll.
EDIT
The actual overflow is set on the .grid element, which is inside the absolutely positioned .container element.
EDIT #2
The author is also using jScrollPane, but you can prevent the bouncing effect simply by making your body 100% width and height and absolutely positioning a container that has overflow set to scroll.
EDIT #3
See the attached code snippet - (you may have to copy and paste it into it's own HTML file because of the way SO displays snippets). There is no bouncing.
* { margin:0; padding:0; }
html,
body { width: 100%; height: 100%; overflow:hidden;}
body>div { height: 50vh; overflow: auto; padding: 10px; background: #000; position: absolute; width: 100px; top: 100px; left: 100px;}
body>div>div { height: 1000px; background: #0f0;}
<div>
<div>scrollable content</div>
</div>

Centering unknown width object in an unknown width container

I have a styling issue where I'm trying to center a wide image relative to it's container. The problem is that the image's width is unknown so I can't do the left:50%, margin-left:-###px; trick because I don't know what the negative margin value will be.
I also can't use text-align:center; because the the image is wider than it's container.
To make matters more complicated, the container's width is also unknown.
I'd quite like to avoid using JavaScript for this but it feels like a big ask with just CSS.
Anyone know of any magical solution here?
UPDATE:
Required support: IE8+, Chrome, Safari, Firefox, Android.
I have tried a couple of the examples provided by you lovely people which have not worked (they would work in most situations, but not mine).
#Vince - I tried your display block trick which works great when the window is wider than the image but when the window is not wider than the image, it effectively becomes 'left-aligned'.
See fiddle example. I have added another container to simulate a narrow mobile device window. Obviously this won't be a hard-coded width as in the fiddle. Also, the img width will not be hard-coded as in the example but I'm trying to simulate the situation that's presented to me.
http://jsfiddle.net/7n1bhzps/1/
Excuse the hideous colours.
UPDATE 2:
Accepted dfsq's answer. Contrary to above, it does not need to support IE8 because the problem is at mobile resolutions. IE8 is not a mobile browser so the need to support this is not necessary.
Thanks all.
Set the container's min-width to any value you feel necessary. Set the image to display as block and use the margin: 0 auto; trick to center it
HTML:
<div id="contain">
<img src="http://i.imgur.com/xs8vh.jpg"/>
</div>
CSS:
#contain {
min-width: 50px;
}
#contain img {
display: block;
margin: 0 auto;
}
JSFiddle: http://jsfiddle.net/j21a8ubo/
You can make use of CSS transofrm: translateX(-50%) to shift the image of unknown width. This technic allows to center image of any width relative to container.
.wrap {
margin: 0 0 10px 160px;
width: 300px;
height: 75px;
border: 3px red solid;
position: relative;
overflow: hidden;
}
.wrap:hover {
overflow: inherit;
}
.wrap img {
position: absolute;
left: 50%;
-ms-transform: translateX(-50%);
-webkit-transform: translateX(-50%);
transform: translateX(-50%);
}
<div class="wrap">
<img src="http://lorempixel.com/600/75/food/3" alt="">
</div>
<div class="wrap">
<img src="http://lorempixel.com/100/75/food/4" alt="">
</div>
Check for support http://caniuse.com/#feat=transforms2d
If you set X's CSS to margin:0px auto; it should center it within the parent container.
Sometimes centering doesn't work, but this can also be a browser-related issue.
If you can adjust the HTML, you could put the element to be centered in a cell in a <table> element, with a cell on either side of it. This is how it was done in IE8 and earlier, though it's not recommended now.
If unknown width of object and its container then use
.center-block{
display: table;
margin:0 auto;
float:none;
}

Categories