Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

CSS background-attachment fixed positioning with var()

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.

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

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!

>Solution :

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 class="parallax"><div style="z-index:2;font-size:24px;mix-blend-mode:overlay;-webkit-text-stroke:2px black;"></div></div>
</div>
</div>
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading