Jump to content
Search Community

Pin Spacer Is Causing The Design to Break (it causes horizontal overflow)

pauljohnknight test
Moderator Tag

Recommended Posts

Hi,

 

I have a layout where I have a search form wrapper element that when the user scrolls to the top it pins to the top of the viewport and a fixed div/bar appears behind it (in the CodePen this div is coloured grey so that you can see it).  This give the appearance of a pinned header after the actual header has left the screen.

This all works OK, but when I reduce the window size the layout breaks - this break is being cause by the GSAP `.pin-spacer` div. I'm not sure if this is supposed to align directly with the pinned element or not, but it's offset to the right of the element being pinned and I'm not sure how to fix it?

Normally I would just add an `overflow:hidden` property on what is in this instance is `.home-section-2`, but because the search box and its wrapper are vertically aligned outside of this section it just cuts half of this element off.

 

Any help would be fabulous.

 


  var fixedTopBar = document.getElementById('fixed-top-bar'),
      searchWrapper = document.getElementById('js-home-search-wrapper')

  var pinSearchBox = gsap.timeline({
      scrollTrigger: {
          trigger: searchWrapper,
          start: "top 0",
          pin: true,
          pinSpacing: false,
          end: () => "+=" + document.querySelector('.home-section-2').offsetHeight,
          toggleActions: "restart pause reverse reverse",
          markers: true
      }
  })

  pinSearchBox.to(fixedTopBar, {duration: .1, opacity: 1, zIndex: 2})

 

 

See the Pen MWJdKaJ by pauljohnknight (@pauljohnknight) on CodePen

Link to comment
Share on other sites

Thanks for the minimal demo, @pauljohnknight. I'm struggling to see the rendering problem - can you tell me exactly how to reproduce it? I've resized my window as small as I can, and things seem to look correct. I do see what you mean about the pin-spacer being to the right, but I don't see any negative consequences of that. 

 

The pin spacer's sole purpose is to essentially "prop open" the normal layout in place of the pinned element when it gets pulled out of the normal document flow by getting its position set to "fixed". Otherwise, the layout would collapse. But we cannot have any transforms applied to the pin-spacer because that would create a new stacking context and the "position: fixed" child would suddenly be fixed relative to that parent element instead of the window (very bad - it would then scroll with the rest of the page). That's just how browsers work. A little confusing/annoying, I know. 

 

Anyway, from what I can tell, you've got transform: translate(-50%) on that element you're pinning but of course we can't apply that to the pin-spacer for the reasons I just mentioned. But it shouldn't really matter because it's solely meant to prop things open in the normal flow. Can you tell me how it's actually causing any noticeable rendering differences? I'm sure I'm missing something obvious. From what I can tell, everything is working perfectly...but I'm also sleep-deprived :)

Link to comment
Share on other sites

Hi Jack,

 

In the demo a horizontal scroll bar appears at the bottom of the window (screenshot attached) and lots of extra space is created (this is being caused by the pin-spacer which is sitting to right of the element).  This only happens on smaller screens (roughly 1300px wide or less).

 

Paul.

gsap-pin-spacer.jpg

Link to comment
Share on other sites

Oh, now I see what you mean. Yeah, there are 3 solutions:

 

1) Hide the overflow with CSS (by FAR the best and most common fix): 

body {
  overflow-x: hidden;
}

That's almost always a better solution anyway because it's extremely common for scroll-based animated pages to have content fly in from the left or right, and in those cases you'd see a horizontal scrollbar anyway (without the fix above). 

 

2) Don't pin elements that have transforms applied. If your element needs a transform, just put it inside a container <div> (or whatever) that doesn't have transforms, and pin that container. 

 

3) It may be possible for me to add a bunch of code to ScrollTrigger to attempt to factor in all the transforms (x, y, xPercent, yPercent, rotation, skewX, skewY, etc.) to calculate the offset and apply it to the top/left instead but (and this is a big but) the reasons I'm extremely hesitant to do this are:

  • Added kb and performance hit for all pinned elements (because they'd all have to do these calculations). So even though maybe 0.1% of users might find this useful, the other 99.9% still have to pay the "tax".
  • There's a chance it'd break existing use cases that rely on the current behavior
  • There are some edge cases that may make it virtually impossible, like if the browser reports top/left as something other than px units. It's just more brittle overall.

So again, I wouldn't really consider this a "bug" anyway - it's more like the nature of the beast. It's easily worked around with a simple line of CSS and if we tried to implement a complex workaround inside ScrollTrigger, it seems more brittle and definitely more costly. See what I mean? 

  • Like 2
Link to comment
Share on other sites

Oh OK. Yes I completely understand it'd thus be a pain to change. I'll have a play around with it and see what other possible options I have. The client does want to keep the original design so i'll probably go down the body overflow route because (I think) when I used a container div I was still getting the same issue. If I come up with another solution I'll post it on here for the record in case anyone else searches the forum.

Thanks for you help and for coming back to me.

  • Like 1
Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...