how to achieve blurry parallax background - css

My objective is to have a full-screen parallax background that is blurred.
The problem is that when you blur an element it no longer spans the full size of the container (because the edges are blurry). I found an example that suggested using transform:scale in order to stretch it just a little bigger than the size required for 'cover', although now this now makes it so that when you scroll down the page the background slowly moves down as well (once again exposing the blurred edges).
HTML
<div class="viewport"></div>
CSS
.viewport {
background-image: url("images/img1.jpg");
background-attachment: fixed;
filter: blur(7px);
position: relative;
transform: scale(1.1);
background-size: cover;
background-position: center;
height: 130vh;
z-index: -1;
}

Consider putting the viewport in a viewport-wrapper with hidden overflow?
HTML
<div class="viewport-wrapper"><div class="viewport"></div></div>
CSS
.viewport-wrapper {
overflow: hidden;
}
Codepen

Related

White line at the edge of the image or section bug

for some time we are struggling with white lines at the edge of the image containers. It occurs when we use the image with src or html elements with background image in css, mostly on mobile views. We tried these scenarios:
div with background-image, background url
div with more than one background urls
images with position:absolute and container position:relative
The only half-solution seems to change image position to absolute while the container is relative and set for example top: -2px. But still, sometimes it occurs especially with zoom on mobile devices.
This bug can be seen between two sections too but only on a mobile device or google chrome developers' device toolbar.
White line bug image
html,body {
padding: 0;
margin: 0;
}
.parent-container {
height: 100vh;
background-color: #600cb5;
}
.child-container {
background-color: #600cb5;
height: 50vh;
}
.child-container:nth-child(2) {
background-image: url('https://res.cloudinary.com/dfvpybkta/image/upload/v1647105459/test/Frame_1_atbkfx.png');
background-repeat: no-repeat;
background-color: white;
background-size: cover;
}
<div class='parent-container'>
<div class='child-container'></div>
<div class='child-container'></div>
</div>

Mouse-movement image-layer effect

I'd like to create the following effect:
There are two full-screen images on top of each other, but only one is visible. When you move the mouse, the second one is revealed within a circle where the mouse is.
I know how to create the circle that follows the mouse using JS. As for the image overlays, I'm stumped. I fiddled with pseudo-elements, with clip-path and opacity, with radial-gradient, with multiple backgrounds -- to no avail.
Radial-gradient would actually be ideal here, but as far as I know it only accepts colors, not images.
Perhaps a third overlay layer? Any ideas? (If there's already a CodePen that does this and that I've missed, please link to it).
Thanks y'all!
short answer: (and all the code below is commented)
I used background property in a <div> instead of using a <img> tag...
the trick is when you use background-attachment: fixed;
in this example, I used 2 backgrounds from Windows 11 OS and you can see really the trick! one dark and one light...
detailed explanation:
so the a <div> and assigned a background-image to the URL of the light-image
the problem here is: when the div is moving with JS, also the image move...
but I find a solution
make the image fixed, which make the image be always in the same position, also if the image is moving
#circle {
background-attachment: fixed;
/* your code */
}
the problem here is: the image isn't responsive,
but I find solution:
make the image size to cover so it will auto-adjust the size and height of the image automatically to the viewport of the device.
#circle {
background-size: cover;
/* your code */
}
for moving is simple... because we can use Javascript, with an eventListener of mousemove
document.addEventListener('mousemove', (e) => {
/* your code */
});
now solved all the problems, however, I will put some documentations below
documentation that can help you:
CSS background-image MDN
CSS background-attachment MDN
CSS background-size MDN
JS mousemove event MDN
here the code
the code can seem to be long,
but not really because I added a lot of comments so everyone can understand
let circle = document.getElementById('circle');
// on mouse move move the circle
document.addEventListener('mousemove', (e) => {
// make the image move relative to the mouse (make sure that in css you applied position: relative; to the div)
circle.style.left = e.pageX - 100 + 'px'; // 100 is half height of circle, so the cursor is in the middle
circle.style.top = e.pageY - 100 + 'px';
});
body {
margin: 0;
overflow: hidden;
}
#bg-image {
position: fixed;
height: 100vh;
width: 100vw;
/*make the background responsive*/
object-fit: cover;
/* under the circle div*/
z-index: -1;
}
#circle {
height: 200px;
width: 200px;
/* make the the div circle */
border-radius: 50%;
/* important using relative for using top and left in javascript */
position: relative;
/* change the url with the link of image you want */
background-image: url(https://laaouatni.github.io/w11CSS/images/0light.jpg);
/*center the background */
background-position: center;
background-repeat: no-repeat;
/* TRICK: making the background responsive*/
background-size: cover;
/* TRICK: the MAGIC is HERE make the image fixed, so is not moving */
background-attachment: fixed;
}
<!-- background image -->
<img id="bg-image" src=" https://laaouatni.github.io/w11CSS/images/1dark.jpg" alt=" ">
<!-- the circle, and moved with javascript -->
<div id="circle"></div>
please see in full mode,
for better results... you can change the values to something like vh or vw for making this more responsive.
I hope this will help you.
You can use a radial gradient as a mask in CSS.
This snippet has an 'underneath' element which is in fact above the background on the body element.
The mask-image cuts out all but the part of its background which is underneath the non-transparent part.
Obviously you will want to alter the dimensions to fit your use case.
Also, the mousemove does literally that (not looking to see whether mousedown for example) just to give a simple demonstration.
Note that some browsers still require a -webkit- prefix for masks.
<!doctype html>
<html>
<head>
<style>
* {
box-sizing: border-box;
margin: 0;
padding: 0;
}
body {
margin: 0;
background-image: url(https://picsum.photos/id/1016/1024/768);
width: 100vw;
height: 100vh;
background-size: cover;
background-position: center;
}
.underneath {
position: absolute;
width: 100%;
height: 100%;
--x: 50vw;
--y: 50vh;
background-image: url(https://picsum.photos/id/1015/1024/768);
background-size: cover;
background-position: center;
-webkit-mask-image: radial-gradient(black 0 15vmin, transparent 15vmin 30vmin);
-webkit-mask-size: 30vmin 30vmin;
-webkit-mask-repeat: no-repeat;
-webkit-mask-position: calc(var(--x) - 15vmin) calc(var(--y) - 15vmin);
mask-image: radial-gradient(black 0 15vmin, transparent 15vmin 30vmin);
mask-size: 30vmin 30vmin;
mask-repeat: no-repeat;
mask-position: calc(var(--x) - 15vmin) calc(var(--y) - 15vmin);
}
</style>
</head>
<body>
<div class="underneath"></div>
<script>
const underneath = document.querySelector('.underneath');
document.body.addEventListener('mousemove', function() {
underneath.style.setProperty('--x', event.clientX + 'px');
underneath.style.setProperty('--y', event.clientY + 'px');
});
</script>
</body>

Chrome shrinking images look sharpen/glitch with background-image but normal with image tag

I found that sometimes when images shrink with Css background, they looks sharpen/blurry/glitch...?
Anyway, they look weird.
Here I have two div with same effect but different approach, the left one use the IMG tag and the right one use a DIV with background image.
with img tag
<div class="left">
<img src="/image.jpg" alt="test"></img>
</div>
.left {
flex: 0 0 $img-w-pc;
height: $img-w-pc * $img-ratio;
position: relative;
overflow: hidden;
img {
position: absolute;
width: 100%;
top: 50%;
left: 0;
transform: translateY(-50%);
}
}
with background-image
<div class="right" style="background-image: url(/image.jpg)"></div>
.right{
flex: 0 0 $img-w-pc;
height: $img-w-pc * $img-ratio;
background-repeat: no-repeat;
background-position: center center;
background-size: cover;
}
The original image size is 1280 x 720 and when it's shrinking with the background-image it'll looks glitch.
However if I use a smaller image or enlarge the div, make the image "not shrink that much", then it'll be fine.
I test it on Chrome and FireFox and only the former with this problem.
What is the cause of it? Is this some special behaviors with Chrome?
Update
I create a codepen here: https://codepen.io/timtnlee/pen/GRjmxVK
Try adding the image-rendering: pixelated; declaration to the styles for your background image.
https://css-tricks.com/almanac/properties/i/image-rendering/

Choppy scrolling with "background-attachment: fixed"

I'm having issues with background-attachment: fixed. When I apply it to the elements on my page it creates a very choppy scrolling effect. Essentially not something that is not a good experience for the user.
My code is here:
HTML
<div class="con row1">
<p>Some text here just to flesh out example</p>
</div>
<div class="grad-space">
</div>
<div class="con row2">
<p>Some text here just to flesh out example</p>
</div>
CSS
.con {
height: 100vh; }
.grad-space {
height: 50vh; }
.row1 {
background: url('https://s-media-cache- ak0.pinimg.com/736x/3d/88/09/3d880927ac8bfec60a04ca93064569e0.jpg') no-repeat center;
background-size: cover;
background-attachment: fixed; }
.row2 {
background: url('https://d3rt1990lpmkn.cloudfront.net/640/31762579d8fd04a756fb791ac9c3634b5828f0dd') no-repeat center;
background-size: cover;
background-attachment: fixed; }
Here's a link to the codepen showing exactly what I'm talking about:
http://codepen.io/reskk/pen/qaYJwq
Edit: Fullpage Codepen: http://codepen.io/reskk/full/qaYJwq/
Now strangely enough when I resize the browser down to a small width (say 800px) the scrolling actually becomes very smooth - just as you'd want it to appear on a finished project.
When the browser is at its max width (and max height, which you can't quite fully get on codepen due to to the code-input box) that is where the janky, choppy scrolling happens.
I've done extensive searching on this and haven't been able to find a solution.
Does anyone have any ideas on this? It's such a gorgeous effect but is unfortunately made useless by the performance it yields.
Thanks,
Reskk
You know you can see any codepen in full page? Fullpage Codepen
About your choppy effect, what you probably are looking is a scroll animation smoother, not sure if this is the right term. What it does is that delays the mouse scroll effect, or reduces "line jumps" height, making the movement look better.
CSS Parallax by davidwalsh
Edit removed frameworks/libraries references (offtopic)
I was stressing with the same problem, and found a lovely solution here: https://medium.com/vehikl-news/fixed-background-image-performance-issue-6b7d9e2dbc55
Essentially, you need to remove the background image from your .rows and move it to a :before element for each. That way you're not using background-position: fixed, but rather position: fixed on your pseudo element.
.hero {
min-height: 100%;
position: relative;
overflow: hidden;
&::before {
background-image: url('background-image.png');
background-repeat: no-repeat;
background-position: center top;
background-size: cover;
content: '';
height: 100%;
left: 0;
position: fixed;
top: 0;
width: 100%;
will-change: transform;
z-index: -1;
}

responsive sprite background image, how to

Hi I have two columns of content within a container, the first column has text and the second is a span with a background sprite image. The problem is when I get to smaller screen resolutions, I want the background sprite image to have a width in percentage to be able to scale it along with the H5 with a percentage width, is there a way to do this?
h5{
float:left;
display:block;
width:800px;
}
.sprite{
background-image: url("assets/img/website_sprite_a.png");
background-position: -60px -60px;
float:left;
display:block;
width:64px;
}
<div class="container">
<h5>Title
</h5>
<span class="sprite">
</span>
</div>
In your case I would go with a single background-image, but in the case you will have a lot of images or you really want to do this you can use the background-size property.
From MDN:
The background-size CSS property specifies the size of the background images. The size of the image can be fully constrained or only partially in order to preserve its intrinsic ratio.
.sprite{
background-image: url("assets/img/website_sprite_a.png");
background-position: -30% -30%; //use % instead pixels
float:left;
display:block;
width:64px;
background-size: 100%; //play with this
}
You also should read this:
Scaling background images
I have played a little bit with this on JSFIddle. Resize the browser to see the effect.
nearly a year too late, but I was trying to figure out the same and wasn't able to come up with or find a direct answer. After a little fooling around with multiple pieces of advice, I figured it out. Haven't had a chance to test this on IE8 yet, and stopped bothering with IE6/7, so please bear that in mind.
The trick I found is to use a combination of background-position (using percentages—of the sprite image—as mentioned before), padding-top (again, using percentages—this is the percentage of the total width of the sprite image), and background-size: cover.
Play around with it at jsfiddle.
#wrapper {
position: relative;
width: 100%;
}
.div {
position: absolute;
top: 0;
left: 0;
background-image: url('http://upload.wikimedia.org/wikipedia/en/2/2e/Sprite_logo.jpg');
background-repeat: no-repeat;
background-position: 0% 0%;
background-size: cover;
padding: 50% 0 0 0;
width: 40%;
}
<div id="wrapper">
<div class="div"></div>
</div>

Resources