AirBnb two column sticky Mapbox with results scroll - React, Mapbox, Tailwind

Viewed 289

I'd like to create the desired results as seen here. Please view in Desktop widescreen. AirBnb results. As you can see with the AirBnb results, the Map on the Righthand side sticks perfectly into place while allowing the user to scroll down to view the results on the Lefthand side.

I've been trying to figure out how they have achieved this but am reaching some road blocks. I found some luck with implementing this bit of code but there is still a slight amount of vertical scrolling before the bottom of the map snaps into place. I believe it has to do with the h-screen class making the map height: 100vh

  <main className="flex">
    {/* Results & Filters section - Left side */}
    <section className='flex-grow'>
      <div className='lg:inline-flex mt-5 mb-5 space-x-3 text-gray-800 whitespace-no-wrap'>
        <p className='custom-button'>Cancellation Flexibility</p>
        <p className='custom-button'>Type of Place</p>
        <p className='custom-button'>Price</p>
        <p className='custom-button'>Rooms and Beds</p>
        <p className='custom-button'>More Filters</p>
      </div>
      <div className="flex flex-col">
        {/* Search results */}
        {searchResults.map(
          ({ img, location, title, description, star, price, total }) => (
          <InfoCard
            key={img}
            img={img}
            location={location}
            title={title}
            description={description}
            star={star}
            price={price}
            total={total}
          />
        ))}
      </div>
    </section>

    {/* Map section - Right side */}
    <aside className="hidden h-screen w-[50%] sticky xl:inline-flex l:min-w-[600px] top-0">
        <Map searchResults={searchResults} />
    </aside>
  </main>

Some help would be greatly appreciated. I've started a codesandbox to make it easier to see what I'm experiencing. Please view in Desktop widescreen https://codesandbox.io/s/determined-bartik-2tftc?file=/pages/index.js

2 Answers

[Edit] : I just noticed the left side is hidden by the map now since the map is out of the flex flow. I'll keep the answer as an idea. If you can manipulate the architecture of the page, it's easy to fix.


Looks like applying :

position: fixed;
right: 0;
justify-content: end;

to the aside tag that contains the map and removing its top-0 class fix your problem. I see that you are using an external library to display the map so I don't know if there is a way to apply css to it since I can't edit the codesandbox sorry. You could just wrap it in a span with a class and target it with .my-class > aside in your css. But first check the documentation, they are probably exposing some classes for you to apply styles.

So I seemed to have solved this. Took a bit of work but I achieved the result I was looking for.

I added some root css here in globals.css file

:root {
  --navigation-bar-offset: 90px;
  --gp-placement-max-height: calc(100vh - var(--navigation-bar-offset, 80px));
}

I utilized these root class names to be used in index.js on the component parent div

<div className="w-full
  sticky
  top-[var(--navigation-bar-offset,80px)]
  h-[var(--gp-placement-max-height,auto)]">
  <MapBox searchResults={searchResults} />
</div>

I also found, that Mapbox was overriding my height from it's setViewport callback in Map.js. So I overrode Mapbox by adding this code in Map.js in the onViewportChange.

onViewportChange={nextViewport => setViewPort({ ...nextViewport, width: "100%", height: "100%" })}

I updated the Codesandbox to reflect these changes. Also, if you resize the browser, it maintains height and width.

Related