So I have this image as a background for a "parallax-divider" div, which I wish to stay on the page as it is, but I would like to make the image scroll slower than other content in order to accomplish a parallax effect. I know that I'm targeting something wrong way, but can't figure out how to fix it. Only thing I get is to move the whole div up and down/stretching in a very undesireable way. Any opinions how to fix this?
Here's the Codepen: http://codepen.io/anon/pen/vxOYrQ
.section {
height: 300px;
background-color: blue;
}
.parallax-divider {
background: url('http://www.planwallpaper.com/static/images/Cool-Background-Wallpaper-Dekstop.jpg') top center no-repeat;
background-size: cover;
background-attachment: fixed;
height: 200px;
}
<div class="section"></div>
<div class="parallax-divider" id="parlx">
<div class="wrapper">
<div class="parallax-divider__image">
<h2>lorem ipsum</h2>
</div>
</div>
</div>
<div class="section"></div>
function parallax() {
var parlx = document.getElementById('parlx');
parlx.style.position = "relative";
parlx.style.top = -(window.pageYOffset / 8) + 'px';
}
window.addEventListener("scroll", parallax, false)
Use transform: translateY() instead of top property. Also set parallax elemen to position: absolute, width: 100% and it wont strech. Like so :
translate('+ (-(window.pageYOffset / 8)) + 'px';
Related
So what I was looking for is a subtle radial gradient background effect which will move from left to right when the page is scrolled, like this site - https://hellonesh.io/ . So when I inspected the code of that site, I found the responsible HTML and CSS for that effect -
HTML
<body>
<main>
<div class="bg" style="background-image: radial-gradient(88.33% 60.62% at 100.87% 48.33%, rgb(86, 53, 173) 0%, rgb(20, 9, 78) 100%);"></div>
<section id="sec-1">
...
</section>
<section id="sec-2">
...
</section>
<section id="sec-3">
...
</section>
</main>
<script>
// Need help here
</script>
</body>
CSS
.bg {
position: fixed;
display: block;
top: 0;
left: 0;
width: 100vw;
height: 100vh;
}
section {
height: 100vh;
}
jQuery/js
$(window).on('scroll', function () {
//When a new section(100Vh) comes into view move the radial gradient left to right or right to left
// completely lost here
// $('.bg').css({background-image: "radial-gradient()"});
});
But I've no idea how to make the radial gradient move in the viewport when scrolled. If it's a plugin please let me know the name. If not then how can I achieve that effect using JavaScript or jQuery? Thanks!
There are two parts to this question: how to sense when another section comes into view and when it does how to move the background image depending on which section is now in view.
For the first we can use InterSectionObserver. If we attach the observer to each section, it will get fired when that section comes into (or goes out of, but we aren't interested in that) the viewport.
For the second, this snippet uses a CSS variable --x to say where the background image radial gradient is to have its 'at' x coord set. I don't know what values you want for each section, so this snippet just looks at the id of the section that is in view and calculates the offset just for the demo.
function callback(entries) {
entries.forEach( entry => {
if (entry.isIntersecting) {
let x = 50 * Number(entry.target.id.replace('sec-', '') - 1); //change to whatever you want the x to be for sec-n
bg.style.setProperty('--x', x + '%');
}
});
}
const bg = document.querySelector('.bg');
const sections = document.querySelectorAll('section');
const observer = new IntersectionObserver(callback);
sections.forEach( section => {
observer.observe(section);
});
.bg {
--x: 0;
--y: 48.33%;
position: fixed;
display: block;
top: 0;
left: 0;
width: 100vw;
height: 100vh;
background-image: radial-gradient(88.33% 60.62% at var(--x) var(--y), rgb(86, 53, 173) 0%, rgb(20, 9, 78) 100%);
}
section {
height: 100vh;
}
<main>
<div class="bg"></div>
<section id="sec-1">
...
</section>
<section id="sec-2">
...
</section>
<section id="sec-3">
...
</section>
</main>
I am trying to create letterboxes for video thumbnails in css. Thumbnails can be any size but I want them to fit within a box with a fixed aspect ratio of 16:9. This is easy to accomplish if I use the background-image properties. See the example below:
.container {
background-color: gray;
position: relative;
width: 100%;
padding-top: 56.25%;
background-size: contain;
background-repeat: no-repeat;
background-position: center;
}
.container1 {
background-image: url("https://bulma.io/images/placeholders/640x480.png");
}
.container2 {
background-image: url("https://bulma.io/images/placeholders/720x240.png");
}
<div class="container container1">
</div>
<br/>
<div class="container container2">
</div>
However, using background-image introduces a few problems. I only want the background of .container to be gray while the thumbnail is loading, once it has loaded I want it to be black. I also want to replace the thumbnail url with a default thumbnail url if for some reason the thumbnail fails to load. I cannot think of a way to do this without being able to use the onload and onerror events of an actual image element.
Fortunately, since in my actual code I am fetching the thumbnail urls dynamically I can also return the width and height of a thumbnail so I know it before I try to load it. However, I cannot figure out how to convert the width and height of the thumbnail into the correct percent it needs to be to cover the center of the box the same way the first example does using background-image. See the example below:
let c1ThumbnailWidth = 640;
let c1ThumbnailHeight = 480;
let c2ThumbnailWidth = 720;
let c2ThumbnailHeight = 240;
$( document ).ready(function() {
$('.container1 img').css('left', 100 * (1 - (9 / 16) * (c1ThumbnailWidth / c1ThumbnailHeight)) / 2 + '%');
$('.container2 img').css('left', 100 * (1 - (9 / 16) * (c2ThumbnailWidth / c2ThumbnailHeight)) / 2 + '%');
$('.container img').one('load', function() {
$(this).parent().css('background-color', '#000');
});
$('.container img').on('error', function () {
$(this).attr('src', 'default.jpg');
});
});
.container {
background-color: gray;
position: relative;
width: 100%;
padding-top: 56.25%;
}
.container img {
position: absolute;
top: 0;
height: 100%;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="container container1">
<img src="https://bulma.io/images/placeholders/640x480.png">
</div>
<br/>
<div class="container container2">
<img src="https://bulma.io/images/placeholders/720x240.png">
</div>
How can I make the image element mimic the behavior of a background-image set to cover or alternatively how can I tell when a background-image has loaded or failed to load and adjust it accordingly?
Have you tried using CSS object-fit on the image element?
https://developer.mozilla.org/en-US/docs/Web/CSS/object-fit
This site I am developing is using HTML5, CSS3, Bootstrap 4, and Jquery. I would like to have a scroll effect on a full-screen background-image that is at the very top of my page (100vh hero banner type thing). I am trying to gradually increase the contrast (css filter: contrast(some%)) of an image as the user scrolls down (its fine if the image is completely unrecognizable by the time it leaves viewport).
I have some Jquery that somewhat does the effect I am looking for, however I would like the effect to be more gradual.
The main issue I am having is that when the user scrolls back to the top of the page the contrast value gets set to 0% leaving a completely grayed out image. What I would like is for the contrast to gradually decrease back to normal (100%) as the user scrolls back up all the way to the top of the page.
I have set up a very simplified codepen. I couldn't get a css background-image url value to reference an external link from codepen, so I am targeting the effect on a full screen image ().
Thanks!
Link to the Pen: [codepen-link][1]
[1]: http://codepen.io/wdzajicek/pen/MVovZE
See code below in snippet
$(document).ready(function (){
$(window).scroll(function(){
var pixelstop = $(window).scrollTop();
$(".myimage ").css("filter", "contrast(" + pixelstop + "%)");
});
});
.header {
height: 100vh;
}
.myimage {
position:absolute;
top: 0;
left: 0;
min-width: 100%;
width; 100%;
z-index: -1;
}
.jumbotron {
position: relative;
background-color: unset;
margin-top: 150px;
z-index: 999;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<header class="header text-center">
<img src="https://raw.githubusercontent.com/wdzajicek/portfolio/master/assets/img/header-bg.jpg" class="myimage" alt="">
</header>
There is the main problem in $(window).scrollTop(); it will return 0 value
that's why contrast value gets set to 0% leaving a completely grayed out image
var pixelstop = $(window).scrollTop();
replace the code with
var pixelstop = 100+100*$(window).scrollTop()/$(window).height();
don't just copy this code please understand thanks.
$(document).ready(function (){
$(window).scroll(function(){
var pixelstop = 100+100*$(window).scrollTop()/$(window).height();
console.log(pixelstop);
$(".myimage ").css("filter", "contrast(" + pixelstop + "%)");
});
});
.header {
height: 100vh;
}
.myimage {
position:absolute;
top: 0;
left: 0;
min-width: 100%;
width; 100%;
z-index: -1;
}
.jumbotron {
position: relative;
background-color: unset;
margin-top: 150px;
z-index: 999;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>
<header class="header text-center">
<img src="https://raw.githubusercontent.com/wdzajicek/portfolio/master/assets/img/header-bg.jpg" class="myimage" alt="">
</header>
100 is default value of filter contrast not 0. that's why the background is grey out because it reaches zero.
I'm currently doing a javascript parallax page. I've managed to set the background image and 2 other pictures(#content,#content2).
When i scroll all the way down past my content and then to my content2, I want my webpage to end there. However I'm able to scroll down infinitely.
Can anyone please look at my code and tell me what i need to add or change so that my webpage ends and stops scrolling after content2.
Please note that my #image is my main background and the content and content2 are separate images that go over my background but i want my page and scrolling to stop at content2.
Code:
<style type="text/css">
* {
margin: 0px;
padding: 0px;
}
#image {
position: relative;
z-index: -1
}
#content {
height:690px;
width: 100%;
margin-top:-10px;
background:url(http:/chicago_bulls_wallpaper_backgrounds.jpg);
position: relative;
z-index: 1;
background-repeat: no-repeat;
background-position: center center;
}
#content2 {
top:710px;
height:570px;
width: 100%;
margin-top:-10px;
background:url(All.jpg);
position: relative;
z-index: 1;
background-repeat: no-repeat;
background-position: center center
}
</style>
<script type="text/javascript">
var ypos, image;
function parallex() {
ypos = window.pageYOffset;
image = document.getElementById('image');
image.style.top = ypos * 1 + 'px';
}
window.addEventListener('scroll', parallex);
</script>
<img id="image" src="black-glass.png" height="710px" width="100%" />
<div id="content"></div>
<div id="content2"></div>
It's because your parallax factor is 1, meaning that the background is moving exactly with the screen. Thus, the browser thinks that it always has room and can always afford to scroll down, which is actually a pretty hilarious bug.
If you were intending true parallax scrolling, set your factor to less than 1, like this:
image.style.top = ypos * 0.95 + 'px';
If you simply didn't want your background to move at all with the rest of the page, set the body's background to this image (as you already do with the divs), and set the background-attachment property to fixed - no JavaScript required.
Is something like this what you are wanting? I am not having a problem with infinite scrolling.
http://codepen.io/vinsongrant/pen/advzww
<img id="image" src="https://upload.wikimedia.org/wikipedia/commons/d/da/The_City_London.jpg" height="710px" width="100%" />
<div id="content">
<h1>Here is content 1</h1>
</div>
<div id="content2">
<h1>Here is content 2</h1>
</div>
I have to clip an image which spans full width. The following things didnt work for me
clip: this requires position absolute so the block elements dont stack below
background-position: it doesnt clip properly when zoomed the clipped portion increases when zoom in and vice versa.
wrapper: the wrapper height is dependent on the browser width so its value should be dynamic.
I used js with setinterval 1 millisec. so that wrapper height is constantly updated. works perfect in all scenarios but setinterval is bad practice. so please suggest a cleaner way to implement this.
document.onreadystatechange = setInterval(function () {
if (document.readyState == "complete") {
brow_width = document.body.clientWidth;
var h1 = (brow_width/7);
document.getElementById("clip1").style.opacity = "1";
if(brow_width > 700){
document.getElementById("clip1").style.height= h1;
}
else{
document.getElementById("clip1").style.height= 110;
}
var h2 = (brow_width/33.33);
document.getElementById("clip2").style.opacity = "1";
if(brow_width > 700){
document.getElementById("clip2").style.height= h2;
document.getElementById("banner2").style.top= h2 - brow_width*0.35;
}
else{
document.getElementById("clip2").style.height= 21;
document.getElementById("banner2").style.top= -220;
}
}
},1);
<!--two different clips of the same image-->
<div id="clip1">
<img id="banner1" src="banner.jpg">
</div>
<div id="clip2">
<img id="banner2" src="banner.jpg">
</div>
Try this:
HTML
<div class="banner">
<div class="bannerImg"></div>
</div>
CSS
.banner {
position: relative;
padding-bottom: 15%;
}
.bannerImg {
background-image: url(...);
background-size: cover;
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
}
(Also here: http://jsfiddle.net/N6mCw/)
The idea is to use the outer wrapper to crop the image. If you need to support IE<9 then instead of a background image you'll have to add an <img> tag within the inner div and remove the background-image CSS:
<div class="banner">
<div class="bannerImg">
<img src"…" />
</div>
</div>
Although… the best way to do this would be to actually crop the image to the correct aspect ratio beforehand!