reactjsnext.jstailwind-cssstylingconditional-rendering

Conditionally render images which are meant to serve as only background elements for body so they don't add height on pages with too little content


I have some NextJS image components to the RootLayout of a NextJS component and gave them negative z-indexes and positioned them absolutely as some content is dynamic and I wanted them to be placed in locations that tie in to the content. The problem is whilst they have been postioned to the base route '/' they are creating too height along the y-axis on pages with less content than the base route. I've tried to third party modules like react measure and body scroll lock but have run into issue with client vs server side rendering since the images are located at the root.

Here is the structure of the root layout:

 <body className={`overflow-x-hidden flex flex-col items-center ${monoDrip.className} bg-zinc-200 text-zinc-900 relative md:max-w-[1920px] pt-28 sm:pt-36`}>
      <div className={`bg-[#BBDDF2] absolute -z-[10] top-[-6rem] right-[11rem] h-[31.25rem] w-[35.25rem] rounded-full blur-[10rem] sm:w-[68.75rem]`} ></div>
      <div className={`bg-[#e9ffe7] absolute -z-[10] top-[-1rem] left-[-35rem] h-[31.25rem] w-[50rem] rounded-full blur-[10rem] sm:w-[68.75rem] md:left[-33rem] lg:left-[-28rem] xl:left-[-15rem] 2xl:left-[-5rem]`} ></div>
      <Image src={Squares} alt={"Background Squares"} priority={true} className={`opacity-50 xs:hidden absolute -z-[10] top-[40rem] right-[-18rem] max-w-full object-contain`} />
      <Image src={Squares} alt={"Background Circles"}  priority={true} className={`rotate-180 opacity-50 xs:hidden absolute -z-[10] top-[40rem] left-[-28rem] max-w-full object-contain`} />
      <Image src={Waves} alt={"Background Waves"} priority={true} className={`opacity-80 xs:hidden absolute -z-[10] top-[82.1rem] right-[-1.6rem] max-w-full object-contain`} />
      <Image src={Waves} alt={"Background Waves"} priority={true} className={`opacity-80 xs:hidden absolute -z-[10] top-[398.9rem] right-[-1.6rem] max-w-full object-contain`} />
      <Image src={Waves2} alt={"Background Waves"} priority={true} className={`opacity-90 w-[60rem] xs:hidden absolute -z-[10] top-[164rem] right-[-0.4rem] max-w-full object-contain`} />
      <Image src={Waves2} alt={"Background Waves"} priority={true} className={`rotate-180 w-[60rem] opacity-90 xs:hidden absolute -z-[10] top-[164rem] left-[-0.7rem] max-w-full object-contain`} />
      <Image src={Waves2} alt={"Background Waves"} priority={true} className={`opacity-90 w-[60rem] xs:hidden absolute -z-[10] top-[164rem] right-[-0.4rem] max-w-full object-contain`} />
      <Image src={Waves2} alt={"Background Waves"} priority={true} className={`rotate-180 w-[60rem] opacity-90 xs:hidden absolute -z-[10] top-[164rem] left-[-0.7rem] max-w-full object-contain`} />
      <Image src={Circles} alt={"Background Waves"} priority={true} className={`w-[37.5rem] opacity-90 xs:hidden absolute -z-[10] top-[255.7rem] left-[-20.3rem] max-w-full object-contain`} />
      <Image src={Circles} alt={"Background Waves"} priority={true} className={`w-[37.5rem] opacity-90 xs:hidden absolute -z-[10] top-[295.7rem] right-[-20.3rem] max-w-full object-contain`} />
      <ActiveSectionContextProvider >
        <Header />
        {children}
      </ActiveSectionContextProvider>

      </body>

And here are the child components:

<main className={`flex flex-col items-center px-[4]`}>
  <Intro />
  <SectionDivider />
  <About />
  <SectionDivider />
  <Services />
  <SectionDivider />
  <Careers />
  <SectionDivider />
  <Community />
  <SectionDivider />
  <Contact />
</main>

I need a way to conditionally render the images based on the number of elements (I've tried using and average height) to no success or their height directly (using the .offset method only returned 1 for me)


Solution

  • I think you went about this problem incorrectly. The best way to do this would be to pass in a background image for each section. So for example the <Intro /> section on any given page would take in a prop called background and you could pass any background you want. This would fix the issue of having "too much height" on pages that have more or less content since there would only be a background per section and not a static number of background sections.

    <main className={`flex flex-col items-center px-[4]`}>
      <Intro background={Squares} />
      <SectionDivider />
      <About background={Waves} />
      <SectionDivider />
      <Services background={Waves2} />
      <SectionDivider />
      <Careers background={Squares} />
      <SectionDivider />
      <Community background={Circles} />
      <SectionDivider />
      <Contact background={Circles} />
    </main>