Agathe
Agathe

Reputation: 313

Body height and horizontal scrolling with html/css

I am trying to make a website with one background image that is moving horizontally while scrolling. I have the scrolling done okay but I have problems adjusting the body size so that it always is fitted to my image (no splicing of the image or no white background after image), no matter the size of my browser's window.

I have achieved scrolling with jquery and tried to play with body/section heights/widths in my css with no success...

body {
  margin: 0;
  padding: 0;
  height: 200vh;
}

section {
  position: relative;
  width: 100%;
  height: 100%;
  background: url(https://cdn.pixabay.com/photo/2017/03/05/00/34/panorama-2117310_960_720.jpg);
  background-size: cover;
  background-attachment: fixed;
  background-repeat: no-repeat;
}
<!DOCTYPE html>
<html>

<head>
  <meta charset="utf-8">
  <title>website.com</title>
  <link rel="stylesheet" href="style.css">
</head>

<body>
  <section></section>
  <script src="https://code.jquery.com/jquery-3.4.1.js" integrity="sha256-WpOohJOqMqqyKL9FccASB9O0KwACQJpFTUBLTYOVvVU=" crossorigin="anonymous">
  </script>
  <script type="text/javascript">
    $(window).scroll(function() {
      var scroll_position = $(window).scrollTop();
      $('section').css({
        'background-position-x': -scroll_position,
      })
    })
  </script>
</body>

</html>

The image can be found at: https://pixabay.com/photos/panorama-miami-florida-water-usa-2117310/

As you can hopefully see, depending on whether you are in full screen or not, it will slice the picture (for me, using body height: 200vh) or add white background after the picture (300vh). I would like, if possible, to have the page always stop at the end of the picture.

Upvotes: 1

Views: 792

Answers (1)

Mosh Feu
Mosh Feu

Reputation: 29277

The thing that you need to consider is the screen ratio so the horizontal and vertical scroll are different and the initial view (the viewport) different.

The calculation will be getting the ratio of the scrollTop (only, that's why we subtract the window's height) relatively the full height and in the same ratio we'll scroll the section horizontally (again, subtract the window's width)

I hope it's not too much complicated.

Here is the full code:

$(window).scroll(function() {
  const ratio = ($(window).scrollTop() / ($('body').height() - $(window).height()));
  var scroll_position = ratio * ($('section').width() - $(window).width());
  $('section').css({
    'background-position-x': -scroll_position,
  })
})
:root {
  --viewport: 200vh;
}

body
{
  margin: 0;
  padding: 0;
}

@media (max-aspect-ratio: 2/1) {
  body {
    height: var(--viewport);
  }
  
  section
  {
    width: var(--viewport);
    height: 100vh;
    background: url(https://cdn.pixabay.com/photo/2017/03/05/00/34/panorama-2117310_960_720.jpg);
    background-size: var(--viewport) 100%;
    background-attachment: fixed;
    background-repeat: no-repeat;
    position: fixed;
  }
}

@media (min-aspect-ratio: 2/1) {
  section
  {
    height: 100vh;
    background: url(https://cdn.pixabay.com/photo/2017/03/05/00/34/panorama-2117310_960_720.jpg);
    background-size: cover;
  }
}
<script src="https://code.jquery.com/jquery-3.4.1.js" integrity="sha256-WpOohJOqMqqyKL9FccASB9O0KwACQJpFTUBLTYOVvVU=" crossorigin="anonymous">
</script>
<section></section>

https://jsbin.com/gabugeg/3/edit?html,css,output

I used the --viewport: 200vh; variable just to make it easier to change in multiple places at once.

The code can be written in more optimised way but I wanted the code to be more readable.

Let me know if everything is clear.

Update

To support weird screen ratios (width / height = 2 in this example) you can use the media queries (min-aspect-ratio) and (max-aspect-ratio: 2/1). If you use different image with different dimensions, you probably will need to tune it again.

Upvotes: 2

Related Questions