Closed flummer closed 3 years ago
@brettsmason Is the new Off-canvas related to this bug ?
@ncoden I can confirm its a bug, but I'm pretty sure its to do with sticky rather than off canvas. @kball will know more I'm sure.
So I looked into this some more. It looks like this is an issue with position: fixed
(set on the .sticky
element) along with css transform
.
The only workaround I can find is using JS to set the top position to the current scroll offset. See http://stackoverflow.com/questions/15194313/transform3d-not-working-with-position-fixed-children for an explanation
Also see this CodePen with the suggestion added: http://codepen.io/brettsmason/pen/ygXJYK (edited)
@kball I'm not sure what the best way to fix this would be. We could change the off canvas behaviour to not use translateX/Y
and use another method, but I chose that as it gives the best performance across devices.
@brettsmason I was thinking we could add an option to sticky for when it is being used with an off-canvas component and make it so that sticky behaves as you have it in your codepen only when that option is enabled. The option would be disabled by default. Thoughts?
@colin-marshall That sounds like a good solution. I guess maybe we don't name it specific for off canvas (or do we?) as it applies to any element that transforms, but maybe mention it in the description (and maybe a callout on the docs on both places).
I also noticed if you scroll fast on my CodePen the performance isn't the best - don't know if there's a better way to do it?
@brettsmason I agree a more universal name like absoluteMode
, transformMode
, or stickyAbsolute
would be better. Have you tested the new off canvas with non-menu sticky components to see if there is any bugs in other use cases?
What device and browser were you seeing poor scroll performance with?
@colin-marshall Would it somehow be possible to check if a parent container is transformed? And then if so set the position using JS, otherwise fall back to the CSS only. This would avoid any confusion with people not being able to get it to work, and we only want the JS positioning when off canvas (or a transformed container) is open.
I haven't tested with any other types of sticky use case, but I'll get some pens setup so we can check.
It was in Chrome for Windows - with fast scrolling it didn't seem to stick to the top quite like position: fixed
did - sort of "bobbed" up and down a bit very slightly.
@brettsmason you can check if the parent is transformed by just getting the CSS transform values for x and y and seeing if they are set to anything other than zero. The problem is that when off-canvas is opened and closed the menu is not actually becoming "unstuck" it just changes where it think it's supposed to be stuck at. So I'm not sure how it would know when to check if the parent is transformed.
This might be a good situation for the new mutation observers, but I need to learn how they work first. I have been meaning to get familiar with them so this poses a good opportunity for me to dig in to them.
@brettsmason it looks like if you add -webkit-transform: translateZ(0)
to the sticky element it might get rid of the weird behavior you see in Chrome. The SO post you linked had a link to another post (http://stackoverflow.com/questions/11258877/fixed-element-disappears-in-chrome) where the accepted answer talks about adding that to a position: fixed
element to fix some wonky behavior. One of the comments says it worked for absolute positioning as well. I can't reproduce on Mac or else I would test.
Comment regarding absolute positioning: http://stackoverflow.com/questions/11258877/fixed-element-disappears-in-chrome#comment34523987_18764086
@colin-marshall When you have a bit of time can we discuss how we can get this into the next patch? 😄 👍
@brettsmason I can actually see the "buggy" scroll behavior now. I think it's happening because it has to keep setting it to position absolute with every scroll event and it can't keep up with scrolling. I think first we need to see if this even fixable before we go dive into the rest of it. I'll work on it a bit today and see if I can come up with anything.
@colin-marshall @brettsmason Would it be possible to change the positioning to use transform rather than x/y offset on absolute? That would prevent the browser from having to repaint every change and make it much easier to keep up.
@kball that's a good idea but it still doesn't keep up very well. The plus side to this solution is that it only can't keep up when the menu is opened while with absolute positioning it was always an issue.
Example: http://codepen.io/colin-marshall/pen/apEaJR
When you close the menu there's a second where it goes off screen due to not having separate events for before and after the off-canvas is closed.
Another possible solution is to move the sticky menu outside of the off-canvas container and then translateX
on the sticky menu in sync with the off-canvas menu. That would require the sticky plugin to know the value of $offcanvas-size
beforehand. I tested this out a couple weeks ago and it worked good except the sticky element was not clickable when off-canvas was open so you had to click below the title-bar to get it to close. Maybe that's just a z-index issue?
In your codepen I'm still seeing the top bar repaint as I scroll... if I add
.sticky {
will-change: transform;
}
I can get rid of that. (see https://www.fourkitchens.com/blog/article/fix-scrolling-performance-css-will-change-property)
this doesn't help IE & Edge or old android (see http://caniuse.com/#feat=will-change) but may help for just about everything else... even turning on 'low-end device' level throttling in chrome devtools it appears to still keep up.
@kball you meant it was only repainting when the off-canvas was open, correct?
I tried the will-change
property and don't see a difference in Chrome. It's still repainting (or looks like it is) when off-canvas is opened.
yes, it was repainting when the off-canvas was open... Can you verify if the repaint is happening using the dev tools? https://developer.chrome.com/devtools/docs/rendering-settings
Repaint only happens when it hits the top of the page. If I scroll using the keyboard it stays perfectly in place like it does with position: fixed
but scrolling with the Trackpad makes it choppy.
@kball I was able to isolate the problem to my 2015 15" Retina MacBook Pro with a discrete AMD Radeon R9 M370X graphics card. When I hook it up to an external monitor it works great but on the laptop screen it's choppy. Forcing it to use integrated graphics or discrete graphics doesn't make a difference either. So I guess this is an issue with my MacBook model more than anything else.
@kball @brettsmason I started trying to add an event to trigger after the off-canvas menu close animation completes and I think we might need to add something like the timer that Orbit uses to detect when a slide is done transitioning in order to achieve this.
Or there might be some way to use a variable that tracks the translationX value of off-canvas content and triggers the event when it hits 0. Maybe mutation observers could do this? (calling @coreysyms)
What do you guys think?
@colin-marshall have you tried using Foundation.transitionend?
@kball that is exactly what I needed! I have it working pretty much flawless in Firefox and Safari. In Chrome, however, the burger icon jerks when the menu opens and you're not scrolled to the top of the page. When you close the off canvas in Chrome the title bar doesn't translate horizontally with the rest of the page content. It stays to the left and then snaps to the right when the transition finishes.
It was doing that before I added Foundation.transitionend
it was just harder to notice because it jumped to the top first. I recorded a video of the behavior for you to see:
https://www.dropbox.com/s/en5knqkwo453yoi/Sticky%20Off%20Canvas.mp4?dl=0
Chrome is the last one in the video.
Hi, wondering if there's a solution to this issue yet?
hi guys I can see that the bug is still alive!!!
Hi,
I have got a solution:
Move sticky/fixed div outside "off-canvas-content".
<div class="off-canvas-wrapper">
<div class="off-canvas position-left" data-off-canvas id="offCanvasL">
<!-- LEFT MENU -->
</div>
<div class="off-canvas position-right" data-off-canvas id="offCanvasR">
<!-- RIGHT MENU -->
</div>
<div class="fixed_div">
<div class="menu_left" data-toggle="offCanvasL"><!-- OPEN LEFT MENU --></div>
<div class="menu_right" data-toggle="offCanvasR"><!-- OPEN RIGHT MENU --></div>
</div>
<div class="off-canvas-content" data-off-canvas-content>
<!-- YOUR CONTENT-->
</div>
</div>
Then we need some CSS rules:
.fixed_div {
position: fixed;
top: 0;
width: 100%;
z-index: 10;
transform: none;
transition: transform .5s ease;
backface-visibility: hidden;
}
.fixed_div.is-open-right.has-transition-push {
transform: translateX(-250px);
}
.fixed_div.is-open-left.has-transition-push {
transform: translateX(250px);
}
Last think that we need to do is add some JQUERY to ours app.js:
$('.menu_left').click(function() {
$('.fixed_div').toggleClass('is-open-right has-transition-push has-position-right');
});
$('.menu_right').click(function() {
$('.fixed_div').toggleClass('is-open-left has-transition-push has-position-left');
});
$('.close-button, .js-off-canvas-overlay').click(function() {
$('.fixed_div').removeClass('is-open-right is-open-left has-transition-push has-position-right has-position-left');
});
and that is all :)
WrapTheCode nailed it. Fixed this issue for me
I had a similar issue with Reveal and when scrolled down and activated data-open
the top-bar would disappear. Quick fix:
<path to data-sticky element > {
position: fixed !important;
width: 100%
}
The combination of a sticky menu bar and off-canvas menu seems to have a bug in that the menu looses it's stickiness when the off-canvas menu is opened.
How to reproduce this bug:
What should happen:
I think the sticky top menu should stay sticky at the top of the window, but move out to the side as it rightfully does with the rest of the main content
What happened instead:
It moves out to the side with the rest of the main content, but attaches to the top of the page instead of staying at the top of the window.
Test case:
Notes:
In a previous version (6.2.4) the page scrolled up to the top, when the off-canvas menu was opened, but that is not ideal if you want to use the off-canvas menu for tools etc.
I like that the main content stays where it is, but the sticky top menu should too.
I'm fairly new to Foundation, so there might be a setting that I have missed, if so, please let me know.