htmlcsswebnext.jstailwind-css

Prevent page from jumping to top when opening sidebar (NextJS, Typescript, Tailwind)


I am working on a site with a sidebar for smaller screens. The sidebar works fine however I want the background page to stay fixed in place when the sidebar is active and not scroll.

I'm using the _app.tsx file to place a sticky nav bar (which has the menu button for the sidebar) and the content (which contains a sticky footer for every page).

I am handling the sidebar visibility with a State handler and have tried adding overflow-hidden to the content section which seems to have been the go-to advice judging from the numerous other questions on this topic - but no luck.

My _app.tsx file which looks like this:

import Footer from '@/components/footer';
import Navbar from '@/components/navbar';
import '@/styles/globals.css';
import type { AppProps } from 'next/app';
import { Inter } from 'next/font/google';
import { useState } from 'react';

const inter = Inter({ subsets: ['latin'] });

export default function App({ Component, pageProps }: AppProps) {
  const [active, setActive] = useState(false);
  const [showSearch, setShowSearch] = useState(false);
  const [searchText, setSearchText] = useState('');

  const handleClick = () => {
    setActive(!active);
  };

  const sideClick = () => {
    setActive(false);
  };

  const searchClick = () => {
    setShowSearch(!showSearch);
  };

  const clearSearch = () => {
    setSearchText('');
  };

  return (
    <div className="flex flex-col h-screen">
      <div className="fixed top-0 z-50 w-full">
        <Navbar
          active={active}
          handleClick={handleClick}
          sideClick={sideClick}
          showSearch={showSearch}
          searchClick={searchClick}
          searchText={searchText}
          clearSearch={clearSearch}
        />
      </div>
      <div className={`${active ? 'overflow-hidden' : 'block'}`}>
        <div className="max-w-[1372px] mt-[42px] md:mt-[48px] grow mx-auto justify-center">
          <Component {...pageProps} />
        </div>
        <div className="w-full">
          <Footer />
        </div>
      </div>
    </div>
  );
}

overflow-hidden results in scroll being disabled however makes the page jump back to top. I've also tried to use changing the position of the content to fixed but this also results in the jump to top.

Does anyone have an idea how I can achieve the background to stay in place when the sidebar is open?


Solution

  • you should put use the overflow hidden on the body tag.

    const handleClick = () => {
        document.body.style.overflow = !active ? 'hidden' : null;
        setActive(!active);
    };
    

    if you know Vue.js, this can be your reference https://github.com/laravel/breeze/blob/1.x/stubs/inertia-vue/resources/js/Components/Modal.vue