Problem with transition height

Hi guys, I'm trying to hide the tabs on scroll down and show on scroll up but I'm facing this problem. Can anyone help me? I'm using MUI and this is how I toggle the height.
<Box
sx={{
display: "grid",
gridTemplateRows: isShowTabs ? "1fr" : "0fr",
transition: "500ms grid-template-rows ease",
}}
>
......
</Box>
<Box
sx={{
display: "grid",
gridTemplateRows: isShowTabs ? "1fr" : "0fr",
transition: "500ms grid-template-rows ease",
}}
>
......
</Box>
12 Replies
empty
emptyOP5mo ago
const [lastScrollTop, setLastScrollTop] = useState(0);
const [isShowTabs, setIsShowTabs] = useState(true);
useEffect(() => {
const scrollableDiv = document.querySelector("#scrollableDiv");
const handleOnscroll = () => {
if (!scrollableDiv) return;
const scrollPos = scrollableDiv?.scrollTop;

if (scrollPos > lastScrollTop) setIsShowTabs(false);
else setIsShowTabs(true);
setLastScrollTop(scrollPos);
};
scrollableDiv?.addEventListener("scroll", handleOnscroll);

return () => {
scrollableDiv?.removeEventListener("scroll", handleOnscroll);
};
}, [lastScrollTop]);
const [lastScrollTop, setLastScrollTop] = useState(0);
const [isShowTabs, setIsShowTabs] = useState(true);
useEffect(() => {
const scrollableDiv = document.querySelector("#scrollableDiv");
const handleOnscroll = () => {
if (!scrollableDiv) return;
const scrollPos = scrollableDiv?.scrollTop;

if (scrollPos > lastScrollTop) setIsShowTabs(false);
else setIsShowTabs(true);
setLastScrollTop(scrollPos);
};
scrollableDiv?.addEventListener("scroll", handleOnscroll);

return () => {
scrollableDiv?.removeEventListener("scroll", handleOnscroll);
};
}, [lastScrollTop]);
This is how I toggle the isShowTabs. I also tried to use sticky but it did not work. I dont know where I'm wrong
clevermissfox
clevermissfox5mo ago
do you have overflow hidden on whatever lives in that row? the tabs parent?
empty
emptyOP5mo ago
I have overflow hidden on child of Box component
clevermissfox
clevermissfox5mo ago
Have you looked in the dev tools at the styles to see if there’s a specificity issue or to confirm if all those styles are being applied ?
empty
emptyOP5mo ago
The style is applied. You can take a look at my video. Because the scrollPos changes nonstop so the isShowTabs changes consecutively and the style toggles as well
clevermissfox
clevermissfox5mo ago
Can you put the relevant component /code into a codepen or a codesandbox.io. Snippets and screen recordings are hard to debug
empty
emptyOP5mo ago
Ok i'll do it https://codesandbox.io/p/sandbox/navbar-hide-on-scroll-down-76fh76?file=%2Fsrc%2FApp.js%3A142%2C1 The component structure is quite different but the bug still occurs. Can you please take a look
tototriou
tototriou5mo ago
use position: fixed and it works instead of position sticky your component is already on top of the page
tototriou
tototriou5mo ago
is that what you want ?
No description
clevermissfox
clevermissfox5mo ago
i didnt see a position sticky in the css, is that being loaded in from a dependancy? I think the issue comes from this (although not a react master so just a hunch)
if (scrollPos > lastScrollTopRef.current) setIsShowTabs(false);
else setIsShowTabs(true);
lastScrollTopRef.current = scrollPos;
if (scrollPos > lastScrollTopRef.current) setIsShowTabs(false);
else setIsShowTabs(true);
lastScrollTopRef.current = scrollPos;
it seems to be flickering back and forth from isShowTabs between true and false because lastScrollTopRef starts at 0, which means scrollPos IS greater than it and isShowTabs is false. then lastScrollTopRef.current is set to scrollPos which is not greater than scrollPos (its equal to) so the 'else' is triggered which is IsShowTabs to true. im getting some conflicting information whether in Ract18 an empty dependancy array will trigger a rerender :
In React 18, an empty dependency array in useEffect no longer guarantees that the effect will only run once on mount. This is due to the introduction of the new Strict Mode behavior and concurrent rendering in React 18. When using an empty dependency array with useEffect in React 18, the effect may be called twice during the initial render - once during the render phase and again during the commit phase. This can lead to an infinite loop if the effect updates state, causing a re-render, which then triggers the effect again, and so on.
So between the renders and the toggling of isShowTabs between true or false and the transition time to toggle your grid rows, its causing a flicker. oh i see the pos sticky in the dev tools and i must be wrong, and @tototriou15 is correct because setting it to fixed seems to fix everythign
tototriou
tototriou5mo ago
sorry i changed it to fixed in my gif to make it work
clevermissfox
clevermissfox5mo ago
yeah it fixes the flicker, well done!
Want results from more Discord servers?
Add your server