1

Im building a portfolio site, my scroll bar get stuck when it touches the top or the bottom of the page, sometimes even sooner. I think the problem has something to do with pixels amount on a higher dpi screen. I also used some effects like parallax, smooth scroll, scroll snap, intersection detector and more. One of them might be the cause of the problem but i can't put a finger on it. This problem only occurs on viewport setting of "Laptop with HiDpi screen" - checked on 2 laptops also.

https://jordansportfolio.netlify.com/ toggle viewport for any other device and refresh to see how it it suppose to work.

I think the problem has something to do with pixels amount on a higher dpi screen, i also used some effects like parallax, smooth scroll, scroll snap, intersection detector and more. One of them might be the cause of the problem but i can't put a finger on it.

What i tried:

My <ParallaxWrapper> is set to 180 vh so i can have a better scroll-snap-align: center position when scrolling back up from the 'About' section. Tried changing it to 100vh and it makes the problem is less serious, the scroll bar only freeze when touching the absolute top or bottom of the page, and it's not consistent, sometime i'm still able to scroll, but if i scroll top when im already at the top position it will sometimes get stuck, same for the bottom of the page. it also makes the page scroll less fast on HiDpi which is good, but i really prefer the 180vh setting for the parallax effect i've set up. So i tried 98vh, seems like i can't get stuck on the top of the page, but now its very easy to get stuck when touch the bottom of the page. If the scroll bar froze, i can press on the screen somewhere and if i hit space-bar it will scroll down or arrows for full scroll control all over the page. Now i'm pretty sure there is 1 pixel that if the viewport "touch" it's freezes the scroll or maybe focus is changed. I've tried to remove <Heightener> out from this component to the App.jsx, nothing changed. I find it very weird that this problem only happens on specific a dpi.. that's means that this is the real problem. I've saw some people talk about scaling issues but i'm not sure what they meant and how to solve my problem.

JSX:

<ParallaxWrapper>
  <Logo image={ForText}>JORDAN'S</Logo>
  <Popup>PORTFOLIO</Popup>
  <PrlxLayerF image={Mountain6} />
  <PrlxLayerE image={Mountain5} />
  <PrlxLayerD image={Mountain4} />
  <PrlxLayerC image={Mountain3} />
  <PrlxLayerB image={Mountain2} />
  <PrlxLayerA image={Mountain1}>
    <Heightener>Code. Meets. Art.</Heightener>
  </PrlxLayerA>
</ParallaxWrapper>

CSS:

const ParallaxWrapper = styled.div`
  height: 180vh;
  scroll-snap-align: center;
  scroll-snap-stop: always;
  scroll-snap-type: mandatory;
  /* position: relative; */ /* NOTE! IF IN POSITION RELATIVE - PUSHES THE PAGE UP */
  @media (max-width: 713px) {
    scroll-snap-align: end;
    height: 140vh;
  }
`;

const Logo = styled.div`
  position: absolute;
  /* same as layers height to hide the logo */
  height: 105%;
  width: 100%;
  z-index: -1;
  display: flexbox;
  align-items: center;
  justify-content: center;
  font-size: 10rem;
  font-family: "Nova Square", sans-serif;
  font-weight: 900;

  background: center / cover no-repeat url(${({ image }) => image});

  background-clip: text;
  -webkit-background-clip: text;
  color: transparent;

  /* smaller then: */
  @media (max-width: 979px) {
    font-size: 8rem;
  }
  @media (max-width: 767px) {
    font-size: 6rem;
  }
  @media (max-width: 480px) {
    font-size: 3.7rem;
  }
  @media (max-width: 360px) {
    font-size: 3rem;
  }
`;

const PrlxLayerF = styled.div`
  height: 105%;
  width: 100%;
  position: absolute;
  transform-origin: 0 0;
  transform: translateZ(-5.5px) scale(6.5);
  z-index: -7;

  background: center/cover no-repeat url(${({ image }) => image});
`;

const Popup = styled(PrlxLayerF)`
  font-size: 4.4rem;
  transform: translateZ(-0.1px) scale(1.1);
  z-index: -3;
  background: none;
  text-align: center;
  line-height: 100vh;
  top: 10%;
  font-family: "Advent Pro", "Poiret One";
  font-weight: 600;

  /* bigger than widescreens */
  @media (min-width: 2500px) {
    top: 9%;
  }
  /* smaller than: */
  @media (max-width: 979px) {
    font-size: 4rem;
    top: 8%;
  }
  @media (max-width: 767px) {
    font-size: 4rem;
    top: 9%;
  }
  @media (max-width: 480px) {
    font-size: 3rem;
    top: 7%;
  }
  @media (max-width: 360px) {
    font-size: 2.5rem;
  }
`;

const PrlxLayerE = styled(PrlxLayerF)`
  background-image: url(${({ image }) => image});
  transform: translateZ(-4.5px) scale(5.5);
  z-index: -6;
`;

const PrlxLayerD = styled(PrlxLayerF)`
  background-image: url(${({ image }) => image});
  transform: translateZ(-3.5px) scale(4.5);
  z-index: -5;
`;

const PrlxLayerC = styled(PrlxLayerF)`
  background-image: url(${({ image }) => image});
  transform: translateZ(-2.5px) scale(3.5);
  z-index: -4;
`;

const PrlxLayerB = styled(PrlxLayerF)`
  background-image: url(${({ image }) => image});
  transform: translateZ(-1.5px) scale(2.5);
  z-index: -3;
`;

const PrlxLayerA = styled(PrlxLayerF)`
  background-image: url(${({ image }) => image});
  transform: translateZ(-0.5px) scale(1.5);
  z-index: -2;

  ::before {
    content: "";
    top: 85%;
    height: 15%;
    width: 100%;
    position: absolute;
    /* display: block; */
    z-index: 1;

    background: rgb(255, 255, 255);
    background: linear-gradient(
      0deg,
      rgba(255, 255, 255, 1) 0%,
      rgba(255, 255, 255, 0.95) 10%,
      rgba(255, 255, 255, 0.85) 15%,
      rgba(255, 255, 255, 0.738) 19%,
      rgba(255, 255, 255, 0.541) 34%,
      rgba(255, 255, 255, 0.382) 47%,
      rgba(255, 255, 255, 0.278) 56%,
      rgba(255, 255, 255, 0.194) 65%,
      rgba(255, 255, 255, 0.126) 73%,
      rgba(255, 255, 255, 0.075) 80.2%,
      rgba(255, 255, 255, 0.042) 86.1%,
      rgba(255, 255, 255, 0.021) 91%,
      rgba(255, 255, 255, 0.008) 95.2%,
      rgba(255, 255, 255, 0.002) 98.2%,
      rgba(255, 255, 255, 0) 100%
    );
  }
`;

const Heightener = styled.div`
  /* this height hides the parallax slow moving layers */
  height: 50%;
  width: 100%;
  background: white;
  position: relative;
  top: 100%;

  display: flexbox;
  justify-content: center;

  padding-top: 3%;
  font-family: "Nova Square";
  font-size: 8rem;

  @media (max-width: 1160px) {
    padding-top: 6%;
    font-size: 6rem;
  }
  @media (max-width: 979px) {
    font-size: 5rem;
  }
  @media (max-width: 713px) {
    font-size: 3.4rem;
  }
  @media (max-width: 480px) {
    font-size: 2.5rem;
  }
  @media (max-width: 360px) {
    font-size: 2rem;
  }
`;

Some weird interactions i've found: - One scroll 'tick' is enough to freeze the scroll bar. - If you scroll fast enough past the parallax part the other sections are fine until you get to the bottom where it also get stuck. - Page generally scrolls way too fast compared to other viewports.

EDIT: removing scroll-snap-type: y mandatory; from the parent seems to solve the stucking and fast scrolling problems. but of course, also the snap scrolling. maybe it's a direction..

Jordan
  • 145
  • 8

1 Answers1

0

I don't have the bug on mobile but I had some other problem, while I was working on a project with 'vh'. When you are working with 'vh' the page behaves really odd on mobile as soon as you are using some type of formular wich needs a keyboard. So keep that in mind before your website dosen't work right on mobile. I was really mad and needed a lot of time to "fix" it.

Nice parallax effect by the way :)

Julius
  • 81
  • 1
  • 7
  • 1
    thanks! and yeah the bug only appears if you open the dev tools and switch viewport to "Laptop with HiDpi screen". or if you actually open it in a laptop with hidpi of course – Jordan Dec 10 '19 at 16:12