I'm trying to create some kind of a parallax effect, but inside a div positioned in a layout. As far as I understood, using background-attachment:fixed;
makes the background position being calculated according to the viewport, so I tried to compute the position I wanted for the background thanks to the layout elements:
* {
--profile-width: 226px;
--left-margin: calc(calc(100% - 1050px)/2);
--post-width: calc(100% - var(--profile-width) - 2*var(--left-margin));
--bg-pos: calc(var(--left-margin) var(--profile-width) calc(var(--post-width)/2) - 200px);
}
.parallax::after {
content: " ";
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
background: url("https://i.imgur.com/7LDjSuM.jpg");
background-attachment:fixed;
background-position:var(--bg-pos) 0;
background-repeat:no-repeat;
background-size: 400px auto;
}
But the background image is not at all positionned where I expect it to be on the x axis. I created a sample project to illustrate the result: https://codepen.io/LGMR/pen/XWEmKeR.
Any idea why the var(--bg-pos)
is not working? I am fairly sure the variable value is correct since I added a position: absolute;
div with left:var(--bg-pos);
and it's showing where I expect it to be.
The thing is, if I use the absolute pixel value of the var(--bg-pos)
(taken from the absolute positioned div), the image is showing properly so my guess is it comes from the use of var()
but I have no clue what's the problem with it.
Thanks a lot!
CodePudding user response:
It's related to the use of percentage, it doesn't work the way you think it does (related: Using percentage values with background-position on a linear-gradient)
Use vw
instead
* {
--size: max(100vw,1050px); /* take the max between screen width and container */
--profile-width: 226px;
--left-margin: calc(calc(var(--size) - 1050px)/2);
--post-width: calc(var(--size) - var(--profile-width) - 2*var(--left-margin));
--bg-pos: calc(var(--left-margin) var(--profile-width) calc(var(--post-width)/2) - 200px);
}
body {
margin-left:0;
}
.parallax {
height:200px;
position:relative;
display: flex;
align-items: center;
justify-content: center;
}
.parallax::after {
content: " ";
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
width:100%;
background: url("https://i.imgur.com/7LDjSuM.jpg");
background-attachment:fixed;
background-position:var(--bg-pos) 0;
background-repeat:no-repeat;
background-size: 400px auto;
}
<div style="text-align:right;position:absolute; top:20px; left:var(--bg-pos);width:400px;height:500px;background:red;">This div is <br/> at the expected x position</div>
<div style="width:1050px;margin:auto;background-color:darkgrey;display:flex;">
<div style="width:226px;background-color:white;border:1px solid black;"></div>
<div style="padding:15px;flex:1;">
<div style="width:50%;margin:auto;height:4000px;"><div ><div style="z-index:2;font-size:24px;mix-blend-mode:overlay;-webkit-text-stroke:2px black;"></div></div>
</div>
</div>